diff options
author | Tao Ma <boyu.mt@taobao.com> | 2012-10-22 00:34:32 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-10-22 00:34:32 -0400 |
commit | 79f1ba49569e5aec919b653c55b03274c2331701 (patch) | |
tree | 612d4200d13a10d5df0cb6508cc5b1e7fd10fd45 /fs/ext4 | |
parent | 76495ec1d47e1c0fe0673faf9179bda6bc8ab5c2 (diff) |
ext4: Checksum the block bitmap properly with bigalloc enabled
In mke2fs, we only checksum the whole bitmap block and it is right.
While in the kernel, we use EXT4_BLOCKS_PER_GROUP to indicate the
size of the checksumed bitmap which is wrong when we enable bigalloc.
The right size should be EXT4_CLUSTERS_PER_GROUP and this patch fixes
it.
Also as every caller of ext4_block_bitmap_csum_set and
ext4_block_bitmap_csum_verify pass in EXT4_BLOCKS_PER_GROUP(sb)/8,
we'd better removes this parameter and sets it in the function itself.
Signed-off-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Lukas Czerner <lczerner@redhat.com>
Cc: stable@vger.kernel.org
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/balloc.c | 8 | ||||
-rw-r--r-- | fs/ext4/bitmap.c | 6 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 4 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 4 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 9 | ||||
-rw-r--r-- | fs/ext4/resize.c | 3 |
6 files changed, 14 insertions, 20 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 1b5089067d01..cf1821784a16 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -174,8 +174,7 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
174 | ext4_free_inodes_set(sb, gdp, 0); | 174 | ext4_free_inodes_set(sb, gdp, 0); |
175 | ext4_itable_unused_set(sb, gdp, 0); | 175 | ext4_itable_unused_set(sb, gdp, 0); |
176 | memset(bh->b_data, 0xff, sb->s_blocksize); | 176 | memset(bh->b_data, 0xff, sb->s_blocksize); |
177 | ext4_block_bitmap_csum_set(sb, block_group, gdp, bh, | 177 | ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); |
178 | EXT4_BLOCKS_PER_GROUP(sb) / 8); | ||
179 | return; | 178 | return; |
180 | } | 179 | } |
181 | memset(bh->b_data, 0, sb->s_blocksize); | 180 | memset(bh->b_data, 0, sb->s_blocksize); |
@@ -212,8 +211,7 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
212 | */ | 211 | */ |
213 | ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), | 212 | ext4_mark_bitmap_end(num_clusters_in_group(sb, block_group), |
214 | sb->s_blocksize * 8, bh->b_data); | 213 | sb->s_blocksize * 8, bh->b_data); |
215 | ext4_block_bitmap_csum_set(sb, block_group, gdp, bh, | 214 | ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); |
216 | EXT4_BLOCKS_PER_GROUP(sb) / 8); | ||
217 | ext4_group_desc_csum_set(sb, block_group, gdp); | 215 | ext4_group_desc_csum_set(sb, block_group, gdp); |
218 | } | 216 | } |
219 | 217 | ||
@@ -350,7 +348,7 @@ void ext4_validate_block_bitmap(struct super_block *sb, | |||
350 | return; | 348 | return; |
351 | } | 349 | } |
352 | if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, | 350 | if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, |
353 | desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) { | 351 | desc, bh))) { |
354 | ext4_unlock_group(sb, block_group); | 352 | ext4_unlock_group(sb, block_group); |
355 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); | 353 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); |
356 | return; | 354 | return; |
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index 5c2d1813ebe9..3285aa5a706a 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c | |||
@@ -58,11 +58,12 @@ void ext4_inode_bitmap_csum_set(struct super_block *sb, ext4_group_t group, | |||
58 | 58 | ||
59 | int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | 59 | int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, |
60 | struct ext4_group_desc *gdp, | 60 | struct ext4_group_desc *gdp, |
61 | struct buffer_head *bh, int sz) | 61 | struct buffer_head *bh) |
62 | { | 62 | { |
63 | __u32 hi; | 63 | __u32 hi; |
64 | __u32 provided, calculated; | 64 | __u32 provided, calculated; |
65 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 65 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
66 | int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; | ||
66 | 67 | ||
67 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, | 68 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, |
68 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) | 69 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)) |
@@ -84,8 +85,9 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | |||
84 | 85 | ||
85 | void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, | 86 | void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, |
86 | struct ext4_group_desc *gdp, | 87 | struct ext4_group_desc *gdp, |
87 | struct buffer_head *bh, int sz) | 88 | struct buffer_head *bh) |
88 | { | 89 | { |
90 | int sz = EXT4_CLUSTERS_PER_GROUP(sb) / 8; | ||
89 | __u32 csum; | 91 | __u32 csum; |
90 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 92 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
91 | 93 | ||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 78971cfd9c7f..3c20de1d59d0 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1882,10 +1882,10 @@ int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | |||
1882 | struct buffer_head *bh, int sz); | 1882 | struct buffer_head *bh, int sz); |
1883 | void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, | 1883 | void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, |
1884 | struct ext4_group_desc *gdp, | 1884 | struct ext4_group_desc *gdp, |
1885 | struct buffer_head *bh, int sz); | 1885 | struct buffer_head *bh); |
1886 | int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | 1886 | int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, |
1887 | struct ext4_group_desc *gdp, | 1887 | struct ext4_group_desc *gdp, |
1888 | struct buffer_head *bh, int sz); | 1888 | struct buffer_head *bh); |
1889 | 1889 | ||
1890 | /* balloc.c */ | 1890 | /* balloc.c */ |
1891 | extern void ext4_validate_block_bitmap(struct super_block *sb, | 1891 | extern void ext4_validate_block_bitmap(struct super_block *sb, |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index fa36372f3fdf..4facdd29a350 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -762,9 +762,7 @@ got: | |||
762 | ext4_free_group_clusters_set(sb, gdp, | 762 | ext4_free_group_clusters_set(sb, gdp, |
763 | ext4_free_clusters_after_init(sb, group, gdp)); | 763 | ext4_free_clusters_after_init(sb, group, gdp)); |
764 | ext4_block_bitmap_csum_set(sb, group, gdp, | 764 | ext4_block_bitmap_csum_set(sb, group, gdp, |
765 | block_bitmap_bh, | 765 | block_bitmap_bh); |
766 | EXT4_BLOCKS_PER_GROUP(sb) / | ||
767 | 8); | ||
768 | ext4_group_desc_csum_set(sb, group, gdp); | 766 | ext4_group_desc_csum_set(sb, group, gdp); |
769 | } | 767 | } |
770 | ext4_unlock_group(sb, group); | 768 | ext4_unlock_group(sb, group); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a415465f97a0..eb1e385d8080 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2805,8 +2805,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2805 | } | 2805 | } |
2806 | len = ext4_free_group_clusters(sb, gdp) - ac->ac_b_ex.fe_len; | 2806 | len = ext4_free_group_clusters(sb, gdp) - ac->ac_b_ex.fe_len; |
2807 | ext4_free_group_clusters_set(sb, gdp, len); | 2807 | ext4_free_group_clusters_set(sb, gdp, len); |
2808 | ext4_block_bitmap_csum_set(sb, ac->ac_b_ex.fe_group, gdp, bitmap_bh, | 2808 | ext4_block_bitmap_csum_set(sb, ac->ac_b_ex.fe_group, gdp, bitmap_bh); |
2809 | EXT4_BLOCKS_PER_GROUP(sb) / 8); | ||
2810 | ext4_group_desc_csum_set(sb, ac->ac_b_ex.fe_group, gdp); | 2809 | ext4_group_desc_csum_set(sb, ac->ac_b_ex.fe_group, gdp); |
2811 | 2810 | ||
2812 | ext4_unlock_group(sb, ac->ac_b_ex.fe_group); | 2811 | ext4_unlock_group(sb, ac->ac_b_ex.fe_group); |
@@ -4666,8 +4665,7 @@ do_more: | |||
4666 | 4665 | ||
4667 | ret = ext4_free_group_clusters(sb, gdp) + count_clusters; | 4666 | ret = ext4_free_group_clusters(sb, gdp) + count_clusters; |
4668 | ext4_free_group_clusters_set(sb, gdp, ret); | 4667 | ext4_free_group_clusters_set(sb, gdp, ret); |
4669 | ext4_block_bitmap_csum_set(sb, block_group, gdp, bitmap_bh, | 4668 | ext4_block_bitmap_csum_set(sb, block_group, gdp, bitmap_bh); |
4670 | EXT4_BLOCKS_PER_GROUP(sb) / 8); | ||
4671 | ext4_group_desc_csum_set(sb, block_group, gdp); | 4669 | ext4_group_desc_csum_set(sb, block_group, gdp); |
4672 | ext4_unlock_group(sb, block_group); | 4670 | ext4_unlock_group(sb, block_group); |
4673 | percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters); | 4671 | percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters); |
@@ -4811,8 +4809,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, | |||
4811 | mb_free_blocks(NULL, &e4b, bit, count); | 4809 | mb_free_blocks(NULL, &e4b, bit, count); |
4812 | blk_free_count = blocks_freed + ext4_free_group_clusters(sb, desc); | 4810 | blk_free_count = blocks_freed + ext4_free_group_clusters(sb, desc); |
4813 | ext4_free_group_clusters_set(sb, desc, blk_free_count); | 4811 | ext4_free_group_clusters_set(sb, desc, blk_free_count); |
4814 | ext4_block_bitmap_csum_set(sb, block_group, desc, bitmap_bh, | 4812 | ext4_block_bitmap_csum_set(sb, block_group, desc, bitmap_bh); |
4815 | EXT4_BLOCKS_PER_GROUP(sb) / 8); | ||
4816 | ext4_group_desc_csum_set(sb, block_group, desc); | 4813 | ext4_group_desc_csum_set(sb, block_group, desc); |
4817 | ext4_unlock_group(sb, block_group); | 4814 | ext4_unlock_group(sb, block_group); |
4818 | percpu_counter_add(&sbi->s_freeclusters_counter, | 4815 | percpu_counter_add(&sbi->s_freeclusters_counter, |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 7a75e1086961..47bf06a2765d 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -1212,8 +1212,7 @@ static int ext4_set_bitmap_checksums(struct super_block *sb, | |||
1212 | bh = ext4_get_bitmap(sb, group_data->block_bitmap); | 1212 | bh = ext4_get_bitmap(sb, group_data->block_bitmap); |
1213 | if (!bh) | 1213 | if (!bh) |
1214 | return -EIO; | 1214 | return -EIO; |
1215 | ext4_block_bitmap_csum_set(sb, group, gdp, bh, | 1215 | ext4_block_bitmap_csum_set(sb, group, gdp, bh); |
1216 | EXT4_BLOCKS_PER_GROUP(sb) / 8); | ||
1217 | brelse(bh); | 1216 | brelse(bh); |
1218 | 1217 | ||
1219 | return 0; | 1218 | return 0; |