[PATCH 2/2] erofs-utils: mkfs: validate source and dataimport mode combinations
Yifan Zhao
zhaoyifan28 at huawei.com
Fri Feb 13 18:32:41 AEDT 2026
This patch adds validation for all combinations of source mode and
dataimport mode, and prints corresponding error/warning messages.
It should have no impact on external behavior.
Signed-off-by: Yifan Zhao <zhaoyifan28 at huawei.com>
---
mkfs/main.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 131 insertions(+), 13 deletions(-)
diff --git a/mkfs/main.c b/mkfs/main.c
index a948b2e..e369347 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -169,7 +169,7 @@ static void usage(int argc, char **argv)
}
printf(
" -C# specify the size of compress physical cluster in bytes\n"
- " -EX[,...] X=extended options\n"
+ " -EX[,...] X=extended options, see mkfs.erofs(1) manual for details\n"
" -L volume-label set the volume label (maximum 15 bytes)\n"
" -m#[:X] enable metadata compression (# = physical cluster size in bytes;\n"
" X = another compression algorithm for metadata)\n"
@@ -300,6 +300,10 @@ static struct ocierofs_config ocicfg;
static bool mkfs_oci_tarindex_mode;
enum {
+ /* XXX: the "DEFAULT" mode is actually source-dependent,
+ * meaning BLOB_INDEX for rebuild mode and FULLDATA for others.
+ * Consider refactoring this...
+ */
EROFS_MKFS_DATA_IMPORT_DEFAULT,
EROFS_MKFS_DATA_IMPORT_FULLDATA,
EROFS_MKFS_DATA_IMPORT_RVSP,
@@ -314,6 +318,118 @@ static enum {
EROFS_MKFS_SOURCE_REBUILD,
} source_mode;
+static int erofs_mkfs_validate_source_datamode(void)
+{
+ int status;
+ enum {
+ EROFS_MKFS_CLEAN_MODE = 0,
+ EROFS_MKFS_INCREMENTAL_MODE = 1
+ };
+ const char *SOURCE_NAME[] = {
+ [EROFS_MKFS_SOURCE_LOCALDIR] = "localdir source",
+ [EROFS_MKFS_SOURCE_TAR] = "tarball source",
+ [EROFS_MKFS_SOURCE_S3] = "S3-compatible object store source",
+ [EROFS_MKFS_SOURCE_OCI] = "OCI remote source",
+ [EROFS_MKFS_SOURCE_REBUILD] = "rebuilding from existing EROFS image(s)",
+ };
+ const char *DATAIMPORT_NAME[] = {
+ [EROFS_MKFS_DATA_IMPORT_DEFAULT] = "default", // placeholder
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = "data",
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = "rvsp",
+ [EROFS_MKFS_DATA_IMPORT_ZEROFILL] = "0",
+ };
+ enum {
+ INVALID = 0, // INVALID must be 0 for static initialization
+ NOP = 1,
+ SUPPORTED = 2,
+ };
+ static const int support[EROFS_MKFS_SOURCE_REBUILD + 1][EROFS_MKFS_INCREMENTAL_MODE + 1][EROFS_MKFS_DATA_IMPORT_ZEROFILL + 1] = {
+ [EROFS_MKFS_SOURCE_LOCALDIR] = {
+ [EROFS_MKFS_CLEAN_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = NOP,
+ [EROFS_MKFS_DATA_IMPORT_ZEROFILL] = NOP
+ },
+ [EROFS_MKFS_INCREMENTAL_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = NOP,
+ [EROFS_MKFS_DATA_IMPORT_ZEROFILL] = NOP
+ },
+ },
+ [EROFS_MKFS_SOURCE_TAR] = {
+ [EROFS_MKFS_CLEAN_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_ZEROFILL] = NOP
+ },
+ [EROFS_MKFS_INCREMENTAL_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_ZEROFILL] = NOP
+ },
+ },
+ [EROFS_MKFS_SOURCE_S3] = {
+ [EROFS_MKFS_CLEAN_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_ZEROFILL] = SUPPORTED,
+ },
+ },
+ [EROFS_MKFS_SOURCE_OCI] = {
+ [EROFS_MKFS_CLEAN_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED
+ },
+ },
+ [EROFS_MKFS_SOURCE_REBUILD] = {
+ [EROFS_MKFS_CLEAN_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_DEFAULT] = SUPPORTED,
+ /* XXX: FULLDATA rebuild mode doesn't work actually, let's keep
+ * its behavior until v1.9 is released to avoid breaking anyone who
+ * might rely on it...
+ */
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = SUPPORTED,
+ },
+ [EROFS_MKFS_INCREMENTAL_MODE] = {
+ [EROFS_MKFS_DATA_IMPORT_DEFAULT] = SUPPORTED,
+ /* XXX: FULLDATA rebuild mode doesn't work actually, let's keep
+ * its behavior until v1.9 is released to avoid breaking anyone who
+ * might rely on it...
+ */
+ [EROFS_MKFS_DATA_IMPORT_FULLDATA] = SUPPORTED,
+ [EROFS_MKFS_DATA_IMPORT_RVSP] = SUPPORTED,
+ },
+ },
+ };
+ int real_dataimport_mode = dataimport_mode;
+ if (real_dataimport_mode == EROFS_MKFS_DATA_IMPORT_DEFAULT)
+ real_dataimport_mode = (source_mode == EROFS_MKFS_SOURCE_REBUILD) ?
+ EROFS_MKFS_DATA_IMPORT_DEFAULT : EROFS_MKFS_DATA_IMPORT_FULLDATA;
+
+ if (source_mode < 0 || source_mode > EROFS_MKFS_SOURCE_REBUILD)
+ return -EINVAL;
+
+ if (real_dataimport_mode < EROFS_MKFS_DATA_IMPORT_DEFAULT ||
+ real_dataimport_mode > EROFS_MKFS_DATA_IMPORT_ZEROFILL)
+ return -EINVAL;
+
+ status = support[source_mode][incremental_mode ? EROFS_MKFS_INCREMENTAL_MODE : EROFS_MKFS_CLEAN_MODE][real_dataimport_mode];
+ if (status == SUPPORTED) {
+ return 0;
+ } else if (status == NOP) {
+ erofs_warn("datamode '%s' under %s mode is a no-op for %s.",
+ DATAIMPORT_NAME[real_dataimport_mode],
+ incremental_mode ? "incremental" : "clean",
+ SOURCE_NAME[source_mode]);
+ return 0;
+ } else {
+ erofs_err("datamode '%s' under %s mode is not supported for %s.",
+ DATAIMPORT_NAME[real_dataimport_mode],
+ incremental_mode ? "incremental" : "clean",
+ SOURCE_NAME[source_mode]);
+ return -EOPNOTSUPP;
+ }
+}
+
static unsigned int rebuild_src_count, total_ccfgs;
static LIST_HEAD(rebuild_src_list);
static u8 fixeduuid[16];
@@ -1570,6 +1686,10 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
if (has_timestamp && cfg.c_timeinherit == TIMESTAMP_UNSPECIFIED)
cfg.c_timeinherit = TIMESTAMP_FIXED;
+
+ err = erofs_mkfs_validate_source_datamode();
+ if (err)
+ return err;
return 0;
}
@@ -1631,11 +1751,16 @@ static int erofs_mkfs_rebuild_load_trees(struct erofs_inode *root)
datamode = EROFS_REBUILD_DATA_BLOB_INDEX;
break;
case EROFS_MKFS_DATA_IMPORT_FULLDATA:
+ /* XXX: fulldata rebuild is unsupported, but let's keep this behavior
+ * in case anyone relies on it until v1.9 is released...
+ */
datamode = EROFS_REBUILD_DATA_FULL;
break;
case EROFS_MKFS_DATA_IMPORT_RVSP:
datamode = EROFS_REBUILD_DATA_RESVSP;
break;
+ case EROFS_MKFS_DATA_IMPORT_ZEROFILL:
+ return -EOPNOTSUPP;
default:
return -EINVAL;
}
@@ -1786,6 +1911,8 @@ int main(int argc, char **argv)
if (source_mode == EROFS_MKFS_SOURCE_TAR) {
if (dataimport_mode == EROFS_MKFS_DATA_IMPORT_RVSP)
erofstar.rvsp_mode = true;
+ if (erofstar.index_mode && erofstar.rvsp_mode)
+ erofs_warn("rvsp mode takes precedence and tar index mode is ignored");
erofstar.dev = rebuild_src_count + 1;
if (erofstar.mapfile) {
@@ -1950,12 +2077,8 @@ int main(int argc, char **argv)
s3cfg.secret_key[S3_SECRET_KEY_LEN] = '\0';
}
- if (incremental_mode ||
- dataimport_mode == EROFS_MKFS_DATA_IMPORT_RVSP)
- err = -EOPNOTSUPP;
- else
- err = s3erofs_build_trees(&importer, &s3cfg,
- cfg.c_src_path,
+ err = s3erofs_build_trees(&importer, &s3cfg,
+ cfg.c_src_path,
dataimport_mode == EROFS_MKFS_DATA_IMPORT_ZEROFILL);
#endif
#ifdef OCIEROFS_ENABLED
@@ -1966,12 +2089,7 @@ int main(int argc, char **argv)
if (!ocicfg.zinfo_path)
ocicfg.zinfo_path = mkfs_aws_zinfo_file;
- if (incremental_mode ||
- dataimport_mode == EROFS_MKFS_DATA_IMPORT_RVSP ||
- dataimport_mode == EROFS_MKFS_DATA_IMPORT_ZEROFILL)
- err = -EOPNOTSUPP;
- else
- err = ocierofs_build_trees(&importer, &ocicfg);
+ err = ocierofs_build_trees(&importer, &ocicfg);
if (err)
goto exit;
#endif
--
2.47.3
More information about the Linux-erofs
mailing list