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