diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-29 19:20:43 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-29 19:20:43 -0700 | 
| 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,  				       struct ext4_group_desc *gdp)  {  	struct ext4_group_info *grp; +	struct ext4_sb_info *sbi = EXT4_SB(sb);  	J_ASSERT_BH(bh, buffer_locked(bh));  	/* 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,  	if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {  		ext4_error(sb, "Checksum bad for group %u", block_group);  		grp = ext4_get_group_info(sb, block_group); +		if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) +			percpu_counter_sub(&sbi->s_freeclusters_counter, +					   grp->bb_free);  		set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); +		if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { +			int count; +			count = ext4_free_inodes_count(sb, gdp); +			percpu_counter_sub(&sbi->s_freeinodes_counter, +					   count); +		}  		set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);  		return 0;  	} @@ -116,6 +126,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)  	struct buffer_head *bh = NULL;  	ext4_fsblk_t bitmap_blk;  	struct ext4_group_info *grp; +	struct ext4_sb_info *sbi = EXT4_SB(sb);  	desc = ext4_get_group_desc(sb, block_group, NULL);  	if (!desc) @@ -185,6 +196,12 @@ verify:  		ext4_error(sb, "Corrupt inode bitmap - block_group = %u, "  			   "inode_bitmap = %llu", block_group, bitmap_blk);  		grp = ext4_get_group_info(sb, block_group); +		if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { +			int count; +			count = ext4_free_inodes_count(sb, desc); +			percpu_counter_sub(&sbi->s_freeinodes_counter, +					   count); +		}  		set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);  		return NULL;  	} @@ -321,6 +338,12 @@ out:  			fatal = err;  	} else {  		ext4_error(sb, "bit already cleared for inode %lu", ino); +		if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { +			int count; +			count = ext4_free_inodes_count(sb, gdp); +			percpu_counter_sub(&sbi->s_freeinodes_counter, +					   count); +		}  		set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);  	}  | 
