[PATCH v3 2/3] erofs-utils: lib: split vle_compress_one()
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Dec 19 01:57:09 AEDT 2023
Split compression for each extent into a new helper for later reworking.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
lib/compress.c | 297 ++++++++++++++++++++++++-------------------------
1 file changed, 147 insertions(+), 150 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c
index a5ef6e4..eafbad1 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -400,7 +400,8 @@ static bool z_erofs_fixup_deduped_fragment(struct z_erofs_vle_compress_ctx *ctx,
return true;
}
-static int vle_compress_one(struct z_erofs_vle_compress_ctx *ctx)
+static int __z_erofs_compress_one(struct z_erofs_vle_compress_ctx *ctx,
+ struct z_erofs_inmem_extent *e)
{
static char dstbuf[EROFS_CONFIG_COMPR_MAX_SZ + EROFS_MAX_BLOCK_SIZE];
struct erofs_inode *inode = ctx->inode;
@@ -411,181 +412,177 @@ static int vle_compress_one(struct z_erofs_vle_compress_ctx *ctx)
unsigned int len = ctx->tail - ctx->head;
bool is_packed_inode = erofs_is_packed_inode(inode);
bool final = !ctx->remaining;
+ bool may_packing = (cfg.c_fragments && final && !is_packed_inode);
+ bool may_inline = (cfg.c_ztailpacking && final && !may_packing);
+ unsigned int compressedsize;
int ret;
- while (len) {
- bool may_packing = (cfg.c_fragments && final &&
- !is_packed_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))
- break;
-
- if (len <= ctx->pclustersize) {
- if (!final || !len)
- break;
- if (may_packing) {
- if (inode->fragment_size && !fix_dedupedfrag) {
- ctx->pclustersize = roundup(len, blksz);
- goto fix_dedupedfrag;
- }
- ctx->e.length = len;
- goto frag_packing;
+ if (len <= ctx->pclustersize) {
+ if (!final || !len)
+ return 1;
+ if (may_packing) {
+ if (inode->fragment_size && !ctx->fix_dedupedfrag) {
+ ctx->pclustersize = roundup(len, blksz);
+ goto fix_dedupedfrag;
}
- if (!may_inline && len <= blksz)
- goto nocompression;
+ e->length = len;
+ goto frag_packing;
}
+ if (!may_inline && len <= blksz)
+ goto nocompression;
+ }
- ctx->e.length = min(len,
- cfg.c_max_decompressed_extent_bytes);
+ e->length = min(len, cfg.c_max_decompressed_extent_bytes);
+ ret = erofs_compress_destsize(h, ctx->queue + ctx->head,
+ &e->length, dst, ctx->pclustersize);
+ if (ret <= 0) {
+ erofs_err("failed to compress %s: %s", inode->i_srcpath,
+ erofs_strerror(ret));
+ return ret;
+ }
- ret = erofs_compress_destsize(h, ctx->queue + ctx->head,
- &ctx->e.length, dst, ctx->pclustersize);
- if (ret <= 0) {
- 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 && e->length == len && ret < blksz))
+ ret = roundup(ret, blksz);
- 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);
-
- /* 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);
- } else {
- may_inline = false;
- may_packing = false;
+ /* check if there is enough gain to keep the compressed data */
+ if (ret * h->compress_threshold / 100 >= e->length) {
+ if (may_inline && len < blksz) {
+ ret = z_erofs_fill_inline_data(inode,
+ ctx->queue + ctx->head, len, true);
+ } else {
+ may_inline = false;
+ may_packing = false;
nocompression:
- ret = write_uncompressed_extent(ctx, &len, dst);
- }
+ ret = write_uncompressed_extent(ctx, &len, dst);
+ }
- if (ret < 0)
- return ret;
- ctx->e.length = ret;
+ if (ret < 0)
+ return ret;
+ e->length = ret;
- /*
- * XXX: For now, we have to leave `ctx->compressedblks
- * = 1' since there is no way to generate compressed
- * indexes after the time that ztailpacking is decided.
- */
- ctx->e.compressedblks = 1;
- ctx->e.raw = true;
- } else if (may_packing && len == ctx->e.length &&
- compressedsize < ctx->pclustersize &&
- (!inode->fragment_size || fix_dedupedfrag)) {
+ /*
+ * XXX: For now, we have to leave `ctx->compressedblk = 1'
+ * since there is no way to generate compressed indexes after
+ * the time that ztailpacking is decided.
+ */
+ e->compressedblks = 1;
+ e->raw = true;
+ } else if (may_packing && len == e->length &&
+ compressedsize < ctx->pclustersize &&
+ (!inode->fragment_size || ctx->fix_dedupedfrag)) {
frag_packing:
- ret = z_erofs_pack_fragments(inode,
- ctx->queue + ctx->head,
- len, ctx->tof_chksum);
- if (ret < 0)
- return ret;
- ctx->e.compressedblks = 0; /* indicate a fragment */
- ctx->e.raw = false;
- ctx->fragemitted = true;
- fix_dedupedfrag = false;
- /* tailpcluster should be less than 1 block */
- } else if (may_inline && len == ctx->e.length &&
- compressedsize < blksz) {
- if (ctx->clusterofs + len <= blksz) {
- inode->eof_tailraw = malloc(len);
- if (!inode->eof_tailraw)
- return -ENOMEM;
-
- memcpy(inode->eof_tailraw,
- ctx->queue + ctx->head, len);
- inode->eof_tailrawsize = len;
- }
-
- ret = z_erofs_fill_inline_data(inode, dst,
- compressedsize, false);
- if (ret < 0)
- return ret;
- ctx->e.compressedblks = 1;
- ctx->e.raw = false;
- } else {
- unsigned int tailused, padding;
+ ret = z_erofs_pack_fragments(inode, ctx->queue + ctx->head,
+ len, ctx->tof_chksum);
+ if (ret < 0)
+ return ret;
+ e->compressedblks = 0; /* indicate a fragment */
+ e->raw = false;
+ ctx->fragemitted = true;
+ /* tailpcluster should be less than 1 block */
+ } else if (may_inline && len == e->length && compressedsize < blksz) {
+ if (ctx->clusterofs + len <= blksz) {
+ inode->eof_tailraw = malloc(len);
+ if (!inode->eof_tailraw)
+ return -ENOMEM;
+
+ memcpy(inode->eof_tailraw, ctx->queue + ctx->head, len);
+ inode->eof_tailrawsize = len;
+ }
- /*
- * If there's space left for the last round when
- * deduping fragments, try to read the fragment and
- * recompress a little more to check whether it can be
- * filled up. Fix up the fragment if succeeds.
- * Otherwise, just drop it and go to packing.
- */
- if (may_packing && len == ctx->e.length &&
- (compressedsize & (blksz - 1)) &&
- ctx->tail < sizeof(ctx->queue)) {
- ctx->pclustersize =
- roundup(compressedsize, blksz);
- goto fix_dedupedfrag;
- }
+ ret = z_erofs_fill_inline_data(inode, dst,
+ compressedsize, false);
+ if (ret < 0)
+ return ret;
+ e->compressedblks = 1;
+ e->raw = false;
+ } else {
+ unsigned int tailused, padding;
- if (may_inline && len == ctx->e.length)
- tryrecompress_trailing(ctx, h,
- ctx->queue + ctx->head,
- &ctx->e.length, dst,
- &compressedsize);
+ /*
+ * If there's space left for the last round when deduping
+ * fragments, try to read the fragment and recompress a little
+ * more to check whether it can be filled up. Fix the fragment
+ * if succeeds. Otherwise, just drop it and go on packing.
+ */
+ if (may_packing && len == e->length &&
+ (compressedsize & (blksz - 1)) &&
+ ctx->tail < sizeof(ctx->queue)) {
+ ctx->pclustersize = roundup(compressedsize, blksz);
+ goto fix_dedupedfrag;
+ }
- ctx->e.compressedblks = BLK_ROUND_UP(sbi, compressedsize);
- DBG_BUGON(ctx->e.compressedblks * blksz >=
- ctx->e.length);
+ if (may_inline && len == e->length)
+ tryrecompress_trailing(ctx, h, ctx->queue + ctx->head,
+ &e->length, dst, &compressedsize);
- 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 + compressedsize, 0, padding);
- padding = 0;
- }
+ e->compressedblks = BLK_ROUND_UP(sbi, compressedsize);
+ DBG_BUGON(e->compressedblks * blksz >= e->length);
- /* write compressed data */
- erofs_dbg("Writing %u compressed data to %u of %u blocks",
- ctx->e.length, ctx->blkaddr,
- ctx->e.compressedblks);
+ padding = 0;
+ tailused = compressedsize & (blksz - 1);
+ if (tailused)
+ padding = blksz - tailused;
- ret = blk_write(sbi, dst - padding, ctx->blkaddr,
- ctx->e.compressedblks);
- if (ret)
- return ret;
- ctx->e.raw = false;
- may_inline = false;
- may_packing = false;
+ /* zero out garbage trailing data for non-0padding */
+ if (!erofs_sb_has_lz4_0padding(sbi)) {
+ memset(dst + compressedsize, 0, padding);
+ padding = 0;
}
- ctx->e.partial = false;
- ctx->e.blkaddr = ctx->blkaddr;
- if (!may_inline && !may_packing && !is_packed_inode)
- (void)z_erofs_dedupe_insert(&ctx->e,
- ctx->queue + ctx->head);
- ctx->blkaddr += ctx->e.compressedblks;
- ctx->head += ctx->e.length;
- len -= ctx->e.length;
- if (fix_dedupedfrag &&
- z_erofs_fixup_deduped_fragment(ctx, len))
- break;
+ /* write compressed data */
+ erofs_dbg("Writing %u compressed data to %u of %u blocks",
+ e->length, ctx->blkaddr, e->compressedblks);
- if (z_erofs_need_refill(ctx))
- break;
+ ret = blk_write(sbi, dst - padding, ctx->blkaddr,
+ e->compressedblks);
+ if (ret)
+ return ret;
+ e->raw = false;
+ may_inline = false;
+ may_packing = false;
}
+ e->partial = false;
+ e->blkaddr = ctx->blkaddr;
+ if (!may_inline && !may_packing && !is_packed_inode)
+ (void)z_erofs_dedupe_insert(e, ctx->queue + ctx->head);
+ ctx->blkaddr += e->compressedblks;
+ ctx->head += e->length;
return 0;
fix_dedupedfrag:
DBG_BUGON(!inode->fragment_size);
ctx->remaining += inode->fragment_size;
- ctx->e.length = 0;
+ e->length = 0;
ctx->fix_dedupedfrag = true;
+ return 1;
+}
+
+static int z_erofs_compress_one(struct z_erofs_vle_compress_ctx *ctx)
+{
+ unsigned int len = ctx->tail - ctx->head;
+ int ret;
+
+ while (len) {
+ if (z_erofs_compress_dedupe(ctx, &len))
+ break;
+
+ ret = __z_erofs_compress_one(ctx, &ctx->e);
+ if (ret) {
+ if (ret > 0)
+ break; /* need more data */
+ return ret;
+ }
+
+ len -= ctx->e.length;
+ if (ctx->fix_dedupedfrag && !ctx->fragemitted &&
+ z_erofs_fixup_deduped_fragment(ctx, len))
+ break;
+
+ if (z_erofs_need_refill(ctx))
+ break;
+ }
return 0;
}
@@ -964,7 +961,7 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd)
ctx.remaining -= rx;
ctx.tail += rx;
- ret = vle_compress_one(&ctx);
+ ret = z_erofs_compress_one(&ctx);
if (ret)
goto err_free_idata;
}
--
2.39.3
More information about the Linux-erofs
mailing list