diff options
| -rw-r--r-- | fs/ext4/balloc.c | 12 |
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 */ |
| 179 | static void ext4_init_block_bitmap(struct super_block *sb, | 179 | static 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); |
