[PATCH v5 8/8] erofs-utils: mkfs: add --keep-whiteout option for tarfs and rebuild mode

Jingbo Xu jefflexu at linux.alibaba.com
Fri Sep 1 19:47:06 AEST 2023


Add "--keep-whiteout=[0|1]" option for tarfs and rebuild mode,
controlling whether whiteout files are kept in the generated image.

This option is enabled by default for both tarfs and rebuild mode, i.e.
as if "--keep-whiteout=1" is specified by default.

To hide whiteout files, specify "--keep-whiteout=0" explicitly.

Signed-off-by: Jingbo Xu <jefflexu at linux.alibaba.com>
---
 include/erofs/config.h   |  1 +
 include/erofs/internal.h |  2 ++
 lib/config.c             |  1 +
 lib/inode.c              | 17 +++++++++++++++--
 lib/tar.c                |  2 --
 mkfs/main.c              | 12 ++++++++++++
 6 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/include/erofs/config.h b/include/erofs/config.h
index c51f0cd..bea46a0 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -54,6 +54,7 @@ struct erofs_configure {
 	bool c_showprogress;
 	bool c_extra_ea_name_prefixes;
 	bool c_xattr_name_filter;
+	bool c_keep_whiteout;
 
 #ifdef HAVE_LIBSELINUX
 	struct selabel_handle *sehnd;
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index fcc0710..2fe7c44 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -427,6 +427,8 @@ static inline u32 erofs_crc32c(u32 crc, const u8 *in, size_t len)
 	return crc;
 }
 
+#define EROFS_WHITEOUT_DEV	0
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/config.c b/lib/config.c
index a3235c8..ae24a17 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -33,6 +33,7 @@ void erofs_init_configure(void)
 	cfg.c_pclusterblks_max = 1;
 	cfg.c_pclusterblks_def = 1;
 	cfg.c_max_decompressed_extent_bytes = -1;
+	cfg.c_keep_whiteout = true;
 }
 
 void erofs_show_config(void)
diff --git a/lib/inode.c b/lib/inode.c
index f71a6ab..5ba87ad 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1323,9 +1323,14 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(int fd, const char *name)
 	return inode;
 }
 
+static bool erofs_inode_is_whiteout(struct erofs_inode *inode)
+{
+	return S_ISCHR(inode->i_mode) && inode->u.i_rdev == EROFS_WHITEOUT_DEV;
+}
+
 int erofs_rebuild_dump_tree(struct erofs_inode *dir)
 {
-	struct erofs_dentry *d;
+	struct erofs_dentry *d, *n;
 	unsigned int nr_subdirs;
 	int ret;
 
@@ -1369,8 +1374,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_keep_whiteout && erofs_inode_is_whiteout(d->inode)) {
+			erofs_dbg("skip 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)
diff --git a/lib/tar.c b/lib/tar.c
index e0fe2a2..8cb392c 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -13,8 +13,6 @@
 #include "erofs/blobchunk.h"
 #include "erofs/rebuild.h"
 
-#define EROFS_WHITEOUT_DEV	0
-
 static char erofs_libbuf[16384];
 
 struct tar_header {
diff --git a/mkfs/main.c b/mkfs/main.c
index e296ea4..ba1406d 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -57,6 +57,7 @@ static struct option long_options[] = {
 	{"gid-offset", required_argument, NULL, 17},
 	{"tar", optional_argument, NULL, 20},
 	{"aufs", no_argument, NULL, 21},
+	{"keep-whiteout", required_argument, NULL, 22},
 	{"mount-point", required_argument, NULL, 512},
 	{"xattr-prefix", required_argument, NULL, 19},
 #ifdef WITH_ANDROID
@@ -121,6 +122,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"
+	      " --keep-whiteout=[01]  keep whiteout in tarfs or rebuild mode\n"
 	      " --quiet               quiet execution (do not write anything to standard output.)\n"
 #ifndef NDEBUG
 	      " --random-pclusterblks randomize pclusterblks for big pcluster (debugging only)\n"
@@ -538,6 +540,16 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
 		case 21:
 			erofstar.aufs = true;
 			break;
+		case 22:
+			if (!strcmp(optarg, "0"))
+				cfg.c_keep_whiteout = false;
+			else if (!strcmp(optarg, "1"))
+				cfg.c_keep_whiteout = true;
+			else {
+				erofs_err("invalid keep-whiteout %s", optarg);
+				return -EINVAL;
+			}
+			break;
 		case 1:
 			usage();
 			exit(0);
-- 
2.19.1.6.gb485710b



More information about the Linux-erofs mailing list