diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-29 22:20:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-29 22:20:43 -0400 |
commit | 16874b2cb867d3eb63ed838f2847143e11556708 (patch) | |
tree | 3052bd2c5fe3a661ef42dea767d6a782d71c821b /fs/ext4/ialloc.c | |
parent | 4c834452aad01531db949414f94f817a86348d59 (diff) | |
parent | a93cd4cf86466caa49cfe64607bea7f0bde3f916 (diff) |
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bugfixes from Ted Ts'o:
"Fix a regression when trying to compile ext4 on older versions gcc.
Fix a number of miscellaneous bugs for punch hole as well as a
long-standing potential double buffer head release when failing a
block allocation for an indirect-mapped file"
* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: Fix hole punching for files with indirect blocks
ext4: Fix block zeroing when punching holes in indirect block files
ext4: decrement free clusters/inodes counters when block group declared bad
fs/mbcache: replace __builtin_log2() with ilog2()
ext4: Fix buffer double free in ext4_alloc_branch()
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 | ||