diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 17:51:52 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 17:51:52 -0500 |
commit | bbbd27e694ce2c5fde9c8fcedbea618dd9153fe7 (patch) | |
tree | 8811b690085ac784ef73c7b4cdff30c6bedd0e34 /fs | |
parent | a6590b9f01dca2d45a38b8387f59812c44f68a2f (diff) | |
parent | 712ddc52ffa1f5324cd8f682d9e5b047b91f34d3 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext2, ext3, udf updates from Jan Kara:
"Several UDF fixes, a support for UDF extent cache, and couple of ext2
and ext3 cleanups and minor fixes"
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
Ext2: remove the static function release_blocks to optimize the kernel
Ext2: mark inode dirty after the function dquot_free_block_nodirty is called
Ext2: remove the overhead check about sb in the function ext2_new_blocks
udf: Remove unused s_extLength from udf_bitmap
udf: Make s_block_bitmap standard array
udf: Fix bitmap overflow on large filesystems with small block size
udf: add extent cache support in case of file reading
udf: Write LVID to disk after opening / closing
Ext3: return ENOMEM rather than EIO if sb_getblk fails
Ext2: return ENOMEM rather than EIO if sb_getblk fails
Ext3: use unlikely to improve the efficiency of the kernel
Ext2: use unlikely to improve the efficiency of the kernel
Ext3: add necessary check in case IO error happens
Ext2: free memory allocated and forget buffer head when io error happens
ext3: Fix memory leak when quota options are specified multiple times
ext3, ext4, ocfs2: remove unused macro NAMEI_RA_INDEX
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2/balloc.c | 28 | ||||
-rw-r--r-- | fs/ext2/inode.c | 12 | ||||
-rw-r--r-- | fs/ext2/super.c | 2 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 4 | ||||
-rw-r--r-- | fs/ext3/inode.c | 16 | ||||
-rw-r--r-- | fs/ext3/namei.c | 1 | ||||
-rw-r--r-- | fs/ext3/resize.c | 12 | ||||
-rw-r--r-- | fs/ext3/super.c | 51 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 4 | ||||
-rw-r--r-- | fs/ext4/namei.c | 1 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 1 | ||||
-rw-r--r-- | fs/udf/inode.c | 86 | ||||
-rw-r--r-- | fs/udf/super.c | 11 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 16 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 5 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 5 |
16 files changed, 177 insertions, 78 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 2616d0ea5c5c..9f9992b37924 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -159,15 +159,6 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
159 | return bh; | 159 | return bh; |
160 | } | 160 | } |
161 | 161 | ||
162 | static void release_blocks(struct super_block *sb, int count) | ||
163 | { | ||
164 | if (count) { | ||
165 | struct ext2_sb_info *sbi = EXT2_SB(sb); | ||
166 | |||
167 | percpu_counter_add(&sbi->s_freeblocks_counter, count); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static void group_adjust_blocks(struct super_block *sb, int group_no, | 162 | static void group_adjust_blocks(struct super_block *sb, int group_no, |
172 | struct ext2_group_desc *desc, struct buffer_head *bh, int count) | 163 | struct ext2_group_desc *desc, struct buffer_head *bh, int count) |
173 | { | 164 | { |
@@ -568,8 +559,11 @@ do_more: | |||
568 | } | 559 | } |
569 | error_return: | 560 | error_return: |
570 | brelse(bitmap_bh); | 561 | brelse(bitmap_bh); |
571 | release_blocks(sb, freed); | 562 | if (freed) { |
572 | dquot_free_block_nodirty(inode, freed); | 563 | percpu_counter_add(&sbi->s_freeblocks_counter, freed); |
564 | dquot_free_block_nodirty(inode, freed); | ||
565 | mark_inode_dirty(inode); | ||
566 | } | ||
573 | } | 567 | } |
574 | 568 | ||
575 | /** | 569 | /** |
@@ -1239,10 +1233,6 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, | |||
1239 | 1233 | ||
1240 | *errp = -ENOSPC; | 1234 | *errp = -ENOSPC; |
1241 | sb = inode->i_sb; | 1235 | sb = inode->i_sb; |
1242 | if (!sb) { | ||
1243 | printk("ext2_new_blocks: nonexistent device"); | ||
1244 | return 0; | ||
1245 | } | ||
1246 | 1236 | ||
1247 | /* | 1237 | /* |
1248 | * Check quota for allocation of this block. | 1238 | * Check quota for allocation of this block. |
@@ -1416,9 +1406,11 @@ allocated: | |||
1416 | 1406 | ||
1417 | *errp = 0; | 1407 | *errp = 0; |
1418 | brelse(bitmap_bh); | 1408 | brelse(bitmap_bh); |
1419 | dquot_free_block_nodirty(inode, *count-num); | 1409 | if (num < *count) { |
1420 | mark_inode_dirty(inode); | 1410 | dquot_free_block_nodirty(inode, *count-num); |
1421 | *count = num; | 1411 | mark_inode_dirty(inode); |
1412 | *count = num; | ||
1413 | } | ||
1422 | return ret_block; | 1414 | return ret_block; |
1423 | 1415 | ||
1424 | io_error: | 1416 | io_error: |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 6363ac66fafa..c3881e56662e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -495,6 +495,10 @@ static int ext2_alloc_branch(struct inode *inode, | |||
495 | * parent to disk. | 495 | * parent to disk. |
496 | */ | 496 | */ |
497 | bh = sb_getblk(inode->i_sb, new_blocks[n-1]); | 497 | bh = sb_getblk(inode->i_sb, new_blocks[n-1]); |
498 | if (unlikely(!bh)) { | ||
499 | err = -ENOMEM; | ||
500 | goto failed; | ||
501 | } | ||
498 | branch[n].bh = bh; | 502 | branch[n].bh = bh; |
499 | lock_buffer(bh); | 503 | lock_buffer(bh); |
500 | memset(bh->b_data, 0, blocksize); | 504 | memset(bh->b_data, 0, blocksize); |
@@ -523,6 +527,14 @@ static int ext2_alloc_branch(struct inode *inode, | |||
523 | } | 527 | } |
524 | *blks = num; | 528 | *blks = num; |
525 | return err; | 529 | return err; |
530 | |||
531 | failed: | ||
532 | for (i = 1; i < n; i++) | ||
533 | bforget(branch[i].bh); | ||
534 | for (i = 0; i < indirect_blks; i++) | ||
535 | ext2_free_blocks(inode, new_blocks[i], 1); | ||
536 | ext2_free_blocks(inode, new_blocks[i], num); | ||
537 | return err; | ||
526 | } | 538 | } |
527 | 539 | ||
528 | /** | 540 | /** |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index fa04d023177e..7f68c8114026 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1500,7 +1500,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, | |||
1500 | bh = sb_bread(sb, tmp_bh.b_blocknr); | 1500 | bh = sb_bread(sb, tmp_bh.b_blocknr); |
1501 | else | 1501 | else |
1502 | bh = sb_getblk(sb, tmp_bh.b_blocknr); | 1502 | bh = sb_getblk(sb, tmp_bh.b_blocknr); |
1503 | if (!bh) { | 1503 | if (unlikely(!bh)) { |
1504 | err = -EIO; | 1504 | err = -EIO; |
1505 | goto out; | 1505 | goto out; |
1506 | } | 1506 | } |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index b6754dbbce3c..2d7557db3ae8 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -662,10 +662,10 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
662 | ea_idebug(inode, "creating block %d", block); | 662 | ea_idebug(inode, "creating block %d", block); |
663 | 663 | ||
664 | new_bh = sb_getblk(sb, block); | 664 | new_bh = sb_getblk(sb, block); |
665 | if (!new_bh) { | 665 | if (unlikely(!new_bh)) { |
666 | ext2_free_blocks(inode, block, 1); | 666 | ext2_free_blocks(inode, block, 1); |
667 | mark_inode_dirty(inode); | 667 | mark_inode_dirty(inode); |
668 | error = -EIO; | 668 | error = -ENOMEM; |
669 | goto cleanup; | 669 | goto cleanup; |
670 | } | 670 | } |
671 | lock_buffer(new_bh); | 671 | lock_buffer(new_bh); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b176d4253544..d512c4bc4ad7 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -676,6 +676,10 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, | |||
676 | * parent to disk. | 676 | * parent to disk. |
677 | */ | 677 | */ |
678 | bh = sb_getblk(inode->i_sb, new_blocks[n-1]); | 678 | bh = sb_getblk(inode->i_sb, new_blocks[n-1]); |
679 | if (unlikely(!bh)) { | ||
680 | err = -ENOMEM; | ||
681 | goto failed; | ||
682 | } | ||
679 | branch[n].bh = bh; | 683 | branch[n].bh = bh; |
680 | lock_buffer(bh); | 684 | lock_buffer(bh); |
681 | BUFFER_TRACE(bh, "call get_create_access"); | 685 | BUFFER_TRACE(bh, "call get_create_access"); |
@@ -717,7 +721,7 @@ failed: | |||
717 | BUFFER_TRACE(branch[i].bh, "call journal_forget"); | 721 | BUFFER_TRACE(branch[i].bh, "call journal_forget"); |
718 | ext3_journal_forget(handle, branch[i].bh); | 722 | ext3_journal_forget(handle, branch[i].bh); |
719 | } | 723 | } |
720 | for (i = 0; i <indirect_blks; i++) | 724 | for (i = 0; i < indirect_blks; i++) |
721 | ext3_free_blocks(handle, inode, new_blocks[i], 1); | 725 | ext3_free_blocks(handle, inode, new_blocks[i], 1); |
722 | 726 | ||
723 | ext3_free_blocks(handle, inode, new_blocks[i], num); | 727 | ext3_free_blocks(handle, inode, new_blocks[i], num); |
@@ -1078,8 +1082,8 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode *inode, | |||
1078 | if (!err && buffer_mapped(&dummy)) { | 1082 | if (!err && buffer_mapped(&dummy)) { |
1079 | struct buffer_head *bh; | 1083 | struct buffer_head *bh; |
1080 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); | 1084 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); |
1081 | if (!bh) { | 1085 | if (unlikely(!bh)) { |
1082 | *errp = -EIO; | 1086 | *errp = -ENOMEM; |
1083 | goto err; | 1087 | goto err; |
1084 | } | 1088 | } |
1085 | if (buffer_new(&dummy)) { | 1089 | if (buffer_new(&dummy)) { |
@@ -2729,12 +2733,12 @@ static int __ext3_get_inode_loc(struct inode *inode, | |||
2729 | return -EIO; | 2733 | return -EIO; |
2730 | 2734 | ||
2731 | bh = sb_getblk(inode->i_sb, block); | 2735 | bh = sb_getblk(inode->i_sb, block); |
2732 | if (!bh) { | 2736 | if (unlikely(!bh)) { |
2733 | ext3_error (inode->i_sb, "ext3_get_inode_loc", | 2737 | ext3_error (inode->i_sb, "ext3_get_inode_loc", |
2734 | "unable to read inode block - " | 2738 | "unable to read inode block - " |
2735 | "inode=%lu, block="E3FSBLK, | 2739 | "inode=%lu, block="E3FSBLK, |
2736 | inode->i_ino, block); | 2740 | inode->i_ino, block); |
2737 | return -EIO; | 2741 | return -ENOMEM; |
2738 | } | 2742 | } |
2739 | if (!buffer_uptodate(bh)) { | 2743 | if (!buffer_uptodate(bh)) { |
2740 | lock_buffer(bh); | 2744 | lock_buffer(bh); |
@@ -2783,7 +2787,7 @@ static int __ext3_get_inode_loc(struct inode *inode, | |||
2783 | 2787 | ||
2784 | bitmap_bh = sb_getblk(inode->i_sb, | 2788 | bitmap_bh = sb_getblk(inode->i_sb, |
2785 | le32_to_cpu(desc->bg_inode_bitmap)); | 2789 | le32_to_cpu(desc->bg_inode_bitmap)); |
2786 | if (!bitmap_bh) | 2790 | if (unlikely(!bitmap_bh)) |
2787 | goto make_io; | 2791 | goto make_io; |
2788 | 2792 | ||
2789 | /* | 2793 | /* |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 890b8947c546..88f64eb1b6fa 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #define NAMEI_RA_CHUNKS 2 | 36 | #define NAMEI_RA_CHUNKS 2 |
37 | #define NAMEI_RA_BLOCKS 4 | 37 | #define NAMEI_RA_BLOCKS 4 |
38 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) | 38 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) |
39 | #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) | ||
40 | 39 | ||
41 | static struct buffer_head *ext3_append(handle_t *handle, | 40 | static struct buffer_head *ext3_append(handle_t *handle, |
42 | struct inode *inode, | 41 | struct inode *inode, |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 0f814f3450de..27105655502c 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -116,8 +116,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, | |||
116 | int err; | 116 | int err; |
117 | 117 | ||
118 | bh = sb_getblk(sb, blk); | 118 | bh = sb_getblk(sb, blk); |
119 | if (!bh) | 119 | if (unlikely(!bh)) |
120 | return ERR_PTR(-EIO); | 120 | return ERR_PTR(-ENOMEM); |
121 | if ((err = ext3_journal_get_write_access(handle, bh))) { | 121 | if ((err = ext3_journal_get_write_access(handle, bh))) { |
122 | brelse(bh); | 122 | brelse(bh); |
123 | bh = ERR_PTR(err); | 123 | bh = ERR_PTR(err); |
@@ -234,8 +234,8 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
234 | goto exit_bh; | 234 | goto exit_bh; |
235 | 235 | ||
236 | gdb = sb_getblk(sb, block); | 236 | gdb = sb_getblk(sb, block); |
237 | if (!gdb) { | 237 | if (unlikely(!gdb)) { |
238 | err = -EIO; | 238 | err = -ENOMEM; |
239 | goto exit_bh; | 239 | goto exit_bh; |
240 | } | 240 | } |
241 | if ((err = ext3_journal_get_write_access(handle, gdb))) { | 241 | if ((err = ext3_journal_get_write_access(handle, gdb))) { |
@@ -722,8 +722,8 @@ static void update_backups(struct super_block *sb, | |||
722 | break; | 722 | break; |
723 | 723 | ||
724 | bh = sb_getblk(sb, group * bpg + blk_off); | 724 | bh = sb_getblk(sb, group * bpg + blk_off); |
725 | if (!bh) { | 725 | if (unlikely(!bh)) { |
726 | err = -EIO; | 726 | err = -ENOMEM; |
727 | break; | 727 | break; |
728 | } | 728 | } |
729 | ext3_debug("update metadata backup %#04lx\n", | 729 | ext3_debug("update metadata backup %#04lx\n", |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 4ba2683c1d44..5546ca225ffe 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -916,21 +916,24 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | |||
916 | "Not enough memory for storing quotafile name"); | 916 | "Not enough memory for storing quotafile name"); |
917 | return 0; | 917 | return 0; |
918 | } | 918 | } |
919 | if (sbi->s_qf_names[qtype] && | 919 | if (sbi->s_qf_names[qtype]) { |
920 | strcmp(sbi->s_qf_names[qtype], qname)) { | 920 | int same = !strcmp(sbi->s_qf_names[qtype], qname); |
921 | ext3_msg(sb, KERN_ERR, | 921 | |
922 | "%s quota file already specified", QTYPE2NAME(qtype)); | ||
923 | kfree(qname); | 922 | kfree(qname); |
924 | return 0; | 923 | if (!same) { |
924 | ext3_msg(sb, KERN_ERR, | ||
925 | "%s quota file already specified", | ||
926 | QTYPE2NAME(qtype)); | ||
927 | } | ||
928 | return same; | ||
925 | } | 929 | } |
926 | sbi->s_qf_names[qtype] = qname; | 930 | if (strchr(qname, '/')) { |
927 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
928 | ext3_msg(sb, KERN_ERR, | 931 | ext3_msg(sb, KERN_ERR, |
929 | "quotafile must be on filesystem root"); | 932 | "quotafile must be on filesystem root"); |
930 | kfree(sbi->s_qf_names[qtype]); | 933 | kfree(qname); |
931 | sbi->s_qf_names[qtype] = NULL; | ||
932 | return 0; | 934 | return 0; |
933 | } | 935 | } |
936 | sbi->s_qf_names[qtype] = qname; | ||
934 | set_opt(sbi->s_mount_opt, QUOTA); | 937 | set_opt(sbi->s_mount_opt, QUOTA); |
935 | return 1; | 938 | return 1; |
936 | } | 939 | } |
@@ -945,11 +948,10 @@ static int clear_qf_name(struct super_block *sb, int qtype) { | |||
945 | " when quota turned on"); | 948 | " when quota turned on"); |
946 | return 0; | 949 | return 0; |
947 | } | 950 | } |
948 | /* | 951 | if (sbi->s_qf_names[qtype]) { |
949 | * The space will be released later when all options are confirmed | 952 | kfree(sbi->s_qf_names[qtype]); |
950 | * to be correct | 953 | sbi->s_qf_names[qtype] = NULL; |
951 | */ | 954 | } |
952 | sbi->s_qf_names[qtype] = NULL; | ||
953 | return 1; | 955 | return 1; |
954 | } | 956 | } |
955 | #endif | 957 | #endif |
@@ -2606,7 +2608,18 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2606 | #ifdef CONFIG_QUOTA | 2608 | #ifdef CONFIG_QUOTA |
2607 | old_opts.s_jquota_fmt = sbi->s_jquota_fmt; | 2609 | old_opts.s_jquota_fmt = sbi->s_jquota_fmt; |
2608 | for (i = 0; i < MAXQUOTAS; i++) | 2610 | for (i = 0; i < MAXQUOTAS; i++) |
2609 | old_opts.s_qf_names[i] = sbi->s_qf_names[i]; | 2611 | if (sbi->s_qf_names[i]) { |
2612 | old_opts.s_qf_names[i] = kstrdup(sbi->s_qf_names[i], | ||
2613 | GFP_KERNEL); | ||
2614 | if (!old_opts.s_qf_names[i]) { | ||
2615 | int j; | ||
2616 | |||
2617 | for (j = 0; j < i; j++) | ||
2618 | kfree(old_opts.s_qf_names[j]); | ||
2619 | return -ENOMEM; | ||
2620 | } | ||
2621 | } else | ||
2622 | old_opts.s_qf_names[i] = NULL; | ||
2610 | #endif | 2623 | #endif |
2611 | 2624 | ||
2612 | /* | 2625 | /* |
@@ -2699,9 +2712,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
2699 | #ifdef CONFIG_QUOTA | 2712 | #ifdef CONFIG_QUOTA |
2700 | /* Release old quota file names */ | 2713 | /* Release old quota file names */ |
2701 | for (i = 0; i < MAXQUOTAS; i++) | 2714 | for (i = 0; i < MAXQUOTAS; i++) |
2702 | if (old_opts.s_qf_names[i] && | 2715 | kfree(old_opts.s_qf_names[i]); |
2703 | old_opts.s_qf_names[i] != sbi->s_qf_names[i]) | ||
2704 | kfree(old_opts.s_qf_names[i]); | ||
2705 | #endif | 2716 | #endif |
2706 | if (enable_quota) | 2717 | if (enable_quota) |
2707 | dquot_resume(sb, -1); | 2718 | dquot_resume(sb, -1); |
@@ -2715,9 +2726,7 @@ restore_opts: | |||
2715 | #ifdef CONFIG_QUOTA | 2726 | #ifdef CONFIG_QUOTA |
2716 | sbi->s_jquota_fmt = old_opts.s_jquota_fmt; | 2727 | sbi->s_jquota_fmt = old_opts.s_jquota_fmt; |
2717 | for (i = 0; i < MAXQUOTAS; i++) { | 2728 | for (i = 0; i < MAXQUOTAS; i++) { |
2718 | if (sbi->s_qf_names[i] && | 2729 | kfree(sbi->s_qf_names[i]); |
2719 | old_opts.s_qf_names[i] != sbi->s_qf_names[i]) | ||
2720 | kfree(sbi->s_qf_names[i]); | ||
2721 | sbi->s_qf_names[i] = old_opts.s_qf_names[i]; | 2730 | sbi->s_qf_names[i] = old_opts.s_qf_names[i]; |
2722 | } | 2731 | } |
2723 | #endif | 2732 | #endif |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index d22ebb7a4f55..b1fc96383e08 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -813,10 +813,10 @@ inserted: | |||
813 | ea_idebug(inode, "creating block %d", block); | 813 | ea_idebug(inode, "creating block %d", block); |
814 | 814 | ||
815 | new_bh = sb_getblk(sb, block); | 815 | new_bh = sb_getblk(sb, block); |
816 | if (!new_bh) { | 816 | if (unlikely(!new_bh)) { |
817 | getblk_failed: | 817 | getblk_failed: |
818 | ext3_free_blocks(handle, inode, block, 1); | 818 | ext3_free_blocks(handle, inode, block, 1); |
819 | error = -EIO; | 819 | error = -ENOMEM; |
820 | goto cleanup; | 820 | goto cleanup; |
821 | } | 821 | } |
822 | lock_buffer(new_bh); | 822 | lock_buffer(new_bh); |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index f9ed946a448e..cc9a512f3a8a 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #define NAMEI_RA_CHUNKS 2 | 47 | #define NAMEI_RA_CHUNKS 2 |
48 | #define NAMEI_RA_BLOCKS 4 | 48 | #define NAMEI_RA_BLOCKS 4 |
49 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) | 49 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) |
50 | #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) | ||
51 | 50 | ||
52 | static struct buffer_head *ext4_append(handle_t *handle, | 51 | static struct buffer_head *ext4_append(handle_t *handle, |
53 | struct inode *inode, | 52 | struct inode *inode, |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 8fe4e2892ab9..fc121350d8cb 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -67,7 +67,6 @@ | |||
67 | #define NAMEI_RA_CHUNKS 2 | 67 | #define NAMEI_RA_CHUNKS 2 |
68 | #define NAMEI_RA_BLOCKS 4 | 68 | #define NAMEI_RA_BLOCKS 4 |
69 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) | 69 | #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) |
70 | #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) | ||
71 | 70 | ||
72 | static unsigned char ocfs2_filetype_table[] = { | 71 | static unsigned char ocfs2_filetype_table[] = { |
73 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK | 72 | DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index cbae1ed0b7c1..7a12e48ad819 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -67,6 +67,74 @@ static void udf_update_extents(struct inode *, | |||
67 | struct extent_position *); | 67 | struct extent_position *); |
68 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); | 68 | static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); |
69 | 69 | ||
70 | static void __udf_clear_extent_cache(struct inode *inode) | ||
71 | { | ||
72 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
73 | |||
74 | if (iinfo->cached_extent.lstart != -1) { | ||
75 | brelse(iinfo->cached_extent.epos.bh); | ||
76 | iinfo->cached_extent.lstart = -1; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | /* Invalidate extent cache */ | ||
81 | static void udf_clear_extent_cache(struct inode *inode) | ||
82 | { | ||
83 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
84 | |||
85 | spin_lock(&iinfo->i_extent_cache_lock); | ||
86 | __udf_clear_extent_cache(inode); | ||
87 | spin_unlock(&iinfo->i_extent_cache_lock); | ||
88 | } | ||
89 | |||
90 | /* Return contents of extent cache */ | ||
91 | static int udf_read_extent_cache(struct inode *inode, loff_t bcount, | ||
92 | loff_t *lbcount, struct extent_position *pos) | ||
93 | { | ||
94 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
95 | int ret = 0; | ||
96 | |||
97 | spin_lock(&iinfo->i_extent_cache_lock); | ||
98 | if ((iinfo->cached_extent.lstart <= bcount) && | ||
99 | (iinfo->cached_extent.lstart != -1)) { | ||
100 | /* Cache hit */ | ||
101 | *lbcount = iinfo->cached_extent.lstart; | ||
102 | memcpy(pos, &iinfo->cached_extent.epos, | ||
103 | sizeof(struct extent_position)); | ||
104 | if (pos->bh) | ||
105 | get_bh(pos->bh); | ||
106 | ret = 1; | ||
107 | } | ||
108 | spin_unlock(&iinfo->i_extent_cache_lock); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | /* Add extent to extent cache */ | ||
113 | static void udf_update_extent_cache(struct inode *inode, loff_t estart, | ||
114 | struct extent_position *pos, int next_epos) | ||
115 | { | ||
116 | struct udf_inode_info *iinfo = UDF_I(inode); | ||
117 | |||
118 | spin_lock(&iinfo->i_extent_cache_lock); | ||
119 | /* Invalidate previously cached extent */ | ||
120 | __udf_clear_extent_cache(inode); | ||
121 | if (pos->bh) | ||
122 | get_bh(pos->bh); | ||
123 | memcpy(&iinfo->cached_extent.epos, pos, | ||
124 | sizeof(struct extent_position)); | ||
125 | iinfo->cached_extent.lstart = estart; | ||
126 | if (next_epos) | ||
127 | switch (iinfo->i_alloc_type) { | ||
128 | case ICBTAG_FLAG_AD_SHORT: | ||
129 | iinfo->cached_extent.epos.offset -= | ||
130 | sizeof(struct short_ad); | ||
131 | break; | ||
132 | case ICBTAG_FLAG_AD_LONG: | ||
133 | iinfo->cached_extent.epos.offset -= | ||
134 | sizeof(struct long_ad); | ||
135 | } | ||
136 | spin_unlock(&iinfo->i_extent_cache_lock); | ||
137 | } | ||
70 | 138 | ||
71 | void udf_evict_inode(struct inode *inode) | 139 | void udf_evict_inode(struct inode *inode) |
72 | { | 140 | { |
@@ -90,6 +158,7 @@ void udf_evict_inode(struct inode *inode) | |||
90 | } | 158 | } |
91 | kfree(iinfo->i_ext.i_data); | 159 | kfree(iinfo->i_ext.i_data); |
92 | iinfo->i_ext.i_data = NULL; | 160 | iinfo->i_ext.i_data = NULL; |
161 | udf_clear_extent_cache(inode); | ||
93 | if (want_delete) { | 162 | if (want_delete) { |
94 | udf_free_inode(inode); | 163 | udf_free_inode(inode); |
95 | } | 164 | } |
@@ -105,6 +174,7 @@ static void udf_write_failed(struct address_space *mapping, loff_t to) | |||
105 | truncate_pagecache(inode, to, isize); | 174 | truncate_pagecache(inode, to, isize); |
106 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 175 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
107 | down_write(&iinfo->i_data_sem); | 176 | down_write(&iinfo->i_data_sem); |
177 | udf_clear_extent_cache(inode); | ||
108 | udf_truncate_extents(inode); | 178 | udf_truncate_extents(inode); |
109 | up_write(&iinfo->i_data_sem); | 179 | up_write(&iinfo->i_data_sem); |
110 | } | 180 | } |
@@ -372,7 +442,7 @@ static int udf_get_block(struct inode *inode, sector_t block, | |||
372 | iinfo->i_next_alloc_goal++; | 442 | iinfo->i_next_alloc_goal++; |
373 | } | 443 | } |
374 | 444 | ||
375 | 445 | udf_clear_extent_cache(inode); | |
376 | phys = inode_getblk(inode, block, &err, &new); | 446 | phys = inode_getblk(inode, block, &err, &new); |
377 | if (!phys) | 447 | if (!phys) |
378 | goto abort; | 448 | goto abort; |
@@ -1171,6 +1241,7 @@ set_size: | |||
1171 | } else { | 1241 | } else { |
1172 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 1242 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
1173 | down_write(&iinfo->i_data_sem); | 1243 | down_write(&iinfo->i_data_sem); |
1244 | udf_clear_extent_cache(inode); | ||
1174 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, | 1245 | memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize, |
1175 | 0x00, bsize - newsize - | 1246 | 0x00, bsize - newsize - |
1176 | udf_file_entry_alloc_offset(inode)); | 1247 | udf_file_entry_alloc_offset(inode)); |
@@ -1184,6 +1255,7 @@ set_size: | |||
1184 | if (err) | 1255 | if (err) |
1185 | return err; | 1256 | return err; |
1186 | down_write(&iinfo->i_data_sem); | 1257 | down_write(&iinfo->i_data_sem); |
1258 | udf_clear_extent_cache(inode); | ||
1187 | truncate_setsize(inode, newsize); | 1259 | truncate_setsize(inode, newsize); |
1188 | udf_truncate_extents(inode); | 1260 | udf_truncate_extents(inode); |
1189 | up_write(&iinfo->i_data_sem); | 1261 | up_write(&iinfo->i_data_sem); |
@@ -2156,11 +2228,12 @@ int8_t inode_bmap(struct inode *inode, sector_t block, | |||
2156 | struct udf_inode_info *iinfo; | 2228 | struct udf_inode_info *iinfo; |
2157 | 2229 | ||
2158 | iinfo = UDF_I(inode); | 2230 | iinfo = UDF_I(inode); |
2159 | pos->offset = 0; | 2231 | if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) { |
2160 | pos->block = iinfo->i_location; | 2232 | pos->offset = 0; |
2161 | pos->bh = NULL; | 2233 | pos->block = iinfo->i_location; |
2234 | pos->bh = NULL; | ||
2235 | } | ||
2162 | *elen = 0; | 2236 | *elen = 0; |
2163 | |||
2164 | do { | 2237 | do { |
2165 | etype = udf_next_aext(inode, pos, eloc, elen, 1); | 2238 | etype = udf_next_aext(inode, pos, eloc, elen, 1); |
2166 | if (etype == -1) { | 2239 | if (etype == -1) { |
@@ -2170,7 +2243,8 @@ int8_t inode_bmap(struct inode *inode, sector_t block, | |||
2170 | } | 2243 | } |
2171 | lbcount += *elen; | 2244 | lbcount += *elen; |
2172 | } while (lbcount <= bcount); | 2245 | } while (lbcount <= bcount); |
2173 | 2246 | /* update extent cache */ | |
2247 | udf_update_extent_cache(inode, lbcount - *elen, pos, 1); | ||
2174 | *offset = (bcount + *elen - lbcount) >> blocksize_bits; | 2248 | *offset = (bcount + *elen - lbcount) >> blocksize_bits; |
2175 | 2249 | ||
2176 | return etype; | 2250 | return etype; |
diff --git a/fs/udf/super.c b/fs/udf/super.c index e9be396a558d..bc5b30a819e8 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -134,6 +134,8 @@ static struct inode *udf_alloc_inode(struct super_block *sb) | |||
134 | ei->i_next_alloc_goal = 0; | 134 | ei->i_next_alloc_goal = 0; |
135 | ei->i_strat4096 = 0; | 135 | ei->i_strat4096 = 0; |
136 | init_rwsem(&ei->i_data_sem); | 136 | init_rwsem(&ei->i_data_sem); |
137 | ei->cached_extent.lstart = -1; | ||
138 | spin_lock_init(&ei->i_extent_cache_lock); | ||
137 | 139 | ||
138 | return &ei->vfs_inode; | 140 | return &ei->vfs_inode; |
139 | } | 141 | } |
@@ -1021,7 +1023,6 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
1021 | if (bitmap == NULL) | 1023 | if (bitmap == NULL) |
1022 | return NULL; | 1024 | return NULL; |
1023 | 1025 | ||
1024 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); | ||
1025 | bitmap->s_nr_groups = nr_groups; | 1026 | bitmap->s_nr_groups = nr_groups; |
1026 | return bitmap; | 1027 | return bitmap; |
1027 | } | 1028 | } |
@@ -1079,8 +1080,6 @@ static int udf_fill_partdesc_info(struct super_block *sb, | |||
1079 | if (!bitmap) | 1080 | if (!bitmap) |
1080 | return 1; | 1081 | return 1; |
1081 | map->s_uspace.s_bitmap = bitmap; | 1082 | map->s_uspace.s_bitmap = bitmap; |
1082 | bitmap->s_extLength = le32_to_cpu( | ||
1083 | phd->unallocSpaceBitmap.extLength); | ||
1084 | bitmap->s_extPosition = le32_to_cpu( | 1083 | bitmap->s_extPosition = le32_to_cpu( |
1085 | phd->unallocSpaceBitmap.extPosition); | 1084 | phd->unallocSpaceBitmap.extPosition); |
1086 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; | 1085 | map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; |
@@ -1115,8 +1114,6 @@ static int udf_fill_partdesc_info(struct super_block *sb, | |||
1115 | if (!bitmap) | 1114 | if (!bitmap) |
1116 | return 1; | 1115 | return 1; |
1117 | map->s_fspace.s_bitmap = bitmap; | 1116 | map->s_fspace.s_bitmap = bitmap; |
1118 | bitmap->s_extLength = le32_to_cpu( | ||
1119 | phd->freedSpaceBitmap.extLength); | ||
1120 | bitmap->s_extPosition = le32_to_cpu( | 1117 | bitmap->s_extPosition = le32_to_cpu( |
1121 | phd->freedSpaceBitmap.extPosition); | 1118 | phd->freedSpaceBitmap.extPosition); |
1122 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; | 1119 | map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP; |
@@ -1866,6 +1863,8 @@ static void udf_open_lvid(struct super_block *sb) | |||
1866 | mark_buffer_dirty(bh); | 1863 | mark_buffer_dirty(bh); |
1867 | sbi->s_lvid_dirty = 0; | 1864 | sbi->s_lvid_dirty = 0; |
1868 | mutex_unlock(&sbi->s_alloc_mutex); | 1865 | mutex_unlock(&sbi->s_alloc_mutex); |
1866 | /* Make opening of filesystem visible on the media immediately */ | ||
1867 | sync_dirty_buffer(bh); | ||
1869 | } | 1868 | } |
1870 | 1869 | ||
1871 | static void udf_close_lvid(struct super_block *sb) | 1870 | static void udf_close_lvid(struct super_block *sb) |
@@ -1906,6 +1905,8 @@ static void udf_close_lvid(struct super_block *sb) | |||
1906 | mark_buffer_dirty(bh); | 1905 | mark_buffer_dirty(bh); |
1907 | sbi->s_lvid_dirty = 0; | 1906 | sbi->s_lvid_dirty = 0; |
1908 | mutex_unlock(&sbi->s_alloc_mutex); | 1907 | mutex_unlock(&sbi->s_alloc_mutex); |
1908 | /* Make closing of filesystem visible on the media immediately */ | ||
1909 | sync_dirty_buffer(bh); | ||
1909 | } | 1910 | } |
1910 | 1911 | ||
1911 | u64 lvid_get_unique_id(struct super_block *sb) | 1912 | u64 lvid_get_unique_id(struct super_block *sb) |
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index bb8309dcd5c1..b5cd8ed2aa12 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h | |||
@@ -1,6 +1,19 @@ | |||
1 | #ifndef _UDF_I_H | 1 | #ifndef _UDF_I_H |
2 | #define _UDF_I_H | 2 | #define _UDF_I_H |
3 | 3 | ||
4 | struct extent_position { | ||
5 | struct buffer_head *bh; | ||
6 | uint32_t offset; | ||
7 | struct kernel_lb_addr block; | ||
8 | }; | ||
9 | |||
10 | struct udf_ext_cache { | ||
11 | /* Extent position */ | ||
12 | struct extent_position epos; | ||
13 | /* Start logical offset in bytes */ | ||
14 | loff_t lstart; | ||
15 | }; | ||
16 | |||
4 | /* | 17 | /* |
5 | * The i_data_sem and i_mutex serve for protection of allocation information | 18 | * The i_data_sem and i_mutex serve for protection of allocation information |
6 | * of a regular files and symlinks. This includes all extents belonging to | 19 | * of a regular files and symlinks. This includes all extents belonging to |
@@ -35,6 +48,9 @@ struct udf_inode_info { | |||
35 | __u8 *i_data; | 48 | __u8 *i_data; |
36 | } i_ext; | 49 | } i_ext; |
37 | struct rw_semaphore i_data_sem; | 50 | struct rw_semaphore i_data_sem; |
51 | struct udf_ext_cache cached_extent; | ||
52 | /* Spinlock for protecting extent cache */ | ||
53 | spinlock_t i_extent_cache_lock; | ||
38 | struct inode vfs_inode; | 54 | struct inode vfs_inode; |
39 | }; | 55 | }; |
40 | 56 | ||
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 5f027227f085..ed401e94aa8c 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -80,10 +80,9 @@ struct udf_virtual_data { | |||
80 | }; | 80 | }; |
81 | 81 | ||
82 | struct udf_bitmap { | 82 | struct udf_bitmap { |
83 | __u32 s_extLength; | ||
84 | __u32 s_extPosition; | 83 | __u32 s_extPosition; |
85 | __u16 s_nr_groups; | 84 | int s_nr_groups; |
86 | struct buffer_head **s_block_bitmap; | 85 | struct buffer_head *s_block_bitmap[0]; |
87 | }; | 86 | }; |
88 | 87 | ||
89 | struct udf_part_map { | 88 | struct udf_part_map { |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index de038da6f6bd..be7dabbbcb49 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -113,11 +113,6 @@ struct ustr { | |||
113 | uint8_t u_len; | 113 | uint8_t u_len; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct extent_position { | ||
117 | struct buffer_head *bh; | ||
118 | uint32_t offset; | ||
119 | struct kernel_lb_addr block; | ||
120 | }; | ||
121 | 116 | ||
122 | /* super.c */ | 117 | /* super.c */ |
123 | 118 | ||