From: Yifan Zhao <zhaoyi...@sjtu.edu.cn> z_erofs_merge_segment() doesn't consider the ztailpacking block in the extent list and unnecessarily writes it back to the disk. This patch fixes this issue by introducing a new `inlined` field in the struct `z_erofs_inmem_extent`.
Fixes: 830b27bc2334 ("erofs-utils: mkfs: introduce inner-file multi-threaded compression") Signed-off-by: Yifan Zhao <zhaoyi...@sjtu.edu.cn> [ Gao Xiang: simplify a bit. ] Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- v2: Yifan's patch is almost correct, it just has minor changes. include/erofs/dedupe.h | 2 +- lib/compress.c | 14 +++++++++++--- lib/dedupe.c | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/erofs/dedupe.h b/include/erofs/dedupe.h index 153bd4c..4cbfb2c 100644 --- a/include/erofs/dedupe.h +++ b/include/erofs/dedupe.h @@ -16,7 +16,7 @@ struct z_erofs_inmem_extent { erofs_blk_t blkaddr; unsigned int compressedblks; unsigned int length; - bool raw, partial; + bool raw, partial, inlined; }; struct z_erofs_dedupe_ctx { diff --git a/lib/compress.c b/lib/compress.c index 74c5707..b084446 100644 --- a/lib/compress.c +++ b/lib/compress.c @@ -305,6 +305,7 @@ static int z_erofs_compress_dedupe(struct z_erofs_compress_sctx *ctx, if (z_erofs_dedupe_match(&dctx)) break; + DBG_BUGON(dctx.e.inlined); delta = ctx->queue + ctx->head - dctx.cur; /* * For big pcluster dedupe, leave two indices at least to store @@ -519,6 +520,7 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx, unsigned int compressedsize; int ret; + *e = (struct z_erofs_inmem_extent){}; if (len <= ctx->pclustersize) { if (!final || !len) return 1; @@ -553,16 +555,18 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx, if (may_inline && len < blksz) { ret = z_erofs_fill_inline_data(inode, ctx->queue + ctx->head, len, true); + if (ret < 0) + return ret; + e->inlined = true; } else { may_inline = false; may_packing = false; nocompression: /* TODO: reset clusterofs to 0 if permitted */ ret = write_uncompressed_extent(ctx, len, dst); + if (ret < 0) + return ret; } - - if (ret < 0) - return ret; e->length = ret; /* @@ -598,6 +602,7 @@ frag_packing: compressedsize, false); if (ret < 0) return ret; + e->inlined = true; e->compressedblks = 1; e->raw = false; } else { @@ -1151,6 +1156,9 @@ int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx, ei->e.blkaddr = sctx->blkaddr; sctx->blkaddr += ei->e.compressedblks; + /* skip write data but leave blkaddr for inline fallback */ + if (ei->e.inlined) + continue; ret2 = blk_write(sbi, sctx->membuf + blkoff * erofs_blksiz(sbi), ei->e.blkaddr, ei->e.compressedblks); blkoff += ei->e.compressedblks; diff --git a/lib/dedupe.c b/lib/dedupe.c index 19a1c8d..aaaccb5 100644 --- a/lib/dedupe.c +++ b/lib/dedupe.c @@ -138,6 +138,7 @@ int z_erofs_dedupe_match(struct z_erofs_dedupe_ctx *ctx) ctx->e.partial = e->partial || (window_size + extra < e->original_length); ctx->e.raw = e->raw; + ctx->e.inlined = false; ctx->e.blkaddr = e->compressed_blkaddr; ctx->e.compressedblks = e->compressed_blks; return 0; -- 2.30.2