[RFC PATCH 1/5] erofs-utils: mkfs: add manifest source mode plumbing

adigitX adityakammati.workspace at gmail.com
Sun Mar 22 02:28:28 AEDT 2026


---
 mkfs/main.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 64 insertions(+), 5 deletions(-)

diff --git a/mkfs/main.c b/mkfs/main.c
index 58c18f9..9641f2f 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -60,6 +60,7 @@ static struct option long_options[] = {
 	{"gid-offset", required_argument, NULL, 17},
 	{"tar", optional_argument, NULL, 20},
 	{"aufs", no_argument, NULL, 21},
+	{"manifest", optional_argument, NULL, 22},
 	{"mount-point", required_argument, NULL, 512},
 #ifdef WITH_ANDROID
 	{"product-out", required_argument, NULL, 513},
@@ -209,6 +210,8 @@ static void usage(int argc, char **argv)
 		" --gid-offset=#         add offset # to all file gids (# = id offset)\n"
 		" --hard-dereference     dereference hardlinks, add links as separate inodes\n"
 		" --ignore-mtime         use build time instead of strict per-file modification time\n"
+		" --manifest[=X]         generate an image from a manifest source\n"
+		"                        (X = auto|composefs|proto; default: auto)\n"
 		" --max-extent-bytes=#   set maximum decompressed extent size # in bytes\n"
 		" --mount-point=X        X=prefix of target fs path (default: /)\n"
 		" --preserve-mtime       keep per-file modification time strictly\n"
@@ -316,12 +319,19 @@ enum {
 
 static enum {
 	EROFS_MKFS_SOURCE_LOCALDIR,
+	EROFS_MKFS_SOURCE_MANIFEST,
 	EROFS_MKFS_SOURCE_TAR,
 	EROFS_MKFS_SOURCE_S3,
 	EROFS_MKFS_SOURCE_OCI,
 	EROFS_MKFS_SOURCE_REBUILD,
 } source_mode;
 
+static enum {
+	EROFS_MKFS_MANIFEST_AUTO,
+	EROFS_MKFS_MANIFEST_COMPOSEFS,
+	EROFS_MKFS_MANIFEST_PROTO,
+} manifest_format;
+
 static unsigned int rebuild_src_count;
 static LIST_HEAD(rebuild_src_list);
 static u8 fixeduuid[16];
@@ -331,6 +341,33 @@ static int tarerofs_decoder;
 static FILE *vmdk_dcf;
 static char *mkfs_aws_zinfo_file;
 
+static int mkfs_parse_manifest_cfg(const char *arg)
+{
+	if (source_mode != EROFS_MKFS_SOURCE_LOCALDIR) {
+		erofs_err("--manifest cannot be used together with another source mode");
+		return -EINVAL;
+	}
+
+	source_mode = EROFS_MKFS_SOURCE_MANIFEST;
+	manifest_format = EROFS_MKFS_MANIFEST_AUTO;
+
+	if (!arg || !*arg)
+		return 0;
+	if (!strcmp(arg, "auto"))
+		return 0;
+	if (!strcmp(arg, "composefs")) {
+		manifest_format = EROFS_MKFS_MANIFEST_COMPOSEFS;
+		return 0;
+	}
+	if (!strcmp(arg, "proto")) {
+		manifest_format = EROFS_MKFS_MANIFEST_PROTO;
+		return 0;
+	}
+
+	erofs_err("invalid manifest format %s", arg);
+	return -EINVAL;
+}
+
 static int erofs_mkfs_feat_set_legacy_compress(struct erofs_importer_params *params,
 					       bool en, const char *val,
 					       unsigned int vallen)
@@ -612,20 +649,24 @@ static int mkfs_apply_zfeature_bits(struct erofs_importer_params *params,
 	return 0;
 }
 
-static void mkfs_parse_tar_cfg(char *cfg)
+static void mkfs_parse_tar_cfg(char *arg)
 {
 	char *p;
 
+	if (source_mode != EROFS_MKFS_SOURCE_LOCALDIR) {
+		erofs_err("--tar cannot be used together with another source mode");
+		return;
+	}
 	source_mode = EROFS_MKFS_SOURCE_TAR;
-	if (!cfg)
+	if (!arg)
 		return;
-	p = strchr(cfg, ',');
+	p = strchr(arg, ',');
 	if (p) {
 		*p = '\0';
 		if ((*++p) != '\0')
 			erofstar.mapfile = strdup(p);
 	}
-	if (!strcmp(cfg, "headerball"))
+	if (!strcmp(arg, "headerball"))
 		erofstar.headeronly_mode = true;
 
 	if (erofstar.headeronly_mode || !strcmp(optarg, "i") ||
@@ -1047,6 +1088,11 @@ static int mkfs_parse_sources(int argc, char *argv[], int optind)
 			source_mode = EROFS_MKFS_SOURCE_REBUILD;
 		}
 		break;
+	case EROFS_MKFS_SOURCE_MANIFEST:
+		cfg.c_src_path = strdup(argv[optind++]);
+		if (!cfg.c_src_path)
+			return -ENOMEM;
+		break;
 	case EROFS_MKFS_SOURCE_TAR:
 		cfg.c_src_path = strdup(argv[optind++]);
 		if (!cfg.c_src_path)
@@ -1363,6 +1409,11 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 		case 21:
 			erofstar.aufs = true;
 			break;
+		case 22:
+			err = mkfs_parse_manifest_cfg(optarg);
+			if (err)
+				return err;
+			break;
 		case 516:
 			params->ovlfs_strip = !optarg || !strcmp(optarg, "1");
 			break;
@@ -1585,9 +1636,14 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 		err = mkfs_parse_sources(argc, argv, optind);
 		if (err)
 			return err;
-	} else if (source_mode != EROFS_MKFS_SOURCE_TAR) {
+	} else if (source_mode != EROFS_MKFS_SOURCE_TAR &&
+		   source_mode != EROFS_MKFS_SOURCE_MANIFEST) {
 		erofs_err("missing argument: SOURCE(s)");
 		return -EINVAL;
+	} else if (source_mode == EROFS_MKFS_SOURCE_MANIFEST) {
+		cfg.c_src_path = strdup("-");
+		if (!cfg.c_src_path)
+			return -ENOMEM;
 	} else {
 		int dupfd;
 
@@ -2032,6 +2088,9 @@ int main(int argc, char **argv)
 	if (source_mode == EROFS_MKFS_SOURCE_TAR) {
 		while (!(err = tarerofs_parse_tar(&importer, &erofstar)))
 			;
+	} else if (source_mode == EROFS_MKFS_SOURCE_MANIFEST) {
+		erofs_err("manifest input support is not implemented yet");
+		err = -EOPNOTSUPP;
 	} else if (source_mode == EROFS_MKFS_SOURCE_REBUILD) {
 		err = erofs_mkfs_rebuild_load_trees(root);
 #ifdef S3EROFS_ENABLED
-- 
2.51.0



More information about the Linux-erofs mailing list