aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/balloc.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index d70f154f6da3..83a6f497c4e0 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -176,7 +176,7 @@ static unsigned int num_clusters_in_group(struct super_block *sb,
176} 176}
177 177
178/* Initializes an uninitialized block bitmap */ 178/* Initializes an uninitialized block bitmap */
179static void ext4_init_block_bitmap(struct super_block *sb, 179static int ext4_init_block_bitmap(struct super_block *sb,
180 struct buffer_head *bh, 180 struct buffer_head *bh,
181 ext4_group_t block_group, 181 ext4_group_t block_group,
182 struct ext4_group_desc *gdp) 182 struct ext4_group_desc *gdp)
@@ -192,7 +192,6 @@ static void ext4_init_block_bitmap(struct super_block *sb,
192 /* If checksum is bad mark all blocks used to prevent allocation 192 /* If checksum is bad mark all blocks used to prevent allocation
193 * essentially implementing a per-group read-only flag. */ 193 * essentially implementing a per-group read-only flag. */
194 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { 194 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
195 ext4_error(sb, "Checksum bad for group %u", block_group);
196 grp = ext4_get_group_info(sb, block_group); 195 grp = ext4_get_group_info(sb, block_group);
197 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 196 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
198 percpu_counter_sub(&sbi->s_freeclusters_counter, 197 percpu_counter_sub(&sbi->s_freeclusters_counter,
@@ -205,7 +204,7 @@ static void ext4_init_block_bitmap(struct super_block *sb,
205 count); 204 count);
206 } 205 }
207 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); 206 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
208 return; 207 return -EIO;
209 } 208 }
210 memset(bh->b_data, 0, sb->s_blocksize); 209 memset(bh->b_data, 0, sb->s_blocksize);
211 210
@@ -243,6 +242,7 @@ static void ext4_init_block_bitmap(struct super_block *sb,
243 sb->s_blocksize * 8, bh->b_data); 242 sb->s_blocksize * 8, bh->b_data);
244 ext4_block_bitmap_csum_set(sb, block_group, gdp, bh); 243 ext4_block_bitmap_csum_set(sb, block_group, gdp, bh);
245 ext4_group_desc_csum_set(sb, block_group, gdp); 244 ext4_group_desc_csum_set(sb, block_group, gdp);
245 return 0;
246} 246}
247 247
248/* Return the number of free blocks in a block group. It is used when 248/* Return the number of free blocks in a block group. It is used when
@@ -438,11 +438,15 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
438 } 438 }
439 ext4_lock_group(sb, block_group); 439 ext4_lock_group(sb, block_group);
440 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 440 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
441 ext4_init_block_bitmap(sb, bh, block_group, desc); 441 int err;
442
443 err = ext4_init_block_bitmap(sb, bh, block_group, desc);
442 set_bitmap_uptodate(bh); 444 set_bitmap_uptodate(bh);
443 set_buffer_uptodate(bh); 445 set_buffer_uptodate(bh);
444 ext4_unlock_group(sb, block_group); 446 ext4_unlock_group(sb, block_group);
445 unlock_buffer(bh); 447 unlock_buffer(bh);
448 if (err)
449 ext4_error(sb, "Checksum bad for grp %u", block_group);
446 return bh; 450 return bh;
447 } 451 }
448 ext4_unlock_group(sb, block_group); 452 ext4_unlock_group(sb, block_group);