erofs-utils: mkfs: add `--ovlfs-strip` option
authorJingbo Xu <jefflexu@linux.alibaba.com>
Wed, 13 Sep 2023 12:03:03 +0000 (20:03 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Thu, 14 Sep 2023 09:45:11 +0000 (17:45 +0800)
Add `--ovlfs-strip=[0|1]` option for tarfs and rebuild mode for now
in order to control whether some overlayfs related stuffs (e.g.
whiteout files, OVL_XATTR_OPAQUE and OVL_XATTR_ORIGIN xattrs) are
finally stripped.

This option is disabled by default for mkfs, that is, the overlayfs
related stuffs described above are kept in the image by default.

Specify `--ovlfs-strip=1` explicitly to strip these stuffs.

Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20230913120304.15741-9-jefflexu@linux.alibaba.com
include/erofs/config.h
include/erofs/xattr.h
lib/inode.c
lib/xattr.c
mkfs/main.c

index 5d3bfba87843832121bcbf8fb52305c255a2b31f..e34272249e1c9aa6efb52c251585fcce61de5c08 100644 (file)
@@ -54,6 +54,7 @@ struct erofs_configure {
        bool c_showprogress;
        bool c_extra_ea_name_prefixes;
        bool c_xattr_name_filter;
+       bool c_ovlfs_strip;
 
 #ifdef HAVE_LIBSELINUX
        struct selabel_handle *sehnd;
index 0364f2409486464d8c580a43aaf908859bac526d..0f76037e7f8f3c35fab0cf59c933b2721d697ff3 100644 (file)
@@ -57,6 +57,7 @@ int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi);
 int erofs_setxattr(struct erofs_inode *inode, char *key,
                   const void *value, size_t size);
 int erofs_set_opaque_xattr(struct erofs_inode *inode);
+void erofs_clear_opaque_xattr(struct erofs_inode *inode);
 int erofs_set_origin_xattr(struct erofs_inode *inode);
 int erofs_read_xattrs_from_disk(struct erofs_inode *inode);
 
index 93e6b232e1fb8fe1f6178f83564639d4709ddb1c..37aa79e03bf98cdd4db31dee4d0be1fef6614c77 100644 (file)
@@ -1326,7 +1326,7 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(int fd, const char *name)
 
 int erofs_rebuild_dump_tree(struct erofs_inode *dir)
 {
-       struct erofs_dentry *d;
+       struct erofs_dentry *d, *n;
        unsigned int nr_subdirs;
        int ret;
 
@@ -1341,7 +1341,10 @@ int erofs_rebuild_dump_tree(struct erofs_inode *dir)
                dir->inode_isize = sizeof(struct erofs_inode_compact);
        }
 
-       if (dir->whiteouts)
+       /* strip all unnecessary overlayfs xattrs when ovlfs_strip is enabled */
+       if (cfg.c_ovlfs_strip)
+               erofs_clear_opaque_xattr(dir);
+       else if (dir->whiteouts)
                erofs_set_origin_xattr(dir);
 
        ret = erofs_prepare_xattr_ibody(dir);
@@ -1373,8 +1376,16 @@ int erofs_rebuild_dump_tree(struct erofs_inode *dir)
        }
 
        nr_subdirs = 0;
-       list_for_each_entry(d, &dir->i_subdirs, d_child)
+       list_for_each_entry_safe(d, n, &dir->i_subdirs, d_child) {
+               if (cfg.c_ovlfs_strip && erofs_inode_is_whiteout(d->inode)) {
+                       erofs_dbg("remove whiteout %s", d->inode->i_srcpath);
+                       list_del(&d->d_child);
+                       erofs_d_invalidate(d);
+                       free(d);
+                       continue;
+               }
                ++nr_subdirs;
+       }
 
        ret = erofs_prepare_dir_layout(dir, nr_subdirs);
        if (ret)
index e3a1b44be3c6400dd715f4649836b4ade61ae301..790547c9ee9d2803d17977c137ca5fed4fcfbd8d 100644 (file)
@@ -499,11 +499,29 @@ int erofs_setxattr(struct erofs_inode *inode, char *key,
        return erofs_xattr_add(&inode->i_xattrs, item);
 }
 
+static void erofs_removexattr(struct erofs_inode *inode, const char *key)
+{
+       struct inode_xattr_node *node, *n;
+
+       list_for_each_entry_safe(node, n, &inode->i_xattrs, list) {
+               if (!strcmp(node->item->kvbuf, key)) {
+                       list_del(&node->list);
+                       put_xattritem(node->item);
+                       free(node);
+               }
+       }
+}
+
 int erofs_set_opaque_xattr(struct erofs_inode *inode)
 {
        return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
 }
 
+void erofs_clear_opaque_xattr(struct erofs_inode *inode)
+{
+       erofs_removexattr(inode, OVL_XATTR_OPAQUE);
+}
+
 int erofs_set_origin_xattr(struct erofs_inode *inode)
 {
        return erofs_setxattr(inode, OVL_XATTR_ORIGIN, NULL, 0);
index 2f0022ad8a3c3da5c26665de45fe2386677b649c..4fa2d92a8454dae95fa48452c15f30e4e438ad9c 100644 (file)
@@ -64,6 +64,7 @@ static struct option long_options[] = {
        {"fs-config-file", required_argument, NULL, 514},
        {"block-list-file", required_argument, NULL, 515},
 #endif
+       {"ovlfs-strip", optional_argument, NULL, 516},
        {0, 0, 0, 0},
 };
 
@@ -115,6 +116,7 @@ static void usage(void)
              " --preserve-mtime      keep per-file modification time strictly\n"
              " --aufs                replace aufs special files with overlayfs metadata\n"
              " --tar=[fi]            generate an image from tarball(s)\n"
+             " --ovlfs-strip=[01]    strip overlayfs metadata in the target image (e.g. whiteouts)\n"
              " --quiet               quiet execution (do not write anything to standard output.)\n"
 #ifndef NDEBUG
              " --random-pclusterblks randomize pclusterblks for big pcluster (debugging only)\n"
@@ -516,6 +518,12 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
                case 21:
                        erofstar.aufs = true;
                        break;
+               case 516:
+                       if (!optarg || !strcmp(optarg, "1"))
+                               cfg.c_ovlfs_strip = true;
+                       else
+                               cfg.c_ovlfs_strip = false;
+                       break;
                case 1:
                        usage();
                        exit(0);