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 | |
| 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
| -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 | ||
