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 <[email protected]> --- 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
