Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()

+68 -6
+16
fs/ext4/balloc.c
··· 194 194 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { 195 195 ext4_error(sb, "Checksum bad for group %u", block_group); 196 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 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 207 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); 199 208 return; 200 209 } ··· 368 359 { 369 360 ext4_fsblk_t blk; 370 361 struct ext4_group_info *grp = ext4_get_group_info(sb, block_group); 362 + struct ext4_sb_info *sbi = EXT4_SB(sb); 371 363 372 364 if (buffer_verified(bh)) 373 365 return; ··· 379 369 ext4_unlock_group(sb, block_group); 380 370 ext4_error(sb, "bg %u: block %llu: invalid block bitmap", 381 371 block_group, blk); 372 + if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 373 + percpu_counter_sub(&sbi->s_freeclusters_counter, 374 + grp->bb_free); 382 375 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); 383 376 return; 384 377 } ··· 389 376 desc, bh))) { 390 377 ext4_unlock_group(sb, block_group); 391 378 ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); 379 + if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 380 + percpu_counter_sub(&sbi->s_freeclusters_counter, 381 + grp->bb_free); 392 382 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); 393 383 return; 394 384 }
+23
fs/ext4/ialloc.c
··· 71 71 struct ext4_group_desc *gdp) 72 72 { 73 73 struct ext4_group_info *grp; 74 + struct ext4_sb_info *sbi = EXT4_SB(sb); 74 75 J_ASSERT_BH(bh, buffer_locked(bh)); 75 76 76 77 /* If checksum is bad mark all blocks and inodes use to prevent ··· 79 78 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) { 80 79 ext4_error(sb, "Checksum bad for group %u", block_group); 81 80 grp = ext4_get_group_info(sb, block_group); 81 + if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 82 + percpu_counter_sub(&sbi->s_freeclusters_counter, 83 + grp->bb_free); 82 84 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); 85 + if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { 86 + int count; 87 + count = ext4_free_inodes_count(sb, gdp); 88 + percpu_counter_sub(&sbi->s_freeinodes_counter, 89 + count); 90 + } 83 91 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); 84 92 return 0; 85 93 } ··· 126 116 struct buffer_head *bh = NULL; 127 117 ext4_fsblk_t bitmap_blk; 128 118 struct ext4_group_info *grp; 119 + struct ext4_sb_info *sbi = EXT4_SB(sb); 129 120 130 121 desc = ext4_get_group_desc(sb, block_group, NULL); 131 122 if (!desc) ··· 196 185 ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " 197 186 "inode_bitmap = %llu", block_group, bitmap_blk); 198 187 grp = ext4_get_group_info(sb, block_group); 188 + if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { 189 + int count; 190 + count = ext4_free_inodes_count(sb, desc); 191 + percpu_counter_sub(&sbi->s_freeinodes_counter, 192 + count); 193 + } 199 194 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); 200 195 return NULL; 201 196 } ··· 338 321 fatal = err; 339 322 } else { 340 323 ext4_error(sb, "bit already cleared for inode %lu", ino); 324 + if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) { 325 + int count; 326 + count = ext4_free_inodes_count(sb, gdp); 327 + percpu_counter_sub(&sbi->s_freeinodes_counter, 328 + count); 329 + } 341 330 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state); 342 331 } 343 332
+19 -5
fs/ext4/indirect.c
··· 389 389 return 0; 390 390 failed: 391 391 for (; i >= 0; i--) { 392 - if (i != indirect_blks && branch[i].bh) 392 + /* 393 + * We want to ext4_forget() only freshly allocated indirect 394 + * blocks. Buffer for new_blocks[i-1] is at branch[i].bh and 395 + * buffer at branch[0].bh is indirect block / inode already 396 + * existing before ext4_alloc_branch() was called. 397 + */ 398 + if (i > 0 && i != indirect_blks && branch[i].bh) 393 399 ext4_forget(handle, 1, inode, branch[i].bh, 394 400 branch[i].bh->b_blocknr); 395 401 ext4_free_blocks(handle, inode, NULL, new_blocks[i], ··· 1316 1310 blk = *i_data; 1317 1311 if (level > 0) { 1318 1312 ext4_lblk_t first2; 1313 + ext4_lblk_t count2; 1314 + 1319 1315 bh = sb_bread(inode->i_sb, le32_to_cpu(blk)); 1320 1316 if (!bh) { 1321 1317 EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk), 1322 1318 "Read failure"); 1323 1319 return -EIO; 1324 1320 } 1325 - first2 = (first > offset) ? first - offset : 0; 1321 + if (first > offset) { 1322 + first2 = first - offset; 1323 + count2 = count; 1324 + } else { 1325 + first2 = 0; 1326 + count2 = count - (offset - first); 1327 + } 1326 1328 ret = free_hole_blocks(handle, inode, bh, 1327 1329 (__le32 *)bh->b_data, level - 1, 1328 - first2, count - offset, 1330 + first2, count2, 1329 1331 inode->i_sb->s_blocksize >> 2); 1330 1332 if (ret) { 1331 1333 brelse(bh); ··· 1343 1329 if (level == 0 || 1344 1330 (bh && all_zeroes((__le32 *)bh->b_data, 1345 1331 (__le32 *)bh->b_data + addr_per_block))) { 1346 - ext4_free_data(handle, inode, parent_bh, &blk, &blk+1); 1347 - *i_data = 0; 1332 + ext4_free_data(handle, inode, parent_bh, 1333 + i_data, i_data + 1); 1348 1334 } 1349 1335 brelse(bh); 1350 1336 bh = NULL;
+8
fs/ext4/mballoc.c
··· 722 722 void *buddy, void *bitmap, ext4_group_t group) 723 723 { 724 724 struct ext4_group_info *grp = ext4_get_group_info(sb, group); 725 + struct ext4_sb_info *sbi = EXT4_SB(sb); 725 726 ext4_grpblk_t max = EXT4_CLUSTERS_PER_GROUP(sb); 726 727 ext4_grpblk_t i = 0; 727 728 ext4_grpblk_t first; ··· 760 759 * corrupt and update bb_free using bitmap value 761 760 */ 762 761 grp->bb_free = free; 762 + if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) 763 + percpu_counter_sub(&sbi->s_freeclusters_counter, 764 + grp->bb_free); 763 765 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state); 764 766 } 765 767 mb_set_largest_free_order(sb, grp); ··· 1435 1431 right_is_free = !mb_test_bit(last + 1, e4b->bd_bitmap); 1436 1432 1437 1433 if (unlikely(block != -1)) { 1434 + struct ext4_sb_info *sbi = EXT4_SB(sb); 1438 1435 ext4_fsblk_t blocknr; 1439 1436 1440 1437 blocknr = ext4_group_first_block_no(sb, e4b->bd_group); ··· 1446 1441 "freeing already freed block " 1447 1442 "(bit %u); block bitmap corrupt.", 1448 1443 block); 1444 + if (!EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info)) 1445 + percpu_counter_sub(&sbi->s_freeclusters_counter, 1446 + e4b->bd_info->bb_free); 1449 1447 /* Mark the block group as corrupt. */ 1450 1448 set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, 1451 1449 &e4b->bd_info->bb_state);
+2 -1
fs/mbcache.c
··· 73 73 #include <linux/mbcache.h> 74 74 #include <linux/init.h> 75 75 #include <linux/blockgroup_lock.h> 76 + #include <linux/log2.h> 76 77 77 78 #ifdef MB_CACHE_DEBUG 78 79 # define mb_debug(f...) do { \ ··· 94 93 95 94 #define MB_CACHE_WRITER ((unsigned short)~0U >> 1) 96 95 97 - #define MB_CACHE_ENTRY_LOCK_BITS __builtin_log2(NR_BG_LOCKS) 96 + #define MB_CACHE_ENTRY_LOCK_BITS ilog2(NR_BG_LOCKS) 98 97 #define MB_CACHE_ENTRY_LOCK_INDEX(ce) \ 99 98 (hash_long((unsigned long)ce, MB_CACHE_ENTRY_LOCK_BITS)) 100 99