static void tryrecompress_trailing(struct z_erofs_vle_compress_ctx *ctx,
struct erofs_compress *ec,
void *in, unsigned int *insize,
- void *out, int *compressedsize)
+ void *out, unsigned int *compressedsize)
{
struct erofs_sb_info *sbi = ctx->inode->sbi;
static char tmp[Z_EROFS_PCLUSTER_MAX_SIZE];
count = *insize;
ret = erofs_compress_destsize(ec, in, &count, (void *)tmp,
- rounddown(ret, erofs_blksiz(sbi)), false);
+ rounddown(ret, erofs_blksiz(sbi)));
if (ret <= 0 || ret + (*insize - count) >=
roundup(*compressedsize, erofs_blksiz(sbi)))
return;
static char dstbuf[EROFS_CONFIG_COMPR_MAX_SZ + EROFS_MAX_BLOCK_SIZE];
struct erofs_inode *inode = ctx->inode;
struct erofs_sb_info *sbi = inode->sbi;
- char *const dst = dstbuf + erofs_blksiz(sbi);
+ unsigned int blksz = erofs_blksiz(sbi);
+ char *const dst = dstbuf + blksz;
struct erofs_compress *const h = &ctx->ccfg->handle;
unsigned int len = ctx->tail - ctx->head;
bool is_packed_inode = erofs_is_packed_inode(inode);
bool may_inline = (cfg.c_ztailpacking && final &&
!may_packing);
bool fix_dedupedfrag = ctx->fix_dedupedfrag;
+ unsigned int compressedsize;
if (z_erofs_compress_dedupe(ctx, &len) && !final)
break;
break;
if (may_packing) {
if (inode->fragment_size && !fix_dedupedfrag) {
- ctx->pclustersize =
- roundup(len, erofs_blksiz(sbi));
+ ctx->pclustersize = roundup(len, blksz);
goto fix_dedupedfrag;
}
ctx->e.length = len;
goto frag_packing;
}
- if (!may_inline && len <= erofs_blksiz(sbi))
+ if (!may_inline && len <= blksz)
goto nocompression;
}
ctx->e.length = min(len,
cfg.c_max_decompressed_extent_bytes);
+
ret = erofs_compress_destsize(h, ctx->queue + ctx->head,
- &ctx->e.length, dst, ctx->pclustersize,
- !(final && len == ctx->e.length));
+ &ctx->e.length, dst, ctx->pclustersize);
if (ret <= 0) {
- if (ret != -EAGAIN) {
- erofs_err("failed to compress %s: %s",
- inode->i_srcpath,
- erofs_strerror(ret));
- }
+ erofs_err("failed to compress %s: %s", inode->i_srcpath,
+ erofs_strerror(ret));
+ return ret;
+ }
+
+ compressedsize = ret;
+ /* even compressed size is smaller, there is no real gain */
+ if (!(may_inline && ctx->e.length == len && ret < blksz))
+ ret = roundup(ret, blksz);
- if (may_inline && len < erofs_blksiz(sbi)) {
+ /* check if there is enough gain to keep the compressed data */
+ if (ret * h->compress_threshold / 100 >= ctx->e.length) {
+ if (may_inline && len < blksz) {
ret = z_erofs_fill_inline_data(inode,
ctx->queue + ctx->head,
len, true);
ctx->e.compressedblks = 1;
ctx->e.raw = true;
} else if (may_packing && len == ctx->e.length &&
- ret < ctx->pclustersize &&
+ compressedsize < ctx->pclustersize &&
(!inode->fragment_size || fix_dedupedfrag)) {
frag_packing:
ret = z_erofs_pack_fragments(inode,
fix_dedupedfrag = false;
/* tailpcluster should be less than 1 block */
} else if (may_inline && len == ctx->e.length &&
- ret < erofs_blksiz(sbi)) {
- if (ctx->clusterofs + len <= erofs_blksiz(sbi)) {
+ compressedsize < blksz) {
+ if (ctx->clusterofs + len <= blksz) {
inode->eof_tailraw = malloc(len);
if (!inode->eof_tailraw)
return -ENOMEM;
inode->eof_tailrawsize = len;
}
- ret = z_erofs_fill_inline_data(inode, dst, ret, false);
+ ret = z_erofs_fill_inline_data(inode, dst,
+ compressedsize, false);
if (ret < 0)
return ret;
ctx->e.compressedblks = 1;
* Otherwise, just drop it and go to packing.
*/
if (may_packing && len == ctx->e.length &&
- (ret & (erofs_blksiz(sbi) - 1)) &&
+ (compressedsize & (blksz - 1)) &&
ctx->tail < sizeof(ctx->queue)) {
- ctx->pclustersize = BLK_ROUND_UP(sbi, ret) *
- erofs_blksiz(sbi);
+ ctx->pclustersize =
+ roundup(compressedsize, blksz);
goto fix_dedupedfrag;
}
if (may_inline && len == ctx->e.length)
tryrecompress_trailing(ctx, h,
ctx->queue + ctx->head,
- &ctx->e.length, dst, &ret);
+ &ctx->e.length, dst,
+ &compressedsize);
- tailused = ret & (erofs_blksiz(sbi) - 1);
- padding = 0;
- ctx->e.compressedblks = BLK_ROUND_UP(sbi, ret);
- DBG_BUGON(ctx->e.compressedblks * erofs_blksiz(sbi) >=
+ ctx->e.compressedblks = BLK_ROUND_UP(sbi, compressedsize);
+ DBG_BUGON(ctx->e.compressedblks * blksz >=
ctx->e.length);
+ padding = 0;
+ tailused = compressedsize & (blksz - 1);
+ if (tailused)
+ padding = blksz - tailused;
+
/* zero out garbage trailing data for non-0padding */
- if (!erofs_sb_has_lz4_0padding(sbi))
- memset(dst + ret, 0,
- roundup(ret, erofs_blksiz(sbi)) - ret);
- else if (tailused)
- padding = erofs_blksiz(sbi) - tailused;
+ if (!erofs_sb_has_lz4_0padding(sbi)) {
+ memset(dst + compressedsize, 0, padding);
+ padding = 0;
+ }
/* write compressed data */
erofs_dbg("Writing %u compressed data to %u of %u blocks",
if (!final && ctx->head >= EROFS_CONFIG_COMPR_MAX_SZ) {
const unsigned int qh_aligned =
- round_down(ctx->head, erofs_blksiz(sbi));
+ round_down(ctx->head, blksz);
const unsigned int qh_after = ctx->head - qh_aligned;
memmove(ctx->queue, ctx->queue + qh_aligned,
#include "compressor.h"
#include "erofs/print.h"
-#define EROFS_CONFIG_COMPR_DEF_BOUNDARY (128)
-
static const struct erofs_algorithm {
char *name;
const struct erofs_compressor *c;
int erofs_compress_destsize(const struct erofs_compress *c,
const void *src, unsigned int *srcsize,
- void *dst, unsigned int dstsize, bool inblocks)
+ void *dst, unsigned int dstsize)
{
- unsigned int uncompressed_capacity, compressed_size;
- int ret;
-
DBG_BUGON(!c->alg);
if (!c->alg->c->compress_destsize)
- return -ENOTSUP;
-
- uncompressed_capacity = *srcsize;
- ret = c->alg->c->compress_destsize(c, src, srcsize, dst, dstsize);
- if (ret < 0)
- return ret;
-
- /* XXX: ret >= destsize_alignsize is a temporary hack for ztailpacking */
- if (inblocks || ret >= c->destsize_alignsize ||
- uncompressed_capacity != *srcsize)
- compressed_size = roundup(ret, c->destsize_alignsize);
- else
- compressed_size = ret;
- DBG_BUGON(c->compress_threshold < 100);
- /* check if there is enough gains to compress */
- if (*srcsize <= compressed_size * c->compress_threshold / 100)
- return -EAGAIN;
- return ret;
+ return -EOPNOTSUPP;
+
+ return c->alg->c->compress_destsize(c, src, srcsize, dst, dstsize);
}
int erofs_compressor_setlevel(struct erofs_compress *c, int compression_level)
/* should be written in "minimum compression ratio * 100" */
c->compress_threshold = 100;
- /* optimize for 4k size page */
- c->destsize_alignsize = erofs_blksiz(sbi);
- c->destsize_redzone_begin = erofs_blksiz(sbi) - 16;
- c->destsize_redzone_end = EROFS_CONFIG_COMPR_DEF_BOUNDARY;
-
if (!alg_name) {
c->alg = NULL;
return 0;