aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGao Xiang <hsiangkao@linux.alibaba.com>2024-05-17 17:00:48 +0800
committerGao Xiang <hsiangkao@linux.alibaba.com>2024-05-17 17:20:22 +0800
commitce8d7ebbbd0275afd9c7597c87de4ca6a76213b3 (patch)
tree5d13be40e0f005dc58c0e5d58d63dbf856cae51e
parented2f7cf8b7483962518e517c3f2401aaead999ad (diff)
downloaderofs-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.c160
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);