Whamcloud - gitweb
mke2fs: Add support for orphan_file feature
authorJan Kara <jack@suse.cz>
Wed, 25 Aug 2021 22:11:31 +0000 (00:11 +0200)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 1 Oct 2021 01:59:09 +0000 (21:59 -0400)
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
misc/mke2fs.8.in
misc/mke2fs.c

index c0b5324..b378e4d 100644 (file)
@@ -403,6 +403,11 @@ file system to change based on the user running \fBmke2fs\fR.
 Set a flag in the file system superblock indicating that it may be
 mounted using experimental kernel code, such as the ext4dev file system.
 .TP
+.BI orphan_file_size= size
+Set size of the file for tracking unlinked but still open inodes and inodes
+with truncate in progress. Larger file allows for better scalability, reserving
+a few blocks per cpu is ideal.
+.TP
 .B discard
 Attempt to discard blocks at mkfs time (discarding blocks initially is useful
 on solid state devices and sparse / thin-provisioned storage). When the device
index 04b2fbc..c955b31 100644 (file)
@@ -94,6 +94,7 @@ static gid_t  root_gid;
 int    journal_size;
 int    journal_flags;
 int    journal_fc_size;
+static e2_blkcnt_t     orphan_file_blocks;
 static int     lazy_itable_init;
 static int     packed_meta_blocks;
 int            no_copy_xattrs;
@@ -1089,6 +1090,21 @@ static void parse_extended_opts(struct ext2_super_block *param,
                                continue;
                        }
                        encoding_flags = arg;
+               } else if (!strcmp(token, "orphan_file_size")) {
+                       if (!arg) {
+                               r_usage++;
+                               badopt = token;
+                               continue;
+                       }
+                       orphan_file_blocks = parse_num_blocks2(arg,
+                                               fs_param.s_log_block_size);
+                       if (orphan_file_blocks == 0) {
+                               fprintf(stderr,
+                                       _("Invalid size of orphan file %s\n"),
+                                       arg);
+                               r_usage++;
+                               continue;
+                       }
                } else {
                        r_usage++;
                        badopt = token;
@@ -1156,7 +1172,8 @@ static __u32 ok_features[3] = {
                EXT2_FEATURE_COMPAT_EXT_ATTR |
                EXT4_FEATURE_COMPAT_SPARSE_SUPER2 |
                EXT4_FEATURE_COMPAT_FAST_COMMIT |
-               EXT4_FEATURE_COMPAT_STABLE_INODES,
+               EXT4_FEATURE_COMPAT_STABLE_INODES |
+               EXT4_FEATURE_COMPAT_ORPHAN_FILE,
        /* Incompat */
        EXT2_FEATURE_INCOMPAT_FILETYPE|
                EXT3_FEATURE_INCOMPAT_EXTENTS|
@@ -1551,6 +1568,7 @@ static void PRS(int argc, char *argv[])
        int             lsector_size = 0, psector_size = 0;
        int             show_version_only = 0, is_device = 0;
        unsigned long long num_inodes = 0; /* unsigned long long to catch too-large input */
+       int             default_orphan_file = 0;
        errcode_t       retval;
        char *          oldpath = getenv("PATH");
        char *          extended_opts = 0;
@@ -2101,8 +2119,20 @@ profile_error:
                ext2fs_clear_feature_ea_inode(&fs_param);
                ext2fs_clear_feature_casefold(&fs_param);
        }
-       edit_feature(fs_features ? fs_features : tmp,
-                    &fs_param.s_feature_compat);
+       if (!fs_features && tmp)
+               edit_feature(tmp, &fs_param.s_feature_compat);
+       /*
+        * Now all the defaults are incorporated in fs_param. Check the state
+        * of orphan_file feature so that we know whether we should silently
+        * disabled in case journal gets disabled.
+        */
+       if (ext2fs_has_feature_orphan_file(&fs_param))
+               default_orphan_file = 1;
+       if (fs_features)
+               edit_feature(fs_features, &fs_param.s_feature_compat);
+       /* Silently disable orphan_file if user chose fs without journal */
+       if (default_orphan_file && !ext2fs_has_feature_journal(&fs_param))
+               ext2fs_clear_feature_orphan_file(&fs_param);
        if (tmp)
                free(tmp);
        (void) ext2fs_free_mem(&fs_features);
@@ -3471,6 +3501,23 @@ no_journal:
                fix_cluster_bg_counts(fs);
        if (ext2fs_has_feature_quota(&fs_param))
                create_quota_inodes(fs);
+       if (ext2fs_has_feature_orphan_file(&fs_param)) {
+               if (!ext2fs_has_feature_journal(&fs_param)) {
+                       com_err(program_name, 0, _("cannot set orphan_file "
+                               "feature without a journal."));
+                       exit(1);
+               }
+               if (!orphan_file_blocks) {
+                       orphan_file_blocks =
+                               ext2fs_default_orphan_file_blocks(fs);
+               }
+               retval = ext2fs_create_orphan_file(fs, orphan_file_blocks);
+               if (retval) {
+                       com_err(program_name, retval,
+                               _("while creating orphan file"));
+                       exit(1);
+               }
+       }
 
        retval = mk_hugefiles(fs, device_name);
        if (retval)