It's also used to prepare for extra compression option support.

Signed-off-by: Gao Xiang <[email protected]>
---
 include/erofs/config.h   |   7 ---
 include/erofs/importer.h |   1 +
 include/erofs/internal.h |   6 ++
 lib/compress.c           |  53 +++++++++--------
 lib/compress_hints.c     |   2 +-
 lib/compressor.c         |  29 ++++------
 lib/compressor.h         |   2 +-
 lib/config.c             |   4 --
 lib/inode.c              |   4 +-
 lib/remotes/s3.c         |   2 +-
 lib/tar.c                |   2 +-
 mkfs/main.c              | 120 +++++++++++++++++++--------------------
 12 files changed, 113 insertions(+), 119 deletions(-)

diff --git a/include/erofs/config.h b/include/erofs/config.h
index 2a84fb515868..3758cc7c198e 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -29,12 +29,6 @@ enum {
 
 #define EROFS_MAX_COMPR_CFGS           64
 
-struct erofs_compr_opts {
-       char *alg;
-       int level;
-       u32 dict_size;
-};
-
 struct erofs_configure {
        const char *c_version;
        int c_dbg_lvl;
@@ -54,7 +48,6 @@ struct erofs_configure {
        char *c_src_path;
        char *c_blobdev_path;
        char *c_compress_hints_file;
-       struct erofs_compr_opts c_compr_opts[EROFS_MAX_COMPR_CFGS];
        char c_force_chunkformat;
        u8 c_mkfs_metabox_algid;
        u32 c_max_decompressed_extent_bytes;
diff --git a/include/erofs/importer.h b/include/erofs/importer.h
index adeea7230447..a7a540d4d182 100644
--- a/include/erofs/importer.h
+++ b/include/erofs/importer.h
@@ -30,6 +30,7 @@ enum {
 };
 
 struct erofs_importer_params {
+       struct z_erofs_paramset *z_paramsets;
        char *source;
        u32 mt_async_queue_limit;
        u32 fixed_uid;
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 3f1e4ffa2b52..3ccae0c7ac86 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -434,6 +434,12 @@ struct erofs_map_dev {
        unsigned int m_deviceid;
 };
 
+struct z_erofs_paramset {
+       char *alg;
+       int clevel;
+       u32 dict_size;
+};
+
 int liberofs_global_init(void);
 void liberofs_global_exit(void);
 
diff --git a/lib/compress.c b/lib/compress.c
index 222e380cdcd7..1c4aa115641d 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -100,11 +100,7 @@ struct erofs_compress_work {
        struct z_erofs_compress_sctx ctx;
        pthread_cond_t cond;
        struct erofs_compress_work *next;
-
-       unsigned int alg_id;
-       char *alg_name;
-       unsigned int comp_level;
-       unsigned int dict_size;
+       struct z_erofs_paramset *zset;
 
        int errcode;
 };
@@ -126,7 +122,8 @@ struct z_erofs_compress_fslot {
 /* compressing configuration specified by users */
 struct erofs_compress_cfg {
        struct erofs_compress handle;
-       unsigned int algorithmtype;
+       struct z_erofs_paramset zset;
+       int algorithmtype;
        bool enable;
 };
 
@@ -1479,19 +1476,22 @@ void z_erofs_mt_workfn(struct erofs_work *work, void 
*tlsp)
        struct z_erofs_compress_ictx *ictx = sctx->ictx;
        struct erofs_inode *inode = ictx->inode;
        struct erofs_sb_info *sbi = inode->sbi;
-       struct erofs_compress_cfg *lc = &tls->ccfg[cwork->alg_id];
+       int zsetno = container_of(cwork->zset, struct erofs_compress_cfg, zset)
+                       - sbi->zmgr->ccfg;
+       struct erofs_compress_cfg *lc = &tls->ccfg[zsetno];
        int ret;
 
        if (__erofs_unlikely(!lc->enable)) {
                unsigned int pclustersize_max =
                        ictx->im->params->pclusterblks_max << sbi->blkszbits;
 
-               ret = erofs_compressor_init(sbi, &lc->handle,
-                                           cwork->alg_name, cwork->comp_level,
-                                           cwork->dict_size, pclustersize_max);
+               lc->zset = *cwork->zset;
+               ret = erofs_compressor_init(sbi, &lc->handle, &lc->zset,
+                                           pclustersize_max);
                if (ret)
                        goto out;
-               lc->algorithmtype = cwork->alg_id;
+               lc->algorithmtype =
+                       z_erofs_get_compress_algorithm_id(&lc->handle);
                lc->enable = true;
        }
 
@@ -1499,7 +1499,7 @@ void z_erofs_mt_workfn(struct erofs_work *work, void 
*tlsp)
        DBG_BUGON(sctx->pclustersize > Z_EROFS_PCLUSTER_MAX_SIZE);
        sctx->queue = tls->queue;
        sctx->destbuf = tls->destbuf;
-       sctx->chandle = &tls->ccfg[cwork->alg_id].handle;
+       sctx->chandle = &lc->handle;
        erofs_compressor_reset(sctx->chandle);
        sctx->membuf = malloc(round_up(sctx->remaining, erofs_blksiz(sbi)));
        if (!sctx->membuf) {
@@ -1639,10 +1639,7 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx 
*ictx)
                };
                init_list_head(&cur->ctx.extents);
 
-               cur->alg_id = ccfg->handle.alg->id;
-               cur->alg_name = ccfg->handle.alg->name;
-               cur->comp_level = ccfg->handle.compression_level;
-               cur->dict_size = ccfg->handle.dict_size;
+               cur->zset = &ccfg->zset;
                cur->errcode = 1;       /* mark as "in progress" */
 
                if (i >= nsegs - 1) {
@@ -2154,13 +2151,20 @@ int z_erofs_compress_init(struct erofs_importer *im)
                newzmgr = true;
        }
 
-       for (i = 0; cfg.c_compr_opts[i].alg; ++i) {
+       for (i = 0; params->z_paramsets[i].alg; ++i) {
                struct erofs_compress_cfg *ccfg = &sbi->zmgr->ccfg[i];
                struct erofs_compress *c = &ccfg->handle;
+               const struct z_erofs_paramset *zset = &params->z_paramsets[i];
+
+               if (ccfg->enable)
+                       return -EINVAL;
 
-               ret = erofs_compressor_init(sbi, c, cfg.c_compr_opts[i].alg,
-                                           cfg.c_compr_opts[i].level,
-                                           cfg.c_compr_opts[i].dict_size,
+               ccfg->zset = *zset;
+               ccfg->zset.alg = strdup(zset->alg);
+               if (!ccfg->zset.alg)
+                       return -ENOMEM;
+
+               ret = erofs_compressor_init(sbi, c, &ccfg->zset,
                                            pclustersize_max);
                if (ret)
                        return ret;
@@ -2168,8 +2172,8 @@ int z_erofs_compress_init(struct erofs_importer *im)
                id = z_erofs_get_compress_algorithm_id(c);
                ccfg->algorithmtype = id;
                ccfg->enable = true;
-               available_compr_algs |= 1 << ccfg->algorithmtype;
-               if (ccfg->algorithmtype != Z_EROFS_COMPRESSION_LZ4)
+               available_compr_algs |= 1 << id;
+               if (id != Z_EROFS_COMPRESSION_LZ4)
                        erofs_sb_set_compr_cfgs(sbi);
                if (c->dict_size > max_dict_size[id])
                        max_dict_size[id] = c->dict_size;
@@ -2253,10 +2257,13 @@ int z_erofs_compress_exit(struct erofs_sb_info *sbi)
        if (!sbi->zmgr)
                return 0;
 
-       for (i = 0; cfg.c_compr_opts[i].alg; ++i) {
+       for (i = 0; i < ARRAY_SIZE(sbi->zmgr->ccfg); ++i) {
+               if (!sbi->zmgr->ccfg[i].enable)
+                       continue;
                ret = erofs_compressor_exit(&sbi->zmgr->ccfg[i].handle);
                if (ret)
                        return ret;
+               free(sbi->zmgr->ccfg[i].zset.alg);
        }
        free(sbi->zmgr);
        return 0;
diff --git a/lib/compress_hints.c b/lib/compress_hints.c
index 15f3e54c2ce4..322ec97f474a 100644
--- a/lib/compress_hints.c
+++ b/lib/compress_hints.c
@@ -129,7 +129,7 @@ int erofs_load_compress_hints(struct erofs_importer *im,
                } else {
                        ccfg = atoi(alg);
                        if (ccfg >= EROFS_MAX_COMPR_CFGS ||
-                           !cfg.c_compr_opts[ccfg].alg) {
+                           !params->z_paramsets[ccfg].alg) {
                                erofs_err("invalid compressing configuration 
\"%s\" at line %u",
                                          alg, line);
                                ret = -EINVAL;
diff --git a/lib/compressor.c b/lib/compressor.c
index efcead1b1f29..79d80372968e 100644
--- a/lib/compressor.c
+++ b/lib/compressor.c
@@ -97,8 +97,8 @@ int erofs_compress(const struct erofs_compress *c,
 }
 
 int erofs_compressor_init(struct erofs_sb_info *sbi, struct erofs_compress *c,
-                         char *alg_name, int compression_level,
-                         u32 dict_size, u32 pclustersize_max)
+                         const struct z_erofs_paramset *zset,
+                         u32 pclustersize_max)
 {
        int ret, i;
 
@@ -109,43 +109,38 @@ int erofs_compressor_init(struct erofs_sb_info *sbi, 
struct erofs_compress *c,
        c->compression_level = -1;
        c->dict_size = 0;
 
-       if (!alg_name) {
-               c->alg = NULL;
-               return 0;
-       }
-
        ret = -EINVAL;
        for (i = 0; i < ARRAY_SIZE(erofs_algs); ++i) {
-               if (alg_name && strcmp(alg_name, erofs_algs[i].name))
+               if (strcmp(zset->alg, erofs_algs[i].name))
                        continue;
 
                if (!erofs_algs[i].c)
                        continue;
 
                if (erofs_algs[i].c->setlevel) {
-                       ret = erofs_algs[i].c->setlevel(c, compression_level);
+                       ret = erofs_algs[i].c->setlevel(c, zset->clevel);
                        if (ret) {
                                erofs_err("failed to set compression level %d 
for %s",
-                                         compression_level, alg_name);
+                                         zset->clevel, zset->alg);
                                return ret;
                        }
-               } else if (compression_level >= 0) {
+               } else if (zset->clevel >= 0) {
                        erofs_err("compression level %d is not supported for 
%s",
-                                 compression_level, alg_name);
+                                 zset->clevel, zset->alg);
                        return -EINVAL;
                }
 
                if (erofs_algs[i].c->setdictsize) {
-                       ret = erofs_algs[i].c->setdictsize(c, dict_size,
+                       ret = erofs_algs[i].c->setdictsize(c, zset->dict_size,
                                                           pclustersize_max);
                        if (ret) {
                                erofs_err("failed to set dict size %u for %s",
-                                         dict_size, alg_name);
+                                         zset->dict_size, zset->alg);
                                return ret;
                        }
-               } else if (dict_size) {
+               } else if (zset->dict_size) {
                        erofs_err("dict size is not supported for %s",
-                                 alg_name);
+                                 zset->alg);
                        return -EINVAL;
                }
 
@@ -158,7 +153,7 @@ int erofs_compressor_init(struct erofs_sb_info *sbi, struct 
erofs_compress *c,
                        return 0;
                }
        }
-       erofs_err("Cannot find a valid compressor %s", alg_name);
+       erofs_err("Cannot find a valid compressor %s", zset->alg);
        return ret;
 }
 
diff --git a/lib/compressor.h b/lib/compressor.h
index c008206a489d..c679466759d3 100644
--- a/lib/compressor.h
+++ b/lib/compressor.h
@@ -69,7 +69,7 @@ int erofs_compress(const struct erofs_compress *c,
                   void *dst, unsigned int dstcapacity);
 
 int erofs_compressor_init(struct erofs_sb_info *sbi, struct erofs_compress *c,
-                         char *alg_name, int compression_level, u32 dict_size,
+                         const struct z_erofs_paramset *zset,
                          u32 pclustersize_max);
 int erofs_compressor_exit(struct erofs_compress *c);
 void erofs_compressor_reset(struct erofs_compress *c);
diff --git a/lib/config.c b/lib/config.c
index 5eb0ddeaa851..3398ded56ac1 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -46,8 +46,6 @@ void erofs_show_config(void)
 
 void erofs_exit_configure(void)
 {
-       int i;
-
 #ifdef HAVE_LIBSELINUX
        if (cfg.sehnd)
                selabel_close(cfg.sehnd);
@@ -56,8 +54,6 @@ void erofs_exit_configure(void)
                free(cfg.c_img_path);
        if (cfg.c_src_path)
                free(cfg.c_src_path);
-       for (i = 0; i < EROFS_MAX_COMPR_CFGS && cfg.c_compr_opts[i].alg; i++)
-               free(cfg.c_compr_opts[i].alg);
 }
 
 struct erofs_configure *erofs_get_configure()
diff --git a/lib/inode.c b/lib/inode.c
index 79e5d3bae573..4a214f91cbb2 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -2023,7 +2023,7 @@ static int erofs_mkfs_begin_nondirectory(const struct 
erofs_mkfs_btctx *btctx,
                                return ret;
                }
 
-               if (cfg.c_compr_opts[0].alg &&
+               if (inode->sbi->available_compr_algs &&
                    erofs_file_is_compressible(im, inode)) {
                        ctx.ictx = erofs_prepare_compressed_file(im, inode);
                        if (IS_ERR(ctx.ictx))
@@ -2352,7 +2352,7 @@ struct erofs_inode 
*erofs_mkfs_build_special_from_fd(struct erofs_importer *im,
                return ERR_PTR(ret);
        }
 
-       if (cfg.c_compr_opts[0].alg &&
+       if (sbi->available_compr_algs &&
            erofs_file_is_compressible(im, inode)) {
                ictx = erofs_prepare_compressed_file(im, inode);
                if (IS_ERR(ictx))
diff --git a/lib/remotes/s3.c b/lib/remotes/s3.c
index 73db4b786c41..5e4e9d39ab24 100644
--- a/lib/remotes/s3.c
+++ b/lib/remotes/s3.c
@@ -1028,7 +1028,7 @@ static int s3erofs_remote_getobject(struct erofs_importer 
*im,
                return -EIO;
 
        resp.pos = 0;
-       if (!cfg.c_compr_opts[0].alg && im->params->no_datainline) {
+       if (!sbi->available_compr_algs && im->params->no_datainline) {
                inode->datalayout = EROFS_INODE_FLAT_PLAIN;
                inode->idata_size = 0;
                ret = erofs_allocate_inode_bh_data(inode,
diff --git a/lib/tar.c b/lib/tar.c
index 1f3092566bd9..178f843c905c 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -1105,7 +1105,7 @@ new_inode:
                                                                 inode->i_size))
                                        ret = -EIO;
                        } else if (tar->try_no_reorder &&
-                                  !cfg.c_compr_opts[0].alg &&
+                                  !sbi->available_compr_algs &&
                                   params->no_datainline) {
                                ret = tarerofs_write_uncompressed_file(inode, 
tar);
                        } else {
diff --git a/mkfs/main.c b/mkfs/main.c
index a948b2e1febd..326c332d37af 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -273,10 +273,12 @@ static void version(void)
 }
 
 static struct erofsmkfs_cfg {
+       struct z_erofs_paramset zcfgs[EROFS_MAX_COMPR_CFGS + 1];
        /* < 0, xattr disabled and >= INT_MAX, always use inline xattrs */
        long inlinexattr_tolerance;
        bool inode_metazone;
        u64 unix_timestamp;
+       unsigned int total_zcfgs;
 } mkfscfg = {
        .inlinexattr_tolerance = 2,
        .unix_timestamp = -1,
@@ -314,7 +316,7 @@ static enum {
        EROFS_MKFS_SOURCE_REBUILD,
 } source_mode;
 
-static unsigned int rebuild_src_count, total_ccfgs;
+static unsigned int rebuild_src_count;
 static LIST_HEAD(rebuild_src_list);
 static u8 fixeduuid[16];
 static bool valid_fixeduuid;
@@ -837,66 +839,66 @@ static int mkfs_parse_oci_options(struct ocierofs_config 
*oci_cfg, char *options
 }
 #endif
 
-static int mkfs_parse_one_compress_alg(char *alg,
-                                      struct erofs_compr_opts *copts)
+struct z_erofs_paramset erofs_mkfs_zparams[EROFS_MAX_COMPR_CFGS + 1];
+unsigned int erofs_mkfs_total_ccfgs;
+
+static int mkfs_parse_one_compress_alg(char *alg)
 {
+       struct z_erofs_paramset *zset = mkfscfg.zcfgs + mkfscfg.total_zcfgs;
        char *p, *q, *opt, *endptr;
 
-       copts->level = -1;
-       copts->dict_size = 0;
+       if (zset >= erofs_mkfs_zparams + ARRAY_SIZE(erofs_mkfs_zparams)) {
+               erofs_err("too many algorithm types");
+               return -EINVAL;
+       }
+       zset->clevel = -1;
+       zset->dict_size = 0;
 
        p = strchr(alg, ',');
-       if (p) {
-               copts->alg = strndup(alg, p - alg);
-
-               /* support old '-zlzma,9' form */
-               if (isdigit(*(p + 1))) {
-                       copts->level = strtol(p + 1, &endptr, 10);
-                       if (*endptr && *endptr != ',') {
-                               erofs_err("invalid compression level %s",
-                                         p + 1);
-                               return -EINVAL;
-                       }
-                       return 0;
-               }
+       if (!p) {
+               zset->alg = alg;
        } else {
-               copts->alg = strdup(alg);
-               return 0;
-       }
-
-       opt = p + 1;
-       while (opt) {
-               q = strchr(opt, ',');
-               if (q)
-                       *q = '\0';
-
-               if ((p = strstr(opt, "level="))) {
-                       p += strlen("level=");
-                       copts->level = strtol(p, &endptr, 10);
-                       if ((endptr == p) || (*endptr && *endptr != ',')) {
+               *p++ = '\0';
+               zset->alg = alg;
+               if (isdigit(*p)) {      /* support old '-zlzma,9' form */
+                       zset->clevel = strtol(p, &endptr, 10);
+                       if (*endptr && *endptr != ',') {
                                erofs_err("invalid compression level %s", p);
                                return -EINVAL;
                        }
-               } else if ((p = strstr(opt, "dictsize="))) {
-                       p += strlen("dictsize=");
-                       copts->dict_size = strtoul(p, &endptr, 10);
-                       if (*endptr == 'k' || *endptr == 'K')
-                               copts->dict_size <<= 10;
-                       else if (*endptr == 'm' || *endptr == 'M')
-                               copts->dict_size <<= 20;
-                       else if ((endptr == p) || (*endptr && *endptr != ',')) {
-                               erofs_err("invalid compression dictsize %s", p);
-                               return -EINVAL;
-                       }
                } else {
-                       erofs_err("invalid compression option %s", opt);
-                       return -EINVAL;
+                       for (opt = p; opt;) {
+                               q = strchr(opt, ',');
+                               if (q)
+                                       *q = '\0';
+
+                               if ((p = strstr(opt, "level="))) {
+                                       p += strlen("level=");
+                                       zset->clevel = strtol(p, &endptr, 10);
+                                       if ((endptr == p) || (*endptr && 
*endptr != ',')) {
+                                               erofs_err("invalid compression 
level %s", p);
+                                               return -EINVAL;
+                                       }
+                               } else if ((p = strstr(opt, "dictsize="))) {
+                                       p += strlen("dictsize=");
+                                       zset->dict_size = strtoul(p, &endptr, 
10);
+                                       if (*endptr == 'k' || *endptr == 'K')
+                                               zset->dict_size <<= 10;
+                                       else if (*endptr == 'm' || *endptr == 
'M')
+                                               zset->dict_size <<= 20;
+                                       else if ((endptr == p) || (*endptr && 
*endptr != ',')) {
+                                               erofs_err("invalid compression 
dictsize %s", p);
+                                               return -EINVAL;
+                                       }
+                               } else {
+                                       erofs_err("invalid compression option 
%s", opt);
+                                       return -EINVAL;
+                               }
+                               opt = q ? q + 1 : NULL;
+                       }
                }
-
-               opt = q ? q + 1 : NULL;
        }
-
-       return 0;
+       return mkfscfg.total_zcfgs++;
 }
 
 static int mkfs_parse_compress_algs(char *algs)
@@ -905,15 +907,9 @@ static int mkfs_parse_compress_algs(char *algs)
        int ret;
 
        for (s = strtok(algs, ":"); s; s = strtok(NULL, ":")) {
-               if (total_ccfgs >= EROFS_MAX_COMPR_CFGS - 1) {
-                       erofs_err("too many algorithm types");
-                       return -EINVAL;
-               }
-
-               ret = mkfs_parse_one_compress_alg(s, 
&cfg.c_compr_opts[total_ccfgs]);
-               if (ret)
+               ret = mkfs_parse_one_compress_alg(s);
+               if (ret < 0)
                        return ret;
-               ++total_ccfgs;
        }
        return 0;
 }
@@ -1210,11 +1206,10 @@ static int mkfs_parse_options_cfg(struct 
erofs_importer_params *params,
                                metabox_algorithmid =
                                        strtoul(algid + 1, &endptr, 0);
                                if (*endptr != '\0') {
-                                       err = mkfs_parse_one_compress_alg(algid 
+ 1,
-                                                       
&cfg.c_compr_opts[total_ccfgs]);
-                                       if (err)
+                                       err = mkfs_parse_one_compress_alg(algid 
+ 1);
+                                       if (err < 0)
                                                return err;
-                                       metabox_algorithmid = total_ccfgs++;
+                                       metabox_algorithmid = err;
                                }
                        }
                        pclustersize_metabox = atoi(optarg);
@@ -1856,6 +1851,7 @@ int main(int argc, char **argv)
 
        if (mkfscfg.inlinexattr_tolerance < 0)
                importer_params.no_xattrs = true;
+       importer_params.z_paramsets = mkfscfg.zcfgs;
        importer_params.source = cfg.c_src_path;
        importer_params.no_datainline = mkfs_no_datainline;
        importer_params.dot_omitted = mkfs_dot_omitted;
@@ -1864,7 +1860,7 @@ int main(int argc, char **argv)
                goto exit;
 
        if (importer_params.dedupe == EROFS_DEDUPE_FORCE_ON) {
-               if (!cfg.c_compr_opts[0].alg) {
+               if (!g_sbi.available_compr_algs) {
                        erofs_err("Compression is not enabled.  Turn on 
chunk-based data deduplication instead.");
                        cfg.c_chunkbits = g_sbi.blkszbits;
                } else {
-- 
2.43.5


Reply via email to