ext4: trigger the lazy inode table initialization after resize
authorTheodore Ts'o <tytso@mit.edu>
Sun, 13 Jan 2013 13:41:45 +0000 (08:41 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 13 Jan 2013 13:41:45 +0000 (08:41 -0500)
After we have finished extending the file system, we need to trigger a
the lazy inode table thread to zero out the inode tables.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/ext4.h
fs/ext4/ioctl.c
fs/ext4/resize.c
fs/ext4/super.c

index 8462eb3c33aa22c62cccb88b030edfb599e2db66..80246237f6d53c16d131a7a4879e6b6526c01dce 100644 (file)
@@ -2227,6 +2227,8 @@ extern int ext4_group_desc_csum_verify(struct super_block *sb, __u32 group,
                                       struct ext4_group_desc *gdp);
 extern void ext4_group_desc_csum_set(struct super_block *sb, __u32 group,
                                     struct ext4_group_desc *gdp);
+extern int ext4_register_li_request(struct super_block *sb,
+                                   ext4_group_t first_not_zeroed);
 
 static inline int ext4_has_group_desc_csum(struct super_block *sb)
 {
index 5747f52f7c727d8de207de8263d07f2b5e4d9f89..4784ac244fc634fab55387b0caebac911991a704 100644 (file)
@@ -313,6 +313,9 @@ mext_out:
                if (err == 0)
                        err = err2;
                mnt_drop_write_file(filp);
+               if (!err && ext4_has_group_desc_csum(sb) &&
+                   test_opt(sb, INIT_INODE_TABLE))
+                       err = ext4_register_li_request(sb, input.group);
 group_add_out:
                ext4_resize_end(sb);
                return err;
@@ -358,6 +361,7 @@ group_add_out:
                ext4_fsblk_t n_blocks_count;
                struct super_block *sb = inode->i_sb;
                int err = 0, err2 = 0;
+               ext4_group_t o_group = EXT4_SB(sb)->s_groups_count;
 
                if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
                               EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
@@ -388,6 +392,11 @@ group_add_out:
                if (err == 0)
                        err = err2;
                mnt_drop_write_file(filp);
+               if (!err && (o_group > EXT4_SB(sb)->s_groups_count) &&
+                   ext4_has_group_desc_csum(sb) &&
+                   test_opt(sb, INIT_INODE_TABLE))
+                       err = ext4_register_li_request(sb, o_group);
+
 resizefs_out:
                ext4_resize_end(sb);
                return err;
index 05f8d4502d42d1a4c065e84e2150fb093f77644a..8eefb636beb828bdd1af9d2aa946ea702c00d522 100644 (file)
@@ -1506,10 +1506,12 @@ static int ext4_setup_next_flex_gd(struct super_block *sb,
                group_data[i].blocks_count = blocks_per_group;
                overhead = ext4_group_overhead_blocks(sb, group + i);
                group_data[i].free_blocks_count = blocks_per_group - overhead;
-               if (ext4_has_group_desc_csum(sb))
+               if (ext4_has_group_desc_csum(sb)) {
                        flex_gd->bg_flags[i] = EXT4_BG_BLOCK_UNINIT |
                                               EXT4_BG_INODE_UNINIT;
-               else
+                       if (!test_opt(sb, INIT_INODE_TABLE))
+                               flex_gd->bg_flags[i] |= EXT4_BG_INODE_ZEROED;
+               } else
                        flex_gd->bg_flags[i] = EXT4_BG_INODE_ZEROED;
        }
 
@@ -1594,7 +1596,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 
        err = ext4_alloc_flex_bg_array(sb, input->group + 1);
        if (err)
-               return err;
+               goto out;
 
        err = ext4_mb_alloc_groupinfo(sb, input->group + 1);
        if (err)
index 3d4fb81bacd540ca7b81fd4005f392aa7a516b53..c014edd12648b9c1573d10a27cce82434581251f 100644 (file)
@@ -2776,7 +2776,7 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
                        break;
        }
 
-       if (group == ngroups)
+       if (group >= ngroups)
                ret = 1;
 
        if (!ret) {
@@ -3016,33 +3016,34 @@ static struct ext4_li_request *ext4_li_request_new(struct super_block *sb,
        return elr;
 }
 
-static int ext4_register_li_request(struct super_block *sb,
-                                   ext4_group_t first_not_zeroed)
+int ext4_register_li_request(struct super_block *sb,
+                            ext4_group_t first_not_zeroed)
 {
        struct ext4_sb_info *sbi = EXT4_SB(sb);
-       struct ext4_li_request *elr;
+       struct ext4_li_request *elr = NULL;
        ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
        int ret = 0;
 
+       mutex_lock(&ext4_li_mtx);
        if (sbi->s_li_request != NULL) {
                /*
                 * Reset timeout so it can be computed again, because
                 * s_li_wait_mult might have changed.
                 */
                sbi->s_li_request->lr_timeout = 0;
-               return 0;
+               goto out;
        }
 
        if (first_not_zeroed == ngroups ||
            (sb->s_flags & MS_RDONLY) ||
            !test_opt(sb, INIT_INODE_TABLE))
-               return 0;
+               goto out;
 
        elr = ext4_li_request_new(sb, first_not_zeroed);
-       if (!elr)
-               return -ENOMEM;
-
-       mutex_lock(&ext4_li_mtx);
+       if (!elr) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        if (NULL == ext4_li_info) {
                ret = ext4_li_info_new();