[PATCH] erofs-utils: mkfs: speed up uncompressed data handling
Gao Xiang
hsiangkao at linux.alibaba.com
Fri Dec 20 20:39:11 AEDT 2024
Currently, it only writes one uncompressed block (typically 4 KiB) and
then tries to recompress the remaining part if the entire data was
compressed and proven to be incompressible.
This is wasteful of CPU resources and slow, as such incompressible data
could be skipped entirely.
The LZMA build time for large pclusters (e.g., 512K, 1M) can be greatly
reduced if there is a significant amount of uncompressed data.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
lib/compress.c | 53 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 46 insertions(+), 7 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c
index 65edd00..d298b8f 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -378,8 +378,8 @@ out:
return 0;
}
-static int write_uncompressed_extent(struct z_erofs_compress_sctx *ctx,
- unsigned int len, char *dst)
+static int write_uncompressed_block(struct z_erofs_compress_sctx *ctx,
+ unsigned int len, char *dst)
{
struct erofs_inode *inode = ctx->ictx->inode;
struct erofs_sb_info *sbi = inode->sbi;
@@ -414,6 +414,44 @@ static int write_uncompressed_extent(struct z_erofs_compress_sctx *ctx,
return count;
}
+static int write_uncompressed_extents(struct z_erofs_compress_sctx *ctx,
+ unsigned int size, unsigned int processed,
+ char *dst)
+{
+ struct erofs_inode *inode = ctx->ictx->inode;
+ unsigned int lclustersize = 1 << inode->z_logical_clusterbits;
+ struct z_erofs_extent_item *ei;
+ int count;
+
+ while (1) {
+ count = write_uncompressed_block(ctx, size, dst);
+ if (count < 0)
+ return count;
+
+ size -= count;
+ if (processed < lclustersize + count)
+ break;
+ processed -= count;
+
+ ei = malloc(sizeof(*ei));
+ if (!ei)
+ return -ENOMEM;
+ init_list_head(&ei->list);
+
+ ei->e = (struct z_erofs_inmem_extent) {
+ .length = count,
+ .compressedblks = BLK_ROUND_UP(inode->sbi, count),
+ .raw = true,
+ .blkaddr = ctx->blkaddr,
+ };
+ if (ctx->blkaddr != EROFS_NULL_ADDR)
+ ctx->blkaddr += ei->e.compressedblks;
+ z_erofs_commit_extent(ctx, ei);
+ ctx->head += count;
+ }
+ return count;
+}
+
static unsigned int z_erofs_get_max_pclustersize(struct erofs_inode *inode)
{
if (erofs_is_packed_inode(inode)) {
@@ -536,6 +574,7 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
unsigned int compressedsize;
int ret;
+ DBG_BUGON(ctx->pivot);
*e = (struct z_erofs_inmem_extent){};
if (len <= ctx->pclustersize) {
if (!final || !len)
@@ -579,7 +618,8 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
may_packing = false;
nocompression:
/* TODO: reset clusterofs to 0 if permitted */
- ret = write_uncompressed_extent(ctx, len, dst);
+ ret = write_uncompressed_extents(ctx, len,
+ min_t(u32, e->length, ret), dst);
if (ret < 0)
return ret;
}
@@ -706,17 +746,16 @@ static int z_erofs_compress_one(struct z_erofs_compress_sctx *ctx)
while (len) {
int ret = z_erofs_compress_dedupe(ctx, &len);
+ if (ret < 0)
+ return ret;
if (ret > 0)
break;
- else if (ret < 0)
- return ret;
- DBG_BUGON(ctx->pivot);
ei = malloc(sizeof(*ei));
if (!ei)
return -ENOMEM;
-
init_list_head(&ei->list);
+
ret = __z_erofs_compress_one(ctx, &ei->e);
if (ret) {
free(ei);
--
2.43.5
More information about the Linux-erofs
mailing list