Skip to content

Commit 0076493

Browse files
azattytso
authored andcommitted
ext4: initialize multi-block allocator before checking block descriptors
With EXT4FS_DEBUG ext4_count_free_clusters() will call ext4_read_block_bitmap() without s_group_info initialized, so we need to initialize multi-block allocator before. And dependencies that must be solved, to allow this: - multi-block allocator needs in group descriptors - need to install s_op before initializing multi-block allocator, because in ext4_mb_init_backend() new inode is created. - initialize number of group desc blocks (s_gdb_count) otherwise number of clusters returned by ext4_free_clusters_after_init() is not correct. (see ext4_bg_num_gdb_nometa()) Here is the stack backtrace: (gdb) bt #0 ext4_get_group_info (group=0, sb=0xffff880079a10000) at ext4.h:2430 #1 ext4_validate_block_bitmap (sb=sb@entry=0xffff880079a10000, desc=desc@entry=0xffff880056510000, block_group=block_group@entry=0, bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:358 CyanogenMod#2 0xffffffff81232202 in ext4_wait_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0, bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:476 CyanogenMod#3 0xffffffff81232eaf in ext4_read_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0) at balloc.c:489 CyanogenMod#4 0xffffffff81232fc0 in ext4_count_free_clusters (sb=sb@entry=0xffff880079a10000) at balloc.c:665 CyanogenMod#5 0xffffffff81259ffa in ext4_check_descriptors (first_not_zeroed=<synthetic pointer>, sb=0xffff880079a10000) at super.c:2143 coolya#6 ext4_fill_super (sb=sb@entry=0xffff880079a10000, data=<optimized out>, data@entry=0x0 <irq_stack_union>, silent=silent@entry=0) at super.c:3851 ... Signed-off-by: Azat Khuzhin <a3at.mail@gmail.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
1 parent 4adb6ab commit 0076493

1 file changed

Lines changed: 27 additions & 24 deletions

File tree

fs/ext4/super.c

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3869,19 +3869,38 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
38693869
goto failed_mount2;
38703870
}
38713871
}
3872+
3873+
/*
3874+
* set up enough so that it can read an inode,
3875+
* and create new inode for buddy allocator
3876+
*/
3877+
sbi->s_gdb_count = db_count;
3878+
if (!test_opt(sb, NOLOAD) &&
3879+
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3880+
sb->s_op = &ext4_sops;
3881+
else
3882+
sb->s_op = &ext4_nojournal_sops;
3883+
3884+
ext4_ext_init(sb);
3885+
err = ext4_mb_init(sb);
3886+
if (err) {
3887+
ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
3888+
err);
3889+
goto failed_mount2;
3890+
}
3891+
38723892
if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
38733893
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
3874-
goto failed_mount2;
3894+
goto failed_mount2a;
38753895
}
38763896
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
38773897
if (!ext4_fill_flex_info(sb)) {
38783898
ext4_msg(sb, KERN_ERR,
38793899
"unable to initialize "
38803900
"flex_bg meta info!");
3881-
goto failed_mount2;
3901+
goto failed_mount2a;
38823902
}
38833903

3884-
sbi->s_gdb_count = db_count;
38853904
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
38863905
spin_lock_init(&sbi->s_next_gen_lock);
38873906

@@ -3916,14 +3935,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
39163935
sbi->s_stripe = ext4_get_stripe_size(sbi);
39173936
sbi->s_extent_max_zeroout_kb = 32;
39183937

3919-
/*
3920-
* set up enough so that it can read an inode
3921-
*/
3922-
if (!test_opt(sb, NOLOAD) &&
3923-
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3924-
sb->s_op = &ext4_sops;
3925-
else
3926-
sb->s_op = &ext4_nojournal_sops;
39273938
sb->s_export_op = &ext4_export_ops;
39283939
sb->s_xattr = ext4_xattr_handlers;
39293940
#ifdef CONFIG_QUOTA
@@ -4113,21 +4124,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
41134124
if (err) {
41144125
ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
41154126
"reserved pool", ext4_calculate_resv_clusters(sb));
4116-
goto failed_mount4a;
4127+
goto failed_mount5;
41174128
}
41184129

41194130
err = ext4_setup_system_zone(sb);
41204131
if (err) {
41214132
ext4_msg(sb, KERN_ERR, "failed to initialize system "
41224133
"zone (%d)", err);
4123-
goto failed_mount4a;
4124-
}
4125-
4126-
ext4_ext_init(sb);
4127-
err = ext4_mb_init(sb);
4128-
if (err) {
4129-
ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
4130-
err);
41314134
goto failed_mount5;
41324135
}
41334136

@@ -4204,11 +4207,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42044207
failed_mount7:
42054208
ext4_unregister_li_request(sb);
42064209
failed_mount6:
4207-
ext4_mb_release(sb);
4208-
failed_mount5:
4209-
ext4_ext_release(sb);
42104210
ext4_release_system_zone(sb);
4211-
failed_mount4a:
4211+
failed_mount5:
42124212
dput(sb->s_root);
42134213
sb->s_root = NULL;
42144214
failed_mount4:
@@ -4232,11 +4232,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42324232
percpu_counter_destroy(&sbi->s_extent_cache_cnt);
42334233
if (sbi->s_mmp_tsk)
42344234
kthread_stop(sbi->s_mmp_tsk);
4235+
failed_mount2a:
4236+
ext4_mb_release(sb);
42354237
failed_mount2:
42364238
for (i = 0; i < db_count; i++)
42374239
brelse(sbi->s_group_desc[i]);
42384240
ext4_kvfree(sbi->s_group_desc);
42394241
failed_mount:
4242+
ext4_ext_release(sb);
42404243
if (sbi->s_chksum_driver)
42414244
crypto_free_shash(sbi->s_chksum_driver);
42424245
if (sbi->s_proc) {

0 commit comments

Comments
 (0)