1 ext4: initialize multi-block allocator before checking block descriptors
3 From: Azat Khuzhin <a3at.mail@gmail.com>
5 With EXT4FS_DEBUG ext4_count_free_clusters() will call
6 ext4_read_block_bitmap() without s_group_info initialized, so we need to
7 initialize multi-block allocator before.
9 And we can't initialize multi-block allocator without group descriptors,
11 Also we need to install s_op before initializing multi-block allocator,
12 because in ext4_mb_init_backend() new inode is created.
16 #0 ext4_get_group_info (group=0, sb=0xffff880079a10000) at ext4.h:2430
17 #1 ext4_validate_block_bitmap (sb=sb@entry=0xffff880079a10000, desc=desc@entry=0xffff880056510000, block_group=block_group@entry=0,
18 bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:358
19 #2 0xffffffff81232202 in ext4_wait_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0,
20 bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:476
21 #3 0xffffffff81232eaf in ext4_read_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0) at balloc.c:489
22 #4 0xffffffff81232fc0 in ext4_count_free_clusters (sb=sb@entry=0xffff880079a10000) at balloc.c:665
23 #5 0xffffffff81259ffa in ext4_check_descriptors (first_not_zeroed=<synthetic pointer>, sb=0xffff880079a10000) at super.c:2143
24 #6 ext4_fill_super (sb=sb@entry=0xffff880079a10000, data=<optimized out>, data@entry=0x0 <irq_stack_union>, silent=silent@entry=0)
26 #7 0xffffffff811b8340 in mount_bdev (fs_type=<optimized out>, flags=0, dev_name=<optimized out>, data=0x0 <irq_stack_union>,
27 fill_super=fill_super@entry=0xffffffff812589c0 <ext4_fill_super>) at super.c:987
28 #8 0xffffffff8124ec35 in ext4_mount (fs_type=<optimized out>, flags=<optimized out>, dev_name=<optimized out>, data=<optimized out>)
30 #9 0xffffffff811b8cf9 in mount_fs (type=type@entry=0xffffffff81c71840 <ext4_fs_type>, flags=flags@entry=0,
31 name=name@entry=0xffff880077a80c70 "/dev/loop4", data=data@entry=0x0 <irq_stack_union>) at super.c:1090
32 #10 0xffffffff811d2ff3 in vfs_kern_mount (type=type@entry=0xffffffff81c71840 <ext4_fs_type>, flags=0,
33 name=name@entry=0xffff880077a80c70 "/dev/loop4", data=data@entry=0x0 <irq_stack_union>) at namespace.c:813
34 #11 0xffffffff811d55de in do_new_mount (data=0x0 <irq_stack_union>, name=0xffff880077a80c70 "/dev/loop4", mnt_flags=32,
35 flags=<optimized out>, fstype=0xffff880077a80ca0 "ext4-insane", path=0xffff88007a5b1ed0) at namespace.c:2068
36 #12 do_mount (dev_name=0xffff880077a80c70 "/dev/loop4", dir_name=<optimized out>, type_page=0xffff880077a80ca0 "ext4-insane",
37 flags=<optimized out>, flags@entry=3236757504, data_page=0x0 <irq_stack_union>) at namespace.c:2392
38 #13 0xffffffff811d6183 in SYSC_mount (data=0x0 <irq_stack_union>, flags=3236757504, type=<optimized out>, dir_name=<optimized out>,
39 dev_name=0x7ffad9649c20 "/dev/loop4") at namespace.c:2586
40 #14 SyS_mount (dev_name=140715365800992, dir_name=<optimized out>, type=<optimized out>, flags=3236757504, data=0) at namespace.c:2559
42 Signed-off-by: Azat Khuzhin <a3at.mail@gmail.com>
43 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
44 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
45 index 9a387b8..0491c81 100644
48 @@ -3848,16 +3848,34 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
54 + * set up enough so that it can read an inode
56 + if (!test_opt(sb, NOLOAD) &&
57 + EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
58 + sb->s_op = &ext4_sops;
60 + sb->s_op = &ext4_nojournal_sops;
63 + err = ext4_mb_init(sb);
65 + ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
70 if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
71 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
73 + goto failed_mount2a;
75 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
76 if (!ext4_fill_flex_info(sb)) {
77 ext4_msg(sb, KERN_ERR,
78 "unable to initialize "
79 "flex_bg meta info!");
81 + goto failed_mount2a;
84 sbi->s_gdb_count = db_count;
85 @@ -3895,14 +3913,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
86 sbi->s_stripe = ext4_get_stripe_size(sbi);
87 sbi->s_extent_max_zeroout_kb = 32;
90 - * set up enough so that it can read an inode
92 - if (!test_opt(sb, NOLOAD) &&
93 - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
94 - sb->s_op = &ext4_sops;
96 - sb->s_op = &ext4_nojournal_sops;
97 sb->s_export_op = &ext4_export_ops;
98 sb->s_xattr = ext4_xattr_handlers;
100 @@ -4084,21 +4094,13 @@ no_journal:
102 ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
103 "reserved pool", ext4_calculate_resv_clusters(sb));
104 - goto failed_mount4a;
105 + goto failed_mount5;
108 err = ext4_setup_system_zone(sb);
110 ext4_msg(sb, KERN_ERR, "failed to initialize system "
112 - goto failed_mount4a;
116 - err = ext4_mb_init(sb);
118 - ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
123 @@ -4175,11 +4177,8 @@ failed_mount8:
125 ext4_unregister_li_request(sb);
127 - ext4_mb_release(sb);
129 - ext4_ext_release(sb);
130 ext4_release_system_zone(sb);
136 @@ -4203,11 +4202,14 @@ failed_mount3:
137 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
139 kthread_stop(sbi->s_mmp_tsk);
141 + ext4_mb_release(sb);
143 for (i = 0; i < db_count; i++)
144 brelse(sbi->s_group_desc[i]);
145 ext4_kvfree(sbi->s_group_desc);
147 + ext4_ext_release(sb);
148 if (sbi->s_chksum_driver)
149 crypto_free_shash(sbi->s_chksum_driver);