aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTao Ma <boyu.mt@taobao.com>2012-10-22 00:34:32 -0400
committerTheodore Ts'o <tytso@mit.edu>2012-10-22 00:34:32 -0400
commit79f1ba49569e5aec919b653c55b03274c2331701 (patch)
tree612d4200d13a10d5df0cb6508cc5b1e7fd10fd45 /fs
parent76495ec1d47e1c0fe0673faf9179bda6bc8ab5c2 (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')
-rw-r--r--fs/ext4/balloc.c8
-rw-r--r--fs/ext4/bitmap.c6
-rw-r--r--fs/ext4/ext4.h4
-rw-r--r--fs/ext4/ialloc.c4
-rw-r--r--fs/ext4/mballoc.c9
-rw-r--r--fs/ext4/resize.c3
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
59int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 59int 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
85void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 86void 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);
1883void ext4_block_bitmap_csum_set(struct super_block *sb, ext4_group_t group, 1883void 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);
1886int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, 1886int 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 */
1891extern void ext4_validate_block_bitmap(struct super_block *sb, 1891extern 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;