Skip to content

Commit f9ae9cf

Browse files
committed
ext4: revert commit which was causing fs corruption after journal replays
Commit 0076493 ("ext4: initialize multi-block allocator before checking block descriptors") causes the block group descriptor's count of the number of free blocks to become inconsistent with the number of free blocks in the allocation bitmap. This is a harmless form of fs corruption, but it causes the kernel to potentially remount the file system read-only, or to panic, depending on the file systems's error behavior. Thanks to Eric Whitney for his tireless work to reproduce and to find the guilty commit. Fixes: 0076493 ("ext4: initialize multi-block allocator before checking block descriptors" Cc: [email protected] # 3.15 Reported-by: David Jander <[email protected]> Reported-by: Matteo Croce <[email protected]> Tested-by: Eric Whitney <[email protected]> Suggested-by: Eric Whitney <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 5dd2142 commit f9ae9cf

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed

fs/ext4/super.c

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3879,38 +3879,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
38793879
goto failed_mount2;
38803880
}
38813881
}
3882-
3883-
/*
3884-
* set up enough so that it can read an inode,
3885-
* and create new inode for buddy allocator
3886-
*/
3887-
sbi->s_gdb_count = db_count;
3888-
if (!test_opt(sb, NOLOAD) &&
3889-
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3890-
sb->s_op = &ext4_sops;
3891-
else
3892-
sb->s_op = &ext4_nojournal_sops;
3893-
3894-
ext4_ext_init(sb);
3895-
err = ext4_mb_init(sb);
3896-
if (err) {
3897-
ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
3898-
err);
3899-
goto failed_mount2;
3900-
}
3901-
39023882
if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
39033883
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
3904-
goto failed_mount2a;
3884+
goto failed_mount2;
39053885
}
39063886
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
39073887
if (!ext4_fill_flex_info(sb)) {
39083888
ext4_msg(sb, KERN_ERR,
39093889
"unable to initialize "
39103890
"flex_bg meta info!");
3911-
goto failed_mount2a;
3891+
goto failed_mount2;
39123892
}
39133893

3894+
sbi->s_gdb_count = db_count;
39143895
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
39153896
spin_lock_init(&sbi->s_next_gen_lock);
39163897

@@ -3945,6 +3926,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
39453926
sbi->s_stripe = ext4_get_stripe_size(sbi);
39463927
sbi->s_extent_max_zeroout_kb = 32;
39473928

3929+
/*
3930+
* set up enough so that it can read an inode
3931+
*/
3932+
if (!test_opt(sb, NOLOAD) &&
3933+
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3934+
sb->s_op = &ext4_sops;
3935+
else
3936+
sb->s_op = &ext4_nojournal_sops;
39483937
sb->s_export_op = &ext4_export_ops;
39493938
sb->s_xattr = ext4_xattr_handlers;
39503939
#ifdef CONFIG_QUOTA
@@ -4134,13 +4123,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
41344123
if (err) {
41354124
ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
41364125
"reserved pool", ext4_calculate_resv_clusters(sb));
4137-
goto failed_mount5;
4126+
goto failed_mount4a;
41384127
}
41394128

41404129
err = ext4_setup_system_zone(sb);
41414130
if (err) {
41424131
ext4_msg(sb, KERN_ERR, "failed to initialize system "
41434132
"zone (%d)", err);
4133+
goto failed_mount4a;
4134+
}
4135+
4136+
ext4_ext_init(sb);
4137+
err = ext4_mb_init(sb);
4138+
if (err) {
4139+
ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
4140+
err);
41444141
goto failed_mount5;
41454142
}
41464143

@@ -4217,8 +4214,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42174214
failed_mount7:
42184215
ext4_unregister_li_request(sb);
42194216
failed_mount6:
4220-
ext4_release_system_zone(sb);
4217+
ext4_mb_release(sb);
42214218
failed_mount5:
4219+
ext4_ext_release(sb);
4220+
ext4_release_system_zone(sb);
4221+
failed_mount4a:
42224222
dput(sb->s_root);
42234223
sb->s_root = NULL;
42244224
failed_mount4:
@@ -4242,14 +4242,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42424242
percpu_counter_destroy(&sbi->s_extent_cache_cnt);
42434243
if (sbi->s_mmp_tsk)
42444244
kthread_stop(sbi->s_mmp_tsk);
4245-
failed_mount2a:
4246-
ext4_mb_release(sb);
42474245
failed_mount2:
42484246
for (i = 0; i < db_count; i++)
42494247
brelse(sbi->s_group_desc[i]);
42504248
ext4_kvfree(sbi->s_group_desc);
42514249
failed_mount:
4252-
ext4_ext_release(sb);
42534250
if (sbi->s_chksum_driver)
42544251
crypto_free_shash(sbi->s_chksum_driver);
42554252
if (sbi->s_proc) {

0 commit comments

Comments
 (0)