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 dependencies that must be solved, to allow this:
10 - multi-block allocator needs in group descriptors
11 - need to install s_op before initializing multi-block allocator,
12 because in ext4_mb_init_backend() new inode is created.
13 - initialize number of group desc blocks (s_gdb_count) otherwise
14 number of clusters returned by ext4_free_clusters_after_init() is not correct.
15 (see ext4_bg_num_gdb_nometa())
17 Here is the stack backtrace:
20 #0 ext4_get_group_info (group=0, sb=0xffff880079a10000) at ext4.h:2430
21 #1 ext4_validate_block_bitmap (sb=sb@entry=0xffff880079a10000,
22 desc=desc@entry=0xffff880056510000, block_group=block_group@entry=0,
23 bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:358
24 #2 0xffffffff81232202 in ext4_wait_block_bitmap (sb=sb@entry=0xffff880079a10000,
25 block_group=block_group@entry=0,
26 bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:476
27 #3 0xffffffff81232eaf in ext4_read_block_bitmap (sb=sb@entry=0xffff880079a10000,
28 block_group=block_group@entry=0) at balloc.c:489
29 #4 0xffffffff81232fc0 in ext4_count_free_clusters (sb=sb@entry=0xffff880079a10000) at balloc.c:665
30 #5 0xffffffff81259ffa in ext4_check_descriptors (first_not_zeroed=<synthetic pointer>,
31 sb=0xffff880079a10000) at super.c:2143
32 #6 ext4_fill_super (sb=sb@entry=0xffff880079a10000, data=<optimized out>,
33 data@entry=0x0 <irq_stack_union>, silent=silent@entry=0) at super.c:3851
36 Signed-off-by: Azat Khuzhin <a3at.mail@gmail.com>
37 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
39 Link: http://marc.info/?l=linux-ext4&m=139493754530149&w=2
40 v5: initialize number of group desc blocks (s_gdb_count) otherwise
41 number of clusters returned by ext4_free_clusters_after_init() is not correct.
43 fs/ext4/super.c | 51 +++++++++++++++++++++++++++------------------------
44 1 file changed, 27 insertions(+), 24 deletions(-)
46 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
47 index f3c6670..6f9e6fa 100644
50 @@ -3869,19 +3869,38 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
56 + * set up enough so that it can read an inode,
57 + * and create new inode for buddy allocator
59 + sbi->s_gdb_count = db_count;
60 + if (!test_opt(sb, NOLOAD) &&
61 + EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
62 + sb->s_op = &ext4_sops;
64 + sb->s_op = &ext4_nojournal_sops;
67 + err = ext4_mb_init(sb);
69 + ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
74 if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
75 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
77 + goto failed_mount2a;
79 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
80 if (!ext4_fill_flex_info(sb)) {
81 ext4_msg(sb, KERN_ERR,
82 "unable to initialize "
83 "flex_bg meta info!");
85 + goto failed_mount2a;
88 - sbi->s_gdb_count = db_count;
89 get_random_bytes(&sbi->s_next_generation, sizeof(u32));
90 spin_lock_init(&sbi->s_next_gen_lock);
92 @@ -3916,14 +3935,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
93 sbi->s_stripe = ext4_get_stripe_size(sbi);
94 sbi->s_extent_max_zeroout_kb = 32;
97 - * set up enough so that it can read an inode
99 - if (!test_opt(sb, NOLOAD) &&
100 - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
101 - sb->s_op = &ext4_sops;
103 - sb->s_op = &ext4_nojournal_sops;
104 sb->s_export_op = &ext4_export_ops;
105 sb->s_xattr = ext4_xattr_handlers;
107 @@ -4113,21 +4124,13 @@ no_journal:
109 ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
110 "reserved pool", ext4_calculate_resv_clusters(sb));
111 - goto failed_mount4a;
112 + goto failed_mount5;
115 err = ext4_setup_system_zone(sb);
117 ext4_msg(sb, KERN_ERR, "failed to initialize system "
119 - goto failed_mount4a;
123 - err = ext4_mb_init(sb);
125 - ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
130 @@ -4204,11 +4207,8 @@ failed_mount8:
132 ext4_unregister_li_request(sb);
134 - ext4_mb_release(sb);
136 - ext4_ext_release(sb);
137 ext4_release_system_zone(sb);
143 @@ -4232,11 +4232,14 @@ failed_mount3:
144 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
146 kthread_stop(sbi->s_mmp_tsk);
148 + ext4_mb_release(sb);
150 for (i = 0; i < db_count; i++)
151 brelse(sbi->s_group_desc[i]);
152 ext4_kvfree(sbi->s_group_desc);
154 + ext4_ext_release(sb);
155 if (sbi->s_chksum_driver)
156 crypto_free_shash(sbi->s_chksum_driver);
162 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
163 the body of a message to majordomo@vger.kernel.org
164 More majordomo info at http://vger.kernel.org/majordomo-info.html