[PATCH v2 1/2] erofs-utils: lib: add a way to request supported algorithms
Guo Xuenan
guoxuenan at huaweicloud.com
Tue Aug 8 22:21:37 AEST 2023
Tested-by: Guo Xuenan <guoxuenan at huawei.com>
Thanks
Xuenan
On 2023/8/8 17:23, Gao Xiang wrote:
> dump.erofs needs to print supported algorithms instead of available
> compressors.
>
> In addition, clean up erofs_get_compress_algorithm_id() too.
>
> Cc: Guo Xuenan <guoxuenan at huawei.com>
> Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
> ---
> changes since v1:
> - fix `available compressors` print.
>
> fsck/main.c | 8 ++--
> include/erofs/compress.h | 3 +-
> lib/compress.c | 33 ++++----------
> lib/compressor.c | 90 ++++++++++++++++++++++++++++---------
> lib/compressor.h | 7 +--
> lib/compressor_deflate.c | 2 -
> lib/compressor_libdeflate.c | 2 -
> lib/compressor_liblzma.c | 2 -
> lib/compressor_lz4.c | 2 -
> lib/compressor_lz4hc.c | 3 --
> mkfs/main.c | 8 ++--
> 11 files changed, 94 insertions(+), 66 deletions(-)
>
> diff --git a/fsck/main.c b/fsck/main.c
> index 39a5534..7f78513 100644
> --- a/fsck/main.c
> +++ b/fsck/main.c
> @@ -61,13 +61,15 @@ static struct list_head erofsfsck_link_hashtable[NR_HARDLINK_HASHTABLE];
>
> static void print_available_decompressors(FILE *f, const char *delim)
> {
> - unsigned int i = 0;
> + int i = 0;
> + bool comma = false;
> const char *s;
>
> - while ((s = z_erofs_list_available_compressors(i)) != NULL) {
> - if (i++)
> + while ((s = z_erofs_list_available_compressors(&i)) != NULL) {
> + if (comma)
> fputs(delim, f);
> fputs(s, f);
> + comma = true;
> }
> fputc('\n', f);
> }
> diff --git a/include/erofs/compress.h b/include/erofs/compress.h
> index f1ad84a..46cff03 100644
> --- a/include/erofs/compress.h
> +++ b/include/erofs/compress.h
> @@ -23,7 +23,8 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi,
> struct erofs_buffer_head *bh);
> int z_erofs_compress_exit(void);
>
> -const char *z_erofs_list_available_compressors(unsigned int i);
> +const char *z_erofs_list_supported_algorithms(int i, unsigned int *mask);
> +const char *z_erofs_list_available_compressors(int *i);
>
> static inline bool erofs_is_packed_inode(struct erofs_inode *inode)
> {
> diff --git a/lib/compress.c b/lib/compress.c
> index b43b077..e5d310f 100644
> --- a/lib/compress.c
> +++ b/lib/compress.c
> @@ -1030,17 +1030,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;
> - if (!strcmp(name, "deflate") || !strcmp(name, "libdeflate"))
> - return Z_EROFS_COMPRESSION_DEFLATE;
> - return -ENOTSUP;
> -}
> -
> static int z_erofs_build_compr_cfgs(struct erofs_sb_info *sbi,
> struct erofs_buffer_head *sb_bh)
> {
> @@ -1123,23 +1112,21 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
> int i, ret;
>
> for (i = 0; cfg.c_compr_alg[i]; ++i) {
> - ret = erofs_compressor_init(sbi, &erofs_ccfg[i].handle,
> - cfg.c_compr_alg[i]);
> + struct erofs_compress *c = &erofs_ccfg[i].handle;
> +
> + ret = erofs_compressor_init(sbi, c, cfg.c_compr_alg[i]);
> if (ret)
> return ret;
>
> - ret = erofs_compressor_setlevel(&erofs_ccfg[i].handle,
> - cfg.c_compr_level[i]);
> + ret = erofs_compressor_setlevel(c, cfg.c_compr_level[i]);
> if (ret)
> return ret;
>
> - ret = erofs_get_compress_algorithm_id(cfg.c_compr_alg[i]);
> - if (ret < 0)
> - return ret;
> - erofs_ccfg[i].algorithmtype = ret;
> + erofs_ccfg[i].algorithmtype =
> + z_erofs_get_compress_algorithm_id(c);
> erofs_ccfg[i].enable = true;
> - sbi->available_compr_algs |= 1 << ret;
> - if (ret != Z_EROFS_COMPRESSION_LZ4)
> + sbi->available_compr_algs |= 1 << erofs_ccfg[i].algorithmtype;
> + if (erofs_ccfg[i].algorithmtype != Z_EROFS_COMPRESSION_LZ4)
> erofs_sb_set_compr_cfgs(sbi);
> }
>
> @@ -1172,10 +1159,8 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
> return -EINVAL;
> }
>
> - if (erofs_sb_has_compr_cfgs(sbi)) {
> - sbi->available_compr_algs |= 1 << ret;
> + if (erofs_sb_has_compr_cfgs(sbi))
> return z_erofs_build_compr_cfgs(sbi, sb_bh);
> - }
> return 0;
> }
>
> diff --git a/lib/compressor.c b/lib/compressor.c
> index 4333f26..7230f01 100644
> --- a/lib/compressor.c
> +++ b/lib/compressor.c
> @@ -10,22 +10,72 @@
>
> #define EROFS_CONFIG_COMPR_DEF_BOUNDARY (128)
>
> -static const struct erofs_compressor *compressors[] = {
> +static const struct erofs_algorithm {
> + char *name;
> + const struct erofs_compressor *c;
> + unsigned int id;
> +
> + /* its name won't be shown as a supported algorithm */
> + bool optimisor;
> +} erofs_algs[] = {
> + { "lz4",
> #if LZ4_ENABLED
> -#if LZ4HC_ENABLED
> - &erofs_compressor_lz4hc,
> -#endif
> &erofs_compressor_lz4,
> +#else
> + NULL,
> #endif
> + Z_EROFS_COMPRESSION_LZ4, false },
> +
> +#if LZ4HC_ENABLED
> + { "lz4hc", &erofs_compressor_lz4hc,
> + Z_EROFS_COMPRESSION_LZ4, true },
> +#endif
> +
> + { "lzma",
> #if HAVE_LIBLZMA
> &erofs_compressor_lzma,
> +#else
> + NULL,
> #endif
> - &erofs_compressor_deflate,
> + Z_EROFS_COMPRESSION_LZMA, false },
> +
> + { "deflate", &erofs_compressor_deflate,
> + Z_EROFS_COMPRESSION_DEFLATE, false },
> +
> #if HAVE_LIBDEFLATE
> - &erofs_compressor_libdeflate,
> + { "libdeflate", &erofs_compressor_libdeflate,
> + Z_EROFS_COMPRESSION_DEFLATE, true },
> #endif
> };
>
> +int z_erofs_get_compress_algorithm_id(const struct erofs_compress *c)
> +{
> + DBG_BUGON(!c->alg);
> + return c->alg->id;
> +}
> +
> +const char *z_erofs_list_supported_algorithms(int i, unsigned int *mask)
> +{
> + if (i >= ARRAY_SIZE(erofs_algs))
> + return NULL;
> + if (!erofs_algs[i].optimisor && (*mask & (1 << erofs_algs[i].id))) {
> + *mask ^= 1 << erofs_algs[i].id;
> + return erofs_algs[i].name;
> + }
> + return "";
> +}
> +
> +const char *z_erofs_list_available_compressors(int *i)
> +{
> + for (;*i < ARRAY_SIZE(erofs_algs); ++*i) {
> + if (!erofs_algs[*i].c)
> + continue;
> + return erofs_algs[(*i)++].name;
> + }
> +
> + return NULL;
> +}
> +
> int erofs_compress_destsize(const struct erofs_compress *c,
> const void *src, unsigned int *srcsize,
> void *dst, unsigned int dstsize, bool inblocks)
> @@ -34,11 +84,11 @@ int erofs_compress_destsize(const struct erofs_compress *c,
> int ret;
>
> DBG_BUGON(!c->alg);
> - if (!c->alg->compress_destsize)
> + if (!c->alg->c->compress_destsize)
> return -ENOTSUP;
>
> uncompressed_capacity = *srcsize;
> - ret = c->alg->compress_destsize(c, src, srcsize, dst, dstsize);
> + ret = c->alg->c->compress_destsize(c, src, srcsize, dst, dstsize);
> if (ret < 0)
> return ret;
>
> @@ -55,16 +105,11 @@ int erofs_compress_destsize(const struct erofs_compress *c,
> return ret;
> }
>
> -const char *z_erofs_list_available_compressors(unsigned int i)
> -{
> - return i >= ARRAY_SIZE(compressors) ? NULL : compressors[i]->name;
> -}
> -
> int erofs_compressor_setlevel(struct erofs_compress *c, int compression_level)
> {
> DBG_BUGON(!c->alg);
> - if (c->alg->setlevel)
> - return c->alg->setlevel(c, compression_level);
> + if (c->alg->c->setlevel)
> + return c->alg->c->setlevel(c, compression_level);
>
> if (compression_level >= 0)
> return -EINVAL;
> @@ -93,13 +138,16 @@ int erofs_compressor_init(struct erofs_sb_info *sbi,
> }
>
> ret = -EINVAL;
> - for (i = 0; i < ARRAY_SIZE(compressors); ++i) {
> - if (alg_name && strcmp(alg_name, compressors[i]->name))
> + for (i = 0; i < ARRAY_SIZE(erofs_algs); ++i) {
> + if (alg_name && strcmp(alg_name, erofs_algs[i].name))
> + continue;
> +
> + if (!erofs_algs[i].c)
> continue;
>
> - ret = compressors[i]->init(c);
> + ret = erofs_algs[i].c->init(c);
> if (!ret) {
> - DBG_BUGON(!c->alg);
> + c->alg = &erofs_algs[i];
> return 0;
> }
> }
> @@ -109,7 +157,7 @@ int erofs_compressor_init(struct erofs_sb_info *sbi,
>
> int erofs_compressor_exit(struct erofs_compress *c)
> {
> - if (c->alg && c->alg->exit)
> - return c->alg->exit(c);
> + if (c->alg && c->alg->c->exit)
> + return c->alg->c->exit(c);
> return 0;
> }
> diff --git a/lib/compressor.h b/lib/compressor.h
> index 08a3988..9fa01d1 100644
> --- a/lib/compressor.h
> +++ b/lib/compressor.h
> @@ -12,8 +12,6 @@
> struct erofs_compress;
>
> struct erofs_compressor {
> - const char *name;
> -
> int default_level;
> int best_level;
>
> @@ -26,9 +24,11 @@ struct erofs_compressor {
> void *dst, unsigned int dstsize);
> };
>
> +struct erofs_algorithm;
> +
> struct erofs_compress {
> struct erofs_sb_info *sbi;
> - const struct erofs_compressor *alg;
> + const struct erofs_algorithm *alg;
>
> unsigned int compress_threshold;
> unsigned int compression_level;
> @@ -48,6 +48,7 @@ extern const struct erofs_compressor erofs_compressor_lzma;
> extern const struct erofs_compressor erofs_compressor_deflate;
> extern const struct erofs_compressor erofs_compressor_libdeflate;
>
> +int z_erofs_get_compress_algorithm_id(const struct erofs_compress *c);
> int erofs_compress_destsize(const struct erofs_compress *c,
> const void *src, unsigned int *srcsize,
> void *dst, unsigned int dstsize, bool inblocks);
> diff --git a/lib/compressor_deflate.c b/lib/compressor_deflate.c
> index 5a7a657..4e5902e 100644
> --- a/lib/compressor_deflate.c
> +++ b/lib/compressor_deflate.c
> @@ -36,7 +36,6 @@ static int compressor_deflate_exit(struct erofs_compress *c)
>
> static int compressor_deflate_init(struct erofs_compress *c)
> {
> - c->alg = &erofs_compressor_deflate;
> c->private_data = NULL;
>
> erofs_warn("EXPERIMENTAL DEFLATE algorithm in use. Use at your own risk!");
> @@ -68,7 +67,6 @@ static int erofs_compressor_deflate_setlevel(struct erofs_compress *c,
> }
>
> const struct erofs_compressor erofs_compressor_deflate = {
> - .name = "deflate",
> .default_level = 1,
> .best_level = 9,
> .init = compressor_deflate_init,
> diff --git a/lib/compressor_libdeflate.c b/lib/compressor_libdeflate.c
> index 2756dd8..c0b019a 100644
> --- a/lib/compressor_libdeflate.c
> +++ b/lib/compressor_libdeflate.c
> @@ -82,7 +82,6 @@ static int compressor_libdeflate_exit(struct erofs_compress *c)
>
> static int compressor_libdeflate_init(struct erofs_compress *c)
> {
> - c->alg = &erofs_compressor_libdeflate;
> c->private_data = NULL;
>
> erofs_warn("EXPERIMENTAL libdeflate compressor in use. Use at your own risk!");
> @@ -104,7 +103,6 @@ static int erofs_compressor_libdeflate_setlevel(struct erofs_compress *c,
> }
>
> const struct erofs_compressor erofs_compressor_libdeflate = {
> - .name = "libdeflate",
> .default_level = 1,
> .best_level = 12,
> .init = compressor_libdeflate_init,
> diff --git a/lib/compressor_liblzma.c b/lib/compressor_liblzma.c
> index f274dce..0ed6f23 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,
> diff --git a/lib/compressor_lz4.c b/lib/compressor_lz4.c
> index e507b70..6677693 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;
> c->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,
> diff --git a/lib/compressor_lz4hc.c b/lib/compressor_lz4hc.c
> index f2120d8..b410e15 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,
> diff --git a/mkfs/main.c b/mkfs/main.c
> index 3809c71..9c2397c 100644
> --- a/mkfs/main.c
> +++ b/mkfs/main.c
> @@ -68,13 +68,15 @@ static struct option long_options[] = {
>
> static void print_available_compressors(FILE *f, const char *delim)
> {
> - unsigned int i = 0;
> + int i = 0;
> + bool comma = false;
> const char *s;
>
> - while ((s = z_erofs_list_available_compressors(i)) != NULL) {
> - if (i++)
> + while ((s = z_erofs_list_available_compressors(&i)) != NULL) {
> + if (comma)
> fputs(delim, f);
> fputs(s, f);
> + comma = true;
> }
> fputc('\n', f);
> }
--
Best regards
Guo Xuenan
More information about the Linux-erofs
mailing list