add patch fix-zeroing-of-page-during-writeback
[ext4-patch-queue.git] / initialize-multi-block-allocator-before-checking-block-descriptors
blob2653cb3228b42bfc99284bdd30afda08c36e0303
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:
19 (gdb) bt
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
34      ...
36 Signed-off-by: Azat Khuzhin <a3at.mail@gmail.com>
37 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
38 ---
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
48 --- a/fs/ext4/super.c
49 +++ b/fs/ext4/super.c
50 @@ -3869,19 +3869,38 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
51                         goto failed_mount2;
52                 }
53         }
55 +       /*
56 +        * set up enough so that it can read an inode,
57 +        * and create new inode for buddy allocator
58 +        */
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;
63 +       else
64 +               sb->s_op = &ext4_nojournal_sops;
66 +       ext4_ext_init(sb);
67 +       err = ext4_mb_init(sb);
68 +       if (err) {
69 +               ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
70 +                        err);
71 +               goto failed_mount2;
72 +       }
74         if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
75                 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
76 -               goto failed_mount2;
77 +               goto failed_mount2a;
78         }
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!");
84 -                       goto failed_mount2;
85 +                       goto failed_mount2a;
86                 }
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;
96 -       /*
97 -        * set up enough so that it can read an inode
98 -        */
99 -       if (!test_opt(sb, NOLOAD) &&
100 -           EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
101 -               sb->s_op = &ext4_sops;
102 -       else
103 -               sb->s_op = &ext4_nojournal_sops;
104         sb->s_export_op = &ext4_export_ops;
105         sb->s_xattr = ext4_xattr_handlers;
106  #ifdef CONFIG_QUOTA
107 @@ -4113,21 +4124,13 @@ no_journal:
108         if (err) {
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;
113         }
115         err = ext4_setup_system_zone(sb);
116         if (err) {
117                 ext4_msg(sb, KERN_ERR, "failed to initialize system "
118                          "zone (%d)", err);
119 -               goto failed_mount4a;
120 -       }
122 -       ext4_ext_init(sb);
123 -       err = ext4_mb_init(sb);
124 -       if (err) {
125 -               ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
126 -                        err);
127                 goto failed_mount5;
128         }
130 @@ -4204,11 +4207,8 @@ failed_mount8:
131  failed_mount7:
132         ext4_unregister_li_request(sb);
133  failed_mount6:
134 -       ext4_mb_release(sb);
135 -failed_mount5:
136 -       ext4_ext_release(sb);
137         ext4_release_system_zone(sb);
138 -failed_mount4a:
139 +failed_mount5:
140         dput(sb->s_root);
141         sb->s_root = NULL;
142  failed_mount4:
143 @@ -4232,11 +4232,14 @@ failed_mount3:
144         percpu_counter_destroy(&sbi->s_extent_cache_cnt);
145         if (sbi->s_mmp_tsk)
146                 kthread_stop(sbi->s_mmp_tsk);
147 +failed_mount2a:
148 +       ext4_mb_release(sb);
149  failed_mount2:
150         for (i = 0; i < db_count; i++)
151                 brelse(sbi->s_group_desc[i]);
152         ext4_kvfree(sbi->s_group_desc);
153  failed_mount:
154 +       ext4_ext_release(sb);
155         if (sbi->s_chksum_driver)
156                 crypto_free_shash(sbi->s_chksum_driver);
157         if (sbi->s_proc) {
158 -- 
159 1.9.1
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