since the compressor is independent in erofs-utils, rework the
compessor code using destructor and constructor, to make adding
a new algothrim easier.

Signed-off-by: Guo Xuenan <guoxue...@huawei.com>
---
 include/erofs/compress.h |   1 -
 lib/compress.c           |  81 +++++++++++------------------
 lib/compressor.c         | 109 +++++++++++++++++++++++----------------
 lib/compressor.h         |   9 +---
 lib/compressor_liblzma.c |   3 +-
 lib/compressor_lz4.c     |   3 +-
 lib/compressor_lz4hc.c   |   4 +-
 mkfs/main.c              |   1 -
 8 files changed, 99 insertions(+), 112 deletions(-)

diff --git a/include/erofs/compress.h b/include/erofs/compress.h
index 714f304..81015b2 100644
--- a/include/erofs/compress.h
+++ b/include/erofs/compress.h
@@ -20,7 +20,6 @@ void z_erofs_drop_inline_pcluster(struct erofs_inode *inode);
 int erofs_write_compressed_file(struct erofs_inode *inode, int fd);
 
 int z_erofs_compress_init(struct erofs_buffer_head *bh);
-int z_erofs_compress_exit(void);
 
 void zerofs_print_available_compressors(FILE *f);
 void zerofs_print_supported_compressors(FILE *f, unsigned int mask);
diff --git a/lib/compress.c b/lib/compress.c
index 14d228f..567f11e 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -21,19 +21,12 @@
 #include "erofs/compress_hints.h"
 #include "erofs/fragments.h"
 
-/* compressing configuration specified by users */
-struct erofs_compress_cfg {
-       struct erofs_compress handle;
-       unsigned int algorithmtype;
-       bool enable;
-} erofs_ccfg[EROFS_MAX_COMPR_CFGS];
-
 struct z_erofs_vle_compress_ctx {
        u8 queue[EROFS_CONFIG_COMPR_MAX_SZ * 2];
        struct z_erofs_inmem_extent e;  /* (lookahead) extent */
 
        struct erofs_inode *inode;
-       struct erofs_compress_cfg *ccfg;
+       struct compressor *compressor;
 
        u8 *metacur;
        unsigned int head, tail;
@@ -382,7 +375,7 @@ static int vle_compress_one(struct z_erofs_vle_compress_ctx 
*ctx)
        static char dstbuf[EROFS_CONFIG_COMPR_MAX_SZ + EROFS_MAX_BLOCK_SIZE];
        struct erofs_inode *inode = ctx->inode;
        char *const dst = dstbuf + erofs_blksiz();
-       struct erofs_compress *const h = &ctx->ccfg->handle;
+       struct erofs_compress *const h = &ctx->compressor->handle;
        unsigned int len = ctx->tail - ctx->head;
        bool is_packed_inode = erofs_is_packed_inode(inode);
        bool final = !ctx->remaining;
@@ -842,6 +835,7 @@ int erofs_write_compressed_file(struct erofs_inode *inode, 
int fd)
        static struct z_erofs_vle_compress_ctx ctx;
        erofs_blk_t blkaddr, compressed_blocks;
        unsigned int legacymetasize;
+       int ccfg_idx;
        int ret;
        u8 *compressmeta = malloc(vle_compressmeta_capacity(inode->i_size));
 
@@ -874,18 +868,18 @@ int erofs_write_compressed_file(struct erofs_inode 
*inode, int fd)
        if (cfg.c_fragments && !cfg.c_dedupe)
                inode->z_advise |= Z_EROFS_ADVISE_INTERLACED_PCLUSTER;
 
+       ccfg_idx = erofs_get_compressor_by_name(cfg.c_compr_alg[0]);
 #ifndef NDEBUG
        if (cfg.c_random_algorithms) {
                while (1) {
-                       inode->z_algorithmtype[0] =
-                               rand() % EROFS_MAX_COMPR_CFGS;
-                       if (erofs_ccfg[inode->z_algorithmtype[0]].enable)
+                       ccfg_idx = rand() % erofs_compressor_num();
+                       if (erofs_ccfg.compressors[ccfg_idx].enable)
                                break;
                }
        }
 #endif
-       ctx.ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
-       inode->z_algorithmtype[0] = ctx.ccfg[0].algorithmtype;
+       ctx.compressor = &erofs_ccfg.compressors[ccfg_idx];
+       inode->z_algorithmtype[0] = ctx.compressor->algorithmtype;
        inode->z_algorithmtype[1] = 0;
 
        inode->idata_size = 0;
@@ -1020,15 +1014,6 @@ err_free_meta:
        return ret;
 }
 
-static int erofs_get_compress_algorithm_id(const char *name)
-{
-       if (!strcmp(name, "lz4") || !strcmp(name, "lz4hc"))
-               return Z_EROFS_COMPRESSION_LZ4;
-       if (!strcmp(name, "lzma"))
-               return Z_EROFS_COMPRESSION_LZMA;
-       return -ENOTSUP;
-}
-
 int z_erofs_build_compr_cfgs(struct erofs_buffer_head *sb_bh)
 {
        struct erofs_buffer_head *bh = sb_bh;
@@ -1085,26 +1070,33 @@ int z_erofs_build_compr_cfgs(struct erofs_buffer_head 
*sb_bh)
 
 int z_erofs_compress_init(struct erofs_buffer_head *sb_bh)
 {
-       int i, ret;
+       int i, k, ret;
 
        for (i = 0; cfg.c_compr_alg[i]; ++i) {
-               ret = erofs_compressor_init(&erofs_ccfg[i].handle,
-                                            cfg.c_compr_alg[i]);
-               if (ret)
-                       return ret;
+               struct compressor *compressor = NULL;
 
-               ret = erofs_compressor_setlevel(&erofs_ccfg[i].handle,
-                                               cfg.c_compr_level[i]);
-               if (ret)
-                       return ret;
+               k = erofs_get_compressor_by_name(cfg.c_compr_alg[i]);
+               if (k < 0) {
+                       erofs_warn("Cannot find valid compressor for %s!", 
cfg.c_compr_alg[i]);
+                       continue;
+               }
 
-               ret = erofs_get_compress_algorithm_id(cfg.c_compr_alg[i]);
-               if (ret < 0)
+               if (!erofs_ccfg.compressors[k].handle.alg) {
+                       erofs_err("compressor %s not available!", 
cfg.c_compr_alg[i]);
+                       return -EINVAL;
+               }
+
+               compressor = &erofs_ccfg.compressors[k];
+               ret = erofs_compressor_setlevel(&compressor->handle, 
cfg.c_compr_level[i]);
+               if (ret) {
+                       erofs_err("compressor %s invalid compress level %d!",
+                               cfg.c_compr_alg[i], cfg.c_compr_level[i]);
                        return ret;
-               erofs_ccfg[i].algorithmtype = ret;
-               erofs_ccfg[i].enable = true;
-               sbi.available_compr_algs |= 1 << ret;
-               if (ret != Z_EROFS_COMPRESSION_LZ4)
+               }
+
+               erofs_ccfg.compressors[k].enable = true;
+               sbi.available_compr_algs |= 1 << 
erofs_ccfg.compressors[k].algorithmtype;
+               if (erofs_ccfg.compressors[k].algorithmtype != 
Z_EROFS_COMPRESSION_LZ4)
                        erofs_sb_set_compr_cfgs();
        }
 
@@ -1138,20 +1130,7 @@ int z_erofs_compress_init(struct erofs_buffer_head 
*sb_bh)
        }
 
        if (erofs_sb_has_compr_cfgs()) {
-               sbi.available_compr_algs |= 1 << ret;
                return z_erofs_build_compr_cfgs(sb_bh);
        }
        return 0;
 }
-
-int z_erofs_compress_exit(void)
-{
-       int i, ret;
-
-       for (i = 0; cfg.c_compr_alg[i]; ++i) {
-               ret = erofs_compressor_exit(&erofs_ccfg[i].handle);
-               if (ret)
-                       return ret;
-       }
-       return 0;
-}
diff --git a/lib/compressor.c b/lib/compressor.c
index 5aee4e0..4ba2d53 100644
--- a/lib/compressor.c
+++ b/lib/compressor.c
@@ -10,6 +10,11 @@
 
 #define EROFS_CONFIG_COMPR_DEF_BOUNDARY                (128)
 
+/* for enable compressor constructor */
+extern bool enable_constructor_lz4;
+extern bool enable_constructor_lz4hc;
+extern bool enable_constructor_lzma;
+
 /* compressing configuration specified by users */
 static struct erofs_supported_algothrim {
        int algtype;
@@ -20,7 +25,25 @@ static struct erofs_supported_algothrim {
        { Z_EROFS_COMPRESSION_LZMA, "lzma"},
 };
 
-static struct erofs_compressors_cfg erofs_ccfg;
+struct erofs_compressors_cfg erofs_ccfg;
+
+static void erofs_init_compressor(struct compressor *compressor,
+       const struct erofs_compressor *alg)
+{
+
+       compressor->handle.alg = alg;
+
+       /* should be written in "minimum compression ratio * 100" */
+       compressor->handle.compress_threshold = 100;
+
+       /* optimize for 4k size page */
+       compressor->handle.destsize_alignsize = erofs_blksiz();
+       compressor->handle.destsize_redzone_begin = erofs_blksiz() - 16;
+       compressor->handle.destsize_redzone_end = 
EROFS_CONFIG_COMPR_DEF_BOUNDARY;
+
+       if (alg && alg->init)
+               alg->init(&compressor->handle);
+}
 
 int erofs_compressor_num(void)
 {
@@ -33,17 +56,38 @@ void erofs_compressor_register(const char *name, const 
struct erofs_compressor *
 
        for (i = 0; i < erofs_compressor_num(); i++) {
                if (!strcmp(erofs_ccfg.compressors[i].name, name)) {
-                       erofs_ccfg.compressors[i].handle.alg = alg;
+                       erofs_init_compressor(&erofs_ccfg.compressors[i], alg);
                        return;
                }
        }
 
        erofs_ccfg.compressors[i].name = name;
-       erofs_ccfg.compressors[i].handle.alg = alg;
        erofs_ccfg.compressors[i].algorithmtype = 
erofs_supported_algothrims[i].algtype;
+       erofs_init_compressor(&erofs_ccfg.compressors[i], alg);
        erofs_ccfg.erofs_ccfg_num = ++i;
 }
 
+int erofs_get_compressor_by_name(const char *name)
+{
+       int i;
+
+       for (i = 0; i < erofs_compressor_num(); i++) {
+               if (!strcmp(erofs_ccfg.compressors[i].name, name)) {
+                       return i;
+               }
+       }
+       return -EINVAL;
+}
+
+static void erofs_compressor_unregister(struct erofs_compress *c)
+{
+       const struct erofs_compressor *alg = c->alg;
+
+       if (alg && alg->exit)
+               alg->exit(c);
+       c->alg = NULL;
+}
+
 int erofs_compress_destsize(const struct erofs_compress *c,
                            const void *src, unsigned int *srcsize,
                            void *dst, unsigned int dstsize, bool inblocks)
@@ -119,46 +163,7 @@ int erofs_compressor_setlevel(struct erofs_compress *c, 
int compression_level)
        return 0;
 }
 
-int erofs_compressor_init(struct erofs_compress *c, char *alg_name)
-{
-       int ret, i;
-
-       /* should be written in "minimum compression ratio * 100" */
-       c->compress_threshold = 100;
-
-       /* optimize for 4k size page */
-       c->destsize_alignsize = erofs_blksiz();
-       c->destsize_redzone_begin = erofs_blksiz() - 16;
-       c->destsize_redzone_end = EROFS_CONFIG_COMPR_DEF_BOUNDARY;
-
-       if (!alg_name) {
-               c->alg = NULL;
-               return 0;
-       }
-
-       ret = -EINVAL;
-       for (i = 0; i < erofs_compressor_num(); ++i) {
-               if (alg_name && strcmp(alg_name, 
erofs_ccfg.compressors[i].name))
-                       continue;
-
-               ret = erofs_ccfg.compressors[i].handle.alg->init(c);
-               if (!ret) {
-                       DBG_BUGON(!c->alg);
-                       return 0;
-               }
-       }
-       erofs_err("Cannot find a valid compressor %s", alg_name);
-       return ret;
-}
-
-int erofs_compressor_exit(struct erofs_compress *c)
-{
-       if (c->alg && c->alg->exit)
-               return c->alg->exit(c);
-       return 0;
-}
-
-void __attribute__((constructor(101))) __erofs_compressor_init(void)
+void __attribute__((constructor(101))) erofs_compressor_init(void)
 {
        int i;
 
@@ -166,9 +171,23 @@ void __attribute__((constructor(101))) 
__erofs_compressor_init(void)
        for (i = 0; i < ARRAY_SIZE(erofs_supported_algothrims); i++) {
                erofs_compressor_register(erofs_supported_algothrims[i].name, 
NULL);
        }
+
+#if LZ4_ENABLED
+       enable_constructor_lz4 = true;
+#endif
+#if LZ4HC_ENABLED
+       enable_constructor_lz4hc = true;
+#endif
+#if HAVE_LIBLZMA
+       enable_constructor_lzma = true;
+#endif
 }
 
-void __attribute__((destructor)) __erofs_compressor_exit(void)
+void __attribute__((destructor)) erofs_compressor_exit(void)
 {
-       erofs_err("__erofs_compressor_exit");
+       int i;
+
+       for (i = 0; i < erofs_compressor_num(); ++i) {
+               erofs_compressor_unregister(&erofs_ccfg.compressors[i].handle);
+       }
 }
diff --git a/lib/compressor.h b/lib/compressor.h
index 3c1b328..00f4264 100644
--- a/lib/compressor.h
+++ b/lib/compressor.h
@@ -13,8 +13,6 @@
 struct erofs_compress;
 
 struct erofs_compressor {
-       const char *name;
-
        int default_level;
        int best_level;
 
@@ -54,18 +52,15 @@ struct erofs_compressors_cfg {
 };
 
 /* list of compression algorithms */
-extern const struct erofs_compressor erofs_compressor_lz4;
-extern const struct erofs_compressor erofs_compressor_lz4hc;
-extern const struct erofs_compressor erofs_compressor_lzma;
+extern struct erofs_compressors_cfg erofs_ccfg;
 
 int erofs_compress_destsize(const struct erofs_compress *c,
                            const void *src, unsigned int *srcsize,
                            void *dst, unsigned int dstsize, bool inblocks);
 
 int erofs_compressor_setlevel(struct erofs_compress *c, int compression_level);
-int erofs_compressor_init(struct erofs_compress *c, char *alg_name);
-int erofs_compressor_exit(struct erofs_compress *c);
 
 void erofs_compressor_register(const char *name, const struct erofs_compressor 
*alg);
 int erofs_compressor_num(void);
+int erofs_get_compressor_by_name(const char *name);
 #endif
diff --git a/lib/compressor_liblzma.c b/lib/compressor_liblzma.c
index b24139c..23ab630 100644
--- a/lib/compressor_liblzma.c
+++ b/lib/compressor_liblzma.c
@@ -88,7 +88,6 @@ static int erofs_compressor_liblzma_init(struct 
erofs_compress *c)
 {
        struct erofs_liblzma_context *ctx;
 
-       c->alg = &erofs_compressor_lzma;
        ctx = malloc(sizeof(*ctx));
        if (!ctx)
                return -ENOMEM;
@@ -100,7 +99,6 @@ static int erofs_compressor_liblzma_init(struct 
erofs_compress *c)
 }
 
 const struct erofs_compressor erofs_compressor_lzma = {
-       .name = "lzma",
        .default_level = LZMA_PRESET_DEFAULT,
        .best_level = 109,
        .init = erofs_compressor_liblzma_init,
@@ -109,6 +107,7 @@ const struct erofs_compressor erofs_compressor_lzma = {
        .compress_destsize = erofs_liblzma_compress_destsize,
 };
 
+bool enable_constructor_lzma;
 static void __attribute__((constructor)) register_lzma_compressor(void)
 {
        erofs_compressor_register("lzma", &erofs_compressor_lzma);
diff --git a/lib/compressor_lz4.c b/lib/compressor_lz4.c
index a8adffe..ef4d986 100644
--- a/lib/compressor_lz4.c
+++ b/lib/compressor_lz4.c
@@ -32,13 +32,11 @@ static int compressor_lz4_exit(struct erofs_compress *c)
 
 static int compressor_lz4_init(struct erofs_compress *c)
 {
-       c->alg = &erofs_compressor_lz4;
        sbi.lz4_max_distance = LZ4_DISTANCE_MAX;
        return 0;
 }
 
 const struct erofs_compressor erofs_compressor_lz4 = {
-       .name = "lz4",
        .default_level = 0,
        .best_level = 0,
        .init = compressor_lz4_init,
@@ -46,6 +44,7 @@ const struct erofs_compressor erofs_compressor_lz4 = {
        .compress_destsize = lz4_compress_destsize,
 };
 
+bool enable_constructor_lz4;
 static void __attribute__((constructor)) register_lz4_compressor(void)
 {
        erofs_compressor_register("lz4", &erofs_compressor_lz4);
diff --git a/lib/compressor_lz4hc.c b/lib/compressor_lz4hc.c
index 2b7e900..c5ce1a3 100644
--- a/lib/compressor_lz4hc.c
+++ b/lib/compressor_lz4hc.c
@@ -38,8 +38,6 @@ static int compressor_lz4hc_exit(struct erofs_compress *c)
 
 static int compressor_lz4hc_init(struct erofs_compress *c)
 {
-       c->alg = &erofs_compressor_lz4hc;
-
        c->private_data = LZ4_createStreamHC();
        if (!c->private_data)
                return -ENOMEM;
@@ -60,7 +58,6 @@ static int compressor_lz4hc_setlevel(struct erofs_compress *c,
 }
 
 const struct erofs_compressor erofs_compressor_lz4hc = {
-       .name = "lz4hc",
        .default_level = LZ4HC_CLEVEL_DEFAULT,
        .best_level = LZ4HC_CLEVEL_MAX,
        .init = compressor_lz4hc_init,
@@ -69,6 +66,7 @@ const struct erofs_compressor erofs_compressor_lz4hc = {
        .compress_destsize = lz4hc_compress_destsize,
 };
 
+bool enable_constructor_lz4hc;
 static void __attribute__((constructor)) register_lz4hc_compressor(void)
 {
        erofs_compressor_register("lz4hc", &erofs_compressor_lz4hc);
diff --git a/mkfs/main.c b/mkfs/main.c
index dbd168e..6bf0472 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -916,7 +916,6 @@ int main(int argc, char **argv)
        if (!err && erofs_sb_has_sb_chksum())
                err = erofs_mkfs_superblock_csum_set();
 exit:
-       z_erofs_compress_exit();
        z_erofs_dedupe_exit();
 #ifdef WITH_ANDROID
        erofs_droid_blocklist_fclose();
-- 
2.31.1

Reply via email to