diff options
| -rw-r--r-- | fs/ext4/balloc.c | 16 | ||||
| -rw-r--r-- | fs/ext4/ialloc.c | 23 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 8 |
3 files changed, 47 insertions, 0 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 0762d143e252..fca382037ddd 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -194,7 +194,16 @@ static void ext4_init_block_bitmap(struct super_block *sb, | |||
| 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); | 195 | ext4_error(sb, "Checksum bad for group %u", block_group); |
| 196 | grp = ext4_get_group_info(sb, block_group); | 196 | grp = ext4_get_group_info(sb, block_group); |
| 197 | if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) | ||
| 198 | percpu_counter_sub(&sbi->s_freeclusters_counter, | ||
| 199 | grp->bb_free); | ||
| 197 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); | 200 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 201 | if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { | ||
| 202 | int count; | ||
| 203 | count = ext4_free_inodes_count(sb, gdp); | ||
| 204 | percpu_counter_sub(&sbi->s_freeinodes_counter, | ||
| 205 | count); | ||
| 206 | } | ||
| 198 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); | 207 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 199 | return; | 208 | return; |
| 200 | } | 209 | } |
| @@ -359,6 +368,7 @@ static void ext4_validate_block_bitmap(struct super_block *sb, | |||
| 359 | { | 368 | { |
| 360 | ext4_fsblk_t blk; | 369 | ext4_fsblk_t blk; |
| 361 | struct ext4_group_info *grp = ext4_get_group_info(sb, block_group); | 370 | struct ext4_group_info *grp = ext4_get_group_info(sb, block_group); |
| 371 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 362 | 372 | ||
| 363 | if (buffer_verified(bh)) | 373 | if (buffer_verified(bh)) |
| 364 | return; | 374 | return; |
| @@ -369,6 +379,9 @@ static void ext4_validate_block_bitmap(struct super_block *sb, | |||
| 369 | ext4_unlock_group(sb, block_group); | 379 | ext4_unlock_group(sb, block_group); |
| 370 | ext4_error(sb, "bg %u: block %llu: invalid block bitmap", | 380 | ext4_error(sb, "bg %u: block %llu: invalid block bitmap", |
| 371 | block_group, blk); | 381 | block_group, blk); |
| 382 | if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) | ||
| 383 | percpu_counter_sub(&sbi->s_freeclusters_counter, | ||
| 384 | grp->bb_free); | ||
| 372 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); | 385 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 373 | return; | 386 | return; |
| 374 | } | 387 | } |
| @@ -376,6 +389,9 @@ static void ext4_validate_block_bitmap(struct super_block *sb, | |||
| 376 | desc, bh))) { | 389 | desc, bh))) { |
| 377 | ext4_unlock_group(sb, block_group); | 390 | ext4_unlock_group(sb, block_group); |
| 378 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); | 391 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); |
| 392 | if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) | ||
| 393 | percpu_counter_sub(&sbi->s_freeclusters_counter, | ||
| 394 | grp->bb_free); | ||
| 379 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); | 395 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 380 | return; | 396 | return; |
| 381 | } | 397 | } |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 0ee59a6644e2..a87455df38bc 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -71,6 +71,7 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb, | |||
| 71 | struct ext4_group_desc *gdp) | 71 | struct ext4_group_desc *gdp) |
| 72 | { | 72 | { |
| 73 | struct ext4_group_info *grp; | 73 | struct ext4_group_info *grp; |
| 74 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 74 | J_ASSERT_BH(bh, buffer_locked(bh)); | 75 | J_ASSERT_BH(bh, buffer_locked(bh)); |
| 75 | 76 | ||
| 76 | /* If checksum is bad mark all blocks and inodes use to prevent | 77 | /* If checksum is bad mark all blocks and inodes use to prevent |
| @@ -78,7 +79,16 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb, | |||
| 78 | if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { | 79 | if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { |
| 79 | ext4_error(sb, "Checksum bad for group %u", block_group); | 80 | ext4_error(sb, "Checksum bad for group %u", block_group); |
| 80 | grp = ext4_get_group_info(sb, block_group); | 81 | grp = ext4_get_group_info(sb, block_group); |
| 82 | if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) | ||
| 83 | percpu_counter_sub(&sbi->s_freeclusters_counter, | ||
| 84 | grp->bb_free); | ||
| 81 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); | 85 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 86 | if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { | ||
| 87 | int count; | ||
| 88 | count = ext4_free_inodes_count(sb, gdp); | ||
| 89 | percpu_counter_sub(&sbi->s_freeinodes_counter, | ||
| 90 | count); | ||
| 91 | } | ||
| 82 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); | 92 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 83 | return 0; | 93 | return 0; |
| 84 | } | 94 | } |
| @@ -116,6 +126,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
| 116 | struct buffer_head *bh = NULL; | 126 | struct buffer_head *bh = NULL; |
| 117 | ext4_fsblk_t bitmap_blk; | 127 | ext4_fsblk_t bitmap_blk; |
| 118 | struct ext4_group_info *grp; | 128 | struct ext4_group_info *grp; |
| 129 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 119 | 130 | ||
| 120 | desc = ext4_get_group_desc(sb, block_group, NULL); | 131 | desc = ext4_get_group_desc(sb, block_group, NULL); |
| 121 | if (!desc) | 132 | if (!desc) |
| @@ -185,6 +196,12 @@ verify: | |||
| 185 | ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " | 196 | ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " |
| 186 | "inode_bitmap = %llu", block_group, bitmap_blk); | 197 | "inode_bitmap = %llu", block_group, bitmap_blk); |
| 187 | grp = ext4_get_group_info(sb, block_group); | 198 | grp = ext4_get_group_info(sb, block_group); |
| 199 | if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { | ||
| 200 | int count; | ||
| 201 | count = ext4_free_inodes_count(sb, desc); | ||
| 202 | percpu_counter_sub(&sbi->s_freeinodes_counter, | ||
| 203 | count); | ||
| 204 | } | ||
| 188 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); | 205 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 189 | return NULL; | 206 | return NULL; |
| 190 | } | 207 | } |
| @@ -321,6 +338,12 @@ out: | |||
| 321 | fatal = err; | 338 | fatal = err; |
| 322 | } else { | 339 | } else { |
| 323 | ext4_error(sb, "bit already cleared for inode %lu", ino); | 340 | ext4_error(sb, "bit already cleared for inode %lu", ino); |
| 341 | if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { | ||
| 342 | int count; | ||
| 343 | count = ext4_free_inodes_count(sb, gdp); | ||
| 344 | percpu_counter_sub(&sbi->s_freeinodes_counter, | ||
| 345 | count); | ||
| 346 | } | ||
| 324 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); | 347 | set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 325 | } | 348 | } |
| 326 | 349 | ||
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 59e31622cc6e..7f72f50a8fa7 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -722,6 +722,7 @@ void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 722 | void *buddy, void *bitmap, ext4_group_t group) | 722 | void *buddy, void *bitmap, ext4_group_t group) |
| 723 | { | 723 | { |
| 724 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); | 724 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
| 725 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 725 | ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb); | 726 | ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb); |
| 726 | ext4_grpblk_t i = 0; | 727 | ext4_grpblk_t i = 0; |
| 727 | ext4_grpblk_t first; | 728 | ext4_grpblk_t first; |
| @@ -759,6 +760,9 @@ void ext4_mb_generate_buddy(struct super_block *sb, | |||
| 759 | * corrupt and update bb_free using bitmap value | 760 | * corrupt and update bb_free using bitmap value |
| 760 | */ | 761 | */ |
| 761 | grp->bb_free = free; | 762 | grp->bb_free = free; |
| 763 | if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) | ||
| 764 | percpu_counter_sub(&sbi->s_freeclusters_counter, | ||
| 765 | grp->bb_free); | ||
| 762 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); | 766 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); |
| 763 | } | 767 | } |
| 764 | mb_set_largest_free_order(sb, grp); | 768 | mb_set_largest_free_order(sb, grp); |
| @@ -1431,6 +1435,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, | |||
| 1431 | right_is_free = !mb_test_bit(last + 1, e4b->bd_bitmap); | 1435 | right_is_free = !mb_test_bit(last + 1, e4b->bd_bitmap); |
| 1432 | 1436 | ||
| 1433 | if (unlikely(block != -1)) { | 1437 | if (unlikely(block != -1)) { |
| 1438 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
| 1434 | ext4_fsblk_t blocknr; | 1439 | ext4_fsblk_t blocknr; |
| 1435 | 1440 | ||
| 1436 | blocknr = ext4_group_first_block_no(sb, e4b->bd_group); | 1441 | blocknr = ext4_group_first_block_no(sb, e4b->bd_group); |
| @@ -1441,6 +1446,9 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, | |||
| 1441 | "freeing already freed block " | 1446 | "freeing already freed block " |
| 1442 | "(bit %u); block bitmap corrupt.", | 1447 | "(bit %u); block bitmap corrupt.", |
| 1443 | block); | 1448 | block); |
| 1449 | if (!EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info)) | ||
| 1450 | percpu_counter_sub(&sbi->s_freeclusters_counter, | ||
| 1451 | e4b->bd_info->bb_free); | ||
| 1444 | /* Mark the block group as corrupt. */ | 1452 | /* Mark the block group as corrupt. */ |
| 1445 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, | 1453 | set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, |
| 1446 | &e4b->bd_info->bb_state); | 1454 | &e4b->bd_info->bb_state); |
