`last_uncompressed_size` should be reset on the basis of segments. Fixes: 830b27bc2334 ("erofs-utils: mkfs: introduce inner-file multi-threaded compression") Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- lib/compress.c | 2 +- lib/compressor.c | 6 +++++ lib/compressor.h | 2 ++ lib/compressor_libdeflate.c | 46 +++++++++++++++++++++++++++---------- 4 files changed, 43 insertions(+), 13 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c index b473587..b61907a 100644 --- a/lib/compress.c +++ b/lib/compress.c @@ -1245,7 +1245,7 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp) sctx->queue = tls->queue; sctx->destbuf = tls->destbuf; sctx->chandle = &tls->ccfg[cwork->alg_id].handle; - + erofs_compressor_reset(sctx->chandle); sctx->membuf = malloc(round_up(sctx->remaining, erofs_blksiz(sbi))); if (!sctx->membuf) { ret = -ENOMEM; diff --git a/lib/compressor.c b/lib/compressor.c index 24c99ac..41f49ff 100644 --- a/lib/compressor.c +++ b/lib/compressor.c @@ -155,3 +155,9 @@ int erofs_compressor_exit(struct erofs_compress *c) return c->alg->c->exit(c); return 0; } + +void erofs_compressor_reset(struct erofs_compress *c) +{ + if (c->alg && c->alg->c->reset) + c->alg->c->reset(c); +} diff --git a/lib/compressor.h b/lib/compressor.h index 59d525d..8d322d5 100644 --- a/lib/compressor.h +++ b/lib/compressor.h @@ -19,6 +19,7 @@ struct erofs_compressor { int (*init)(struct erofs_compress *c); int (*exit)(struct erofs_compress *c); + void (*reset)(struct erofs_compress *c); int (*setlevel)(struct erofs_compress *c, int compression_level); int (*setdictsize)(struct erofs_compress *c, u32 dict_size); @@ -63,5 +64,6 @@ int erofs_compress_destsize(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); int erofs_compressor_exit(struct erofs_compress *c); +void erofs_compressor_reset(struct erofs_compress *c); #endif diff --git a/lib/compressor_libdeflate.c b/lib/compressor_libdeflate.c index 14cbce4..32e8ff9 100644 --- a/lib/compressor_libdeflate.c +++ b/lib/compressor_libdeflate.c @@ -3,22 +3,28 @@ #include "erofs/print.h" #include "erofs/config.h" #include <libdeflate.h> +#include <stdlib.h> #include "compressor.h" #include "erofs/atomic.h" +struct erofs_libdeflate_context { + struct libdeflate_compressor *strm; + size_t last_uncompressed_size; +}; + static int libdeflate_compress_destsize(const struct erofs_compress *c, const void *src, unsigned int *srcsize, void *dst, unsigned int dstsize) { - static size_t last_uncompressed_size = 0; + struct erofs_libdeflate_context *ctx = c->private_data; size_t l = 0; /* largest input that fits so far */ size_t l_csize = 0; size_t r = *srcsize + 1; /* smallest input that doesn't fit so far */ size_t m; u8 tmpbuf[dstsize + 9]; - if (last_uncompressed_size) - m = last_uncompressed_size * 15 / 16; + if (ctx->last_uncompressed_size) + m = ctx->last_uncompressed_size * 15 / 16; else m = dstsize * 4; for (;;) { @@ -27,7 +33,7 @@ static int libdeflate_compress_destsize(const struct erofs_compress *c, m = max(m, l + 1); m = min(m, r - 1); - csize = libdeflate_deflate_compress(c->private_data, src, m, + csize = libdeflate_deflate_compress(ctx->strm, src, m, tmpbuf, dstsize + 9); /*printf("Tried %zu => %zu\n", m, csize);*/ if (csize > 0 && csize <= dstsize) { @@ -68,33 +74,48 @@ static int libdeflate_compress_destsize(const struct erofs_compress *c, /*printf("Choosing %zu => %zu\n", l, l_csize);*/ *srcsize = l; - last_uncompressed_size = l; + ctx->last_uncompressed_size = l; return l_csize; } static int compressor_libdeflate_exit(struct erofs_compress *c) { - if (!c->private_data) - return -EINVAL; + struct erofs_libdeflate_context *ctx = c->private_data; - libdeflate_free_compressor(c->private_data); + if (!ctx) + return -EINVAL; + libdeflate_free_compressor(ctx->strm); + free(ctx); return 0; } static int compressor_libdeflate_init(struct erofs_compress *c) { static erofs_atomic_bool_t __warnonce; + struct erofs_libdeflate_context *ctx; - libdeflate_free_compressor(c->private_data); - c->private_data = libdeflate_alloc_compressor(c->compression_level); - if (!c->private_data) + DBG_BUGON(c->private_data); + ctx = calloc(1, sizeof(struct erofs_libdeflate_context)); + if (!ctx) return -ENOMEM; - + ctx->strm = libdeflate_alloc_compressor(c->compression_level); + if (!ctx->strm) { + free(ctx); + return -ENOMEM; + } + c->private_data = ctx; if (!erofs_atomic_test_and_set(&__warnonce)) erofs_warn("EXPERIMENTAL libdeflate compressor in use. Use at your own risk!"); return 0; } +static void compressor_libdeflate_reset(struct erofs_compress *c) +{ + struct erofs_libdeflate_context *ctx = c->private_data; + + ctx->last_uncompressed_size = 0; +} + static int erofs_compressor_libdeflate_setlevel(struct erofs_compress *c, int compression_level) { @@ -114,6 +135,7 @@ const struct erofs_compressor erofs_compressor_libdeflate = { .best_level = 12, .init = compressor_libdeflate_init, .exit = compressor_libdeflate_exit, + .reset = compressor_libdeflate_reset, .setlevel = erofs_compressor_libdeflate_setlevel, .compress_destsize = libdeflate_compress_destsize, }; -- 2.43.5