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

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 bug fixes from Ted Ts'o:
"The following are all bug fixes and regressions. The most notable are
the ones which cause problems for ext4 on RAID --- a performance
problem when mounting very large filesystems, and a kernel OOPS when
doing an rm -rf on large directory hierarchies on fast devices."

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: fix kernel BUG on large-scale rm -rf commands
ext4: fix long mount times on very big file systems
ext4: don't call ext4_error while block group is locked
ext4: avoid kmemcheck complaint from reading uninitialized memory
ext4: make sure the journal sb is written in ext4_clear_journal_err()

+47 -27
+37 -25
fs/ext4/balloc.c
··· 280 280 return desc; 281 281 } 282 282 283 - static int ext4_valid_block_bitmap(struct super_block *sb, 284 - struct ext4_group_desc *desc, 285 - unsigned int block_group, 286 - struct buffer_head *bh) 283 + /* 284 + * Return the block number which was discovered to be invalid, or 0 if 285 + * the block bitmap is valid. 286 + */ 287 + static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, 288 + struct ext4_group_desc *desc, 289 + unsigned int block_group, 290 + struct buffer_head *bh) 287 291 { 288 292 ext4_grpblk_t offset; 289 293 ext4_grpblk_t next_zero_bit; 290 - ext4_fsblk_t bitmap_blk; 294 + ext4_fsblk_t blk; 291 295 ext4_fsblk_t group_first_block; 292 296 293 297 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { ··· 301 297 * or it has to also read the block group where the bitmaps 302 298 * are located to verify they are set. 303 299 */ 304 - return 1; 300 + return 0; 305 301 } 306 302 group_first_block = ext4_group_first_block_no(sb, block_group); 307 303 308 304 /* check whether block bitmap block number is set */ 309 - bitmap_blk = ext4_block_bitmap(sb, desc); 310 - offset = bitmap_blk - group_first_block; 305 + blk = ext4_block_bitmap(sb, desc); 306 + offset = blk - group_first_block; 311 307 if (!ext4_test_bit(offset, bh->b_data)) 312 308 /* bad block bitmap */ 313 - goto err_out; 309 + return blk; 314 310 315 311 /* check whether the inode bitmap block number is set */ 316 - bitmap_blk = ext4_inode_bitmap(sb, desc); 317 - offset = bitmap_blk - group_first_block; 312 + blk = ext4_inode_bitmap(sb, desc); 313 + offset = blk - group_first_block; 318 314 if (!ext4_test_bit(offset, bh->b_data)) 319 315 /* bad block bitmap */ 320 - goto err_out; 316 + return blk; 321 317 322 318 /* check whether the inode table block number is set */ 323 - bitmap_blk = ext4_inode_table(sb, desc); 324 - offset = bitmap_blk - group_first_block; 319 + blk = ext4_inode_table(sb, desc); 320 + offset = blk - group_first_block; 325 321 next_zero_bit = ext4_find_next_zero_bit(bh->b_data, 326 322 offset + EXT4_SB(sb)->s_itb_per_group, 327 323 offset); 328 - if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group) 329 - /* good bitmap for inode tables */ 330 - return 1; 331 - 332 - err_out: 333 - ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu", 334 - block_group, bitmap_blk); 324 + if (next_zero_bit < offset + EXT4_SB(sb)->s_itb_per_group) 325 + /* bad bitmap for inode tables */ 326 + return blk; 335 327 return 0; 336 328 } 337 329 ··· 336 336 unsigned int block_group, 337 337 struct buffer_head *bh) 338 338 { 339 + ext4_fsblk_t blk; 340 + 339 341 if (buffer_verified(bh)) 340 342 return; 341 343 342 344 ext4_lock_group(sb, block_group); 343 - if (ext4_valid_block_bitmap(sb, desc, block_group, bh) && 344 - ext4_block_bitmap_csum_verify(sb, block_group, desc, bh, 345 - EXT4_BLOCKS_PER_GROUP(sb) / 8)) 346 - set_buffer_verified(bh); 345 + blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); 346 + if (unlikely(blk != 0)) { 347 + ext4_unlock_group(sb, block_group); 348 + ext4_error(sb, "bg %u: block %llu: invalid block bitmap", 349 + block_group, blk); 350 + return; 351 + } 352 + if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, 353 + desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) { 354 + ext4_unlock_group(sb, block_group); 355 + ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); 356 + return; 357 + } 358 + set_buffer_verified(bh); 347 359 ext4_unlock_group(sb, block_group); 348 360 } 349 361
-1
fs/ext4/bitmap.c
··· 79 79 if (provided == calculated) 80 80 return 1; 81 81 82 - ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group); 83 82 return 0; 84 83 } 85 84
+1
fs/ext4/extents.c
··· 2662 2662 } 2663 2663 path[0].p_depth = depth; 2664 2664 path[0].p_hdr = ext_inode_hdr(inode); 2665 + i = 0; 2665 2666 2666 2667 if (ext4_ext_check(inode, path[0].p_hdr, depth)) { 2667 2668 err = -EIO;
+6
fs/ext4/super.c
··· 948 948 ei->i_reserved_meta_blocks = 0; 949 949 ei->i_allocated_meta_blocks = 0; 950 950 ei->i_da_metadata_calc_len = 0; 951 + ei->i_da_metadata_calc_last_lblock = 0; 951 952 spin_lock_init(&(ei->i_block_reservation_lock)); 952 953 #ifdef CONFIG_QUOTA 953 954 ei->i_reserved_quota = 0; ··· 3109 3108 ext4_group_t i, ngroups = ext4_get_groups_count(sb); 3110 3109 int s, j, count = 0; 3111 3110 3111 + if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC)) 3112 + return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) + 3113 + sbi->s_itb_per_group + 2); 3114 + 3112 3115 first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + 3113 3116 (grp * EXT4_BLOCKS_PER_GROUP(sb)); 3114 3117 last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; ··· 4424 4419 ext4_commit_super(sb, 1); 4425 4420 4426 4421 jbd2_journal_clear_err(journal); 4422 + jbd2_journal_update_sb_errno(journal); 4427 4423 } 4428 4424 } 4429 4425
+2 -1
fs/jbd2/journal.c
··· 1377 1377 * Update a journal's errno. Write updated superblock to disk waiting for IO 1378 1378 * to complete. 1379 1379 */ 1380 - static void jbd2_journal_update_sb_errno(journal_t *journal) 1380 + void jbd2_journal_update_sb_errno(journal_t *journal) 1381 1381 { 1382 1382 journal_superblock_t *sb = journal->j_superblock; 1383 1383 ··· 1390 1390 1391 1391 jbd2_write_superblock(journal, WRITE_SYNC); 1392 1392 } 1393 + EXPORT_SYMBOL(jbd2_journal_update_sb_errno); 1393 1394 1394 1395 /* 1395 1396 * Read the superblock for a given journal, performing initial
+1
include/linux/jbd2.h
··· 1125 1125 extern int jbd2_journal_recover (journal_t *journal); 1126 1126 extern int jbd2_journal_wipe (journal_t *, int); 1127 1127 extern int jbd2_journal_skip_recovery (journal_t *); 1128 + extern void jbd2_journal_update_sb_errno(journal_t *); 1128 1129 extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t, 1129 1130 unsigned long, int); 1130 1131 extern void __jbd2_journal_abort_hard (journal_t *);