diff options
Diffstat (limited to 'fs/ext4/ialloc.c')
-rw-r--r-- | fs/ext4/ialloc.c | 23 |
1 files changed, 23 insertions, 0 deletions
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 | ||