diff options
author | Gao Xiang <hsiangkao@linux.alibaba.com> | 2024-05-17 17:00:48 +0800 |
---|---|---|
committer | Gao Xiang <hsiangkao@linux.alibaba.com> | 2024-05-17 17:20:22 +0800 |
commit | ce8d7ebbbd0275afd9c7597c87de4ca6a76213b3 (patch) | |
tree | 5d13be40e0f005dc58c0e5d58d63dbf856cae51e | |
parent | ed2f7cf8b7483962518e517c3f2401aaead999ad (diff) | |
download | erofs-utils-upstream-dev.tar.gz |
erofs-utils: mkfs: add `--zfeature-bits` optionupstream-dev
Thus, we could traverse all compression features with continuous
numbers easily in the testcases.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20240517090048.3039594-1-hsiangkao@linux.alibaba.com
-rw-r--r-- | mkfs/main.c | 160 |
1 files changed, 124 insertions, 36 deletions
diff --git a/mkfs/main.c b/mkfs/main.c index c26cb56..12321ed 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -81,6 +81,7 @@ static struct option long_options[] = { #ifdef EROFS_MT_ENABLED {"workers", required_argument, NULL, 520}, #endif + {"zfeature-bits", required_argument, NULL, 521}, {0, 0, 0, 0}, }; @@ -166,6 +167,7 @@ static void usage(int argc, char **argv) " --gid-offset=# add offset # to all file gids (# = id offset)\n" " --ignore-mtime use build time instead of strict per-file modification time\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" " --offset=# skip # bytes at the beginning of IMAGE.\n" " --aufs replace aufs special files with overlayfs metadata\n" @@ -190,7 +192,7 @@ static void usage(int argc, char **argv) " --workers=# set the number of worker threads to # (default: %u)\n" #endif " --xattr-prefix=X X=extra xattr name prefix\n" - " --mount-point=X X=prefix of target fs path (default: /)\n" + " --zfeature-bits toggle filesystem compression features according to given bits\n" #ifdef WITH_ANDROID "\n" "Android-specific options:\n" @@ -220,10 +222,81 @@ static bool tar_mode, rebuild_mode; static unsigned int rebuild_src_count; static LIST_HEAD(rebuild_src_list); +static int erofs_mkfs_feat_set_legacy_compress(bool en, const char *val, + unsigned int vallen) +{ + if (vallen) + return -EINVAL; + /* disable compacted indexes and 0padding */ + cfg.c_legacy_compress = en; + return 0; +} + +static int erofs_mkfs_feat_set_ztailpacking(bool en, const char *val, + unsigned int vallen) +{ + if (vallen) + return -EINVAL; + cfg.c_ztailpacking = en; + return 0; +} + +static int erofs_mkfs_feat_set_fragments(bool en, const char *val, + unsigned int vallen) +{ + if (!en) { + if (vallen) + return -EINVAL; + cfg.c_fragments = false; + return 0; + } + + if (vallen) { + char *endptr; + u64 i = strtoull(val, &endptr, 0); + + if (endptr - val != vallen) { + erofs_err("invalid pcluster size %s for the packed file %s", val); + return -EINVAL; + } + pclustersize_packed = i; + } + cfg.c_fragments = true; + return 0; +} + +static int erofs_mkfs_feat_set_all_fragments(bool en, const char *val, + unsigned int vallen) +{ + cfg.c_all_fragments = en; + return erofs_mkfs_feat_set_fragments(en, val, vallen); +} + +static int erofs_mkfs_feat_set_dedupe(bool en, const char *val, + unsigned int vallen) +{ + if (vallen) + return -EINVAL; + cfg.c_dedupe = en; + return 0; +} + +static struct { + char *feat; + int (*set)(bool en, const char *val, unsigned int len); +} z_erofs_mkfs_features[] = { + {"legacy-compress", erofs_mkfs_feat_set_legacy_compress}, + {"ztailpacking", erofs_mkfs_feat_set_ztailpacking}, + {"fragments", erofs_mkfs_feat_set_fragments}, + {"all-fragments", erofs_mkfs_feat_set_all_fragments}, + {"dedupe", erofs_mkfs_feat_set_dedupe}, + {NULL, NULL}, +}; + static int parse_extended_opts(const char *opts) { #define MATCH_EXTENTED_OPT(opt, token, keylen) \ - (keylen == sizeof(opt) - 1 && !memcmp(token, opt, sizeof(opt) - 1)) + (keylen == strlen(opt) && !memcmp(token, opt, keylen)) const char *token, *next, *tokenend, *value __maybe_unused; unsigned int keylen, vallen; @@ -262,12 +335,7 @@ static int parse_extended_opts(const char *opts) clear = true; } - if (MATCH_EXTENTED_OPT("legacy-compress", token, keylen)) { - if (vallen) - return -EINVAL; - /* disable compacted indexes and 0padding */ - cfg.c_legacy_compress = true; - } else if (MATCH_EXTENTED_OPT("force-inode-compact", token, keylen)) { + if (MATCH_EXTENTED_OPT("force-inode-compact", token, keylen)) { if (vallen) return -EINVAL; cfg.c_force_inodeversion = FORCE_INODE_COMPACT; @@ -296,41 +364,51 @@ static int parse_extended_opts(const char *opts) if (vallen) return -EINVAL; cfg.c_force_chunkformat = FORCE_INODE_CHUNK_INDEXES; - } else if (MATCH_EXTENTED_OPT("ztailpacking", token, keylen)) { - if (vallen) - return -EINVAL; - cfg.c_ztailpacking = !clear; - } else if (MATCH_EXTENTED_OPT("all-fragments", token, keylen)) { - cfg.c_all_fragments = true; - goto handle_fragment; - } else if (MATCH_EXTENTED_OPT("fragments", token, keylen)) { - char *endptr; - u64 i; - -handle_fragment: - cfg.c_fragments = true; - if (vallen) { - i = strtoull(value, &endptr, 0); - if (endptr - value != vallen) { - erofs_err("invalid pcluster size for the packed file %s", - next); - return -EINVAL; - } - pclustersize_packed = i; - } - } else if (MATCH_EXTENTED_OPT("dedupe", token, keylen)) { - if (vallen) - return -EINVAL; - cfg.c_dedupe = !clear; } else if (MATCH_EXTENTED_OPT("xattr-name-filter", token, keylen)) { if (vallen) return -EINVAL; cfg.c_xattr_name_filter = !clear; } else { - erofs_err("unknown extended option %.*s", - p - token, token); + int i, err; + + for (i = 0; z_erofs_mkfs_features[i].feat; ++i) { + if (!MATCH_EXTENTED_OPT(z_erofs_mkfs_features[i].feat, + token, keylen)) + continue; + err = z_erofs_mkfs_features[i].set(!clear, value, vallen); + if (err) + return err; + break; + } + + if (!z_erofs_mkfs_features[i].feat) { + erofs_err("unknown extended option %.*s", + p - token, token); + return -EINVAL; + } + } + } + return 0; +} + +static int mkfs_apply_zfeature_bits(uintmax_t bits) +{ + int i; + + for (i = 0; bits; ++i) { + int err; + + if (!z_erofs_mkfs_features[i].feat) { + erofs_err("unsupported zfeature bit %u", i); return -EINVAL; } + err = z_erofs_mkfs_features[i].set(bits & 1, NULL, 0); + if (err) { + erofs_err("failed to apply zfeature %s", + z_erofs_mkfs_features[i].feat); + return err; + } + bits >>= 1; } return 0; } @@ -690,6 +768,16 @@ static int mkfs_parse_options_cfg(int argc, char *argv[]) break; } #endif + case 521: + i = strtol(optarg, &endptr, 0); + if (errno || *endptr != '\0') { + erofs_err("invalid zfeature bits %s", optarg); + return -EINVAL; + } + err = mkfs_apply_zfeature_bits(i); + if (err) + return err; + break; case 'V': version(); exit(0); |