From: Gao Xiang <xiang@kernel.org>
To: linux-erofs@lists.ozlabs.org
Cc: Gao Xiang <hsiangkao@linux.alibaba.com>
Subject: [PATCH v2 5/8] erofs-utils: lib: split up z_erofs_mt_compress()
Date: Mon, 22 Apr 2024 08:34:47 +0800 [thread overview]
Message-ID: <20240422003450.19132-5-xiang@kernel.org> (raw)
In-Reply-To: <20240422003450.19132-1-xiang@kernel.org>
From: Gao Xiang <hsiangkao@linux.alibaba.com>
The on-disk compressed data write will be moved into a new function
erofs_mt_write_compressed_file().
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
lib/compress.c | 162 ++++++++++++++++++++++++++++---------------------
1 file changed, 93 insertions(+), 69 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c
index 0bc5426..4ac4760 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -57,6 +57,8 @@ struct z_erofs_compress_ictx { /* inode context */
pthread_mutex_t mutex;
pthread_cond_t cond;
int nfini;
+
+ struct erofs_compress_work *mtworks;
#endif
};
@@ -530,11 +532,11 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
if (len <= ctx->pclustersize) {
if (!final || !len)
return 1;
+ if (inode->fragment_size && !ictx->fix_dedupedfrag) {
+ ctx->pclustersize = roundup(len, blksz);
+ goto fix_dedupedfrag;
+ }
if (may_packing) {
- if (inode->fragment_size && !ictx->fix_dedupedfrag) {
- ctx->pclustersize = roundup(len, blksz);
- goto fix_dedupedfrag;
- }
e->length = len;
goto frag_packing;
}
@@ -1034,6 +1036,26 @@ int z_erofs_compress_segment(struct z_erofs_compress_sctx *ctx,
z_erofs_commit_extent(ctx, ctx->pivot);
ctx->pivot = NULL;
}
+
+ /* generate an extra extent for the deduplicated fragment */
+ if (ctx->seg_idx >= ictx->seg_num - 1 &&
+ ictx->inode->fragment_size && !ictx->fragemitted) {
+ struct z_erofs_extent_item *ei;
+
+ ei = malloc(sizeof(*ei));
+ if (!ei)
+ return -ENOMEM;
+
+ ei->e = (struct z_erofs_inmem_extent) {
+ .length = ictx->inode->fragment_size,
+ .compressedblks = 0,
+ .raw = false,
+ .partial = false,
+ .blkaddr = ctx->blkaddr,
+ };
+ init_list_head(&ei->list);
+ z_erofs_commit_extent(ctx, ei);
+ }
return 0;
}
@@ -1048,6 +1070,8 @@ int erofs_commit_compressed_file(struct z_erofs_compress_ictx *ictx,
u8 *compressmeta;
int ret;
+ z_erofs_fragments_commit(inode);
+
/* fall back to no compression mode */
DBG_BUGON(compressed_blocks < !!inode->idata_size);
compressed_blocks -= !!inode->idata_size;
@@ -1125,11 +1149,11 @@ err_free_meta:
free(compressmeta);
inode->compressmeta = NULL;
err_free_idata:
+ erofs_bdrop(bh, true); /* revoke buffer */
if (inode->idata) {
free(inode->idata);
inode->idata = NULL;
}
- erofs_bdrop(bh, true); /* revoke buffer */
return ret;
}
@@ -1260,7 +1284,7 @@ int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
sctx->blkaddr += ei->e.compressedblks;
/* skip write data but leave blkaddr for inline fallback */
- if (ei->e.inlined)
+ if (ei->e.inlined || !ei->e.compressedblks)
continue;
ret2 = blk_write(sbi, sctx->membuf + blkoff * erofs_blksiz(sbi),
ei->e.blkaddr, ei->e.compressedblks);
@@ -1274,15 +1298,13 @@ int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
return ret;
}
-int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
- erofs_blk_t blkaddr,
- erofs_blk_t *compressed_blocks)
+int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx)
{
struct erofs_compress_work *cur, *head = NULL, **last = &head;
struct erofs_compress_cfg *ccfg = ictx->ccfg;
struct erofs_inode *inode = ictx->inode;
int nsegs = DIV_ROUND_UP(inode->i_size, cfg.c_segment_size);
- int ret, i;
+ int i;
ictx->seg_num = nsegs;
ictx->nfini = 0;
@@ -1290,11 +1312,12 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
pthread_cond_init(&ictx->cond, NULL);
for (i = 0; i < nsegs; i++) {
- if (z_erofs_mt_ctrl.idle) {
- cur = z_erofs_mt_ctrl.idle;
+ cur = z_erofs_mt_ctrl.idle;
+ if (cur) {
z_erofs_mt_ctrl.idle = cur->next;
cur->next = NULL;
- } else {
+ }
+ if (!cur) {
cur = calloc(1, sizeof(*cur));
if (!cur)
return -ENOMEM;
@@ -1324,14 +1347,31 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
cur->work.fn = z_erofs_mt_workfn;
erofs_queue_work(&z_erofs_mt_ctrl.wq, &cur->work);
}
+ ictx->mtworks = head;
+ return 0;
+}
+
+int erofs_mt_write_compressed_file(struct z_erofs_compress_ictx *ictx)
+{
+ struct erofs_buffer_head *bh = NULL;
+ struct erofs_compress_work *head = ictx->mtworks, *cur;
+ erofs_blk_t blkaddr, compressed_blocks = 0;
+ int ret;
pthread_mutex_lock(&ictx->mutex);
while (ictx->nfini < ictx->seg_num)
pthread_cond_wait(&ictx->cond, &ictx->mutex);
pthread_mutex_unlock(&ictx->mutex);
+ bh = erofs_balloc(DATA, 0, 0, 0);
+ if (IS_ERR(bh))
+ return PTR_ERR(bh);
+
+ DBG_BUGON(!head);
+ blkaddr = erofs_mapbh(bh->block);
+
ret = 0;
- while (head) {
+ do {
cur = head;
head = cur->next;
@@ -1345,14 +1385,19 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
if (ret2)
ret = ret2;
- *compressed_blocks += cur->ctx.blkaddr - blkaddr;
+ compressed_blocks += cur->ctx.blkaddr - blkaddr;
blkaddr = cur->ctx.blkaddr;
}
cur->next = z_erofs_mt_ctrl.idle;
z_erofs_mt_ctrl.idle = cur;
- }
- return ret;
+ } while(head);
+
+ if (ret)
+ return ret;
+
+ return erofs_commit_compressed_file(ictx, bh,
+ blkaddr - compressed_blocks, compressed_blocks);
}
#endif
@@ -1362,9 +1407,8 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
struct erofs_buffer_head *bh;
static struct z_erofs_compress_ictx ctx;
static struct z_erofs_compress_sctx sctx;
- erofs_blk_t blkaddr, compressed_blocks = 0;
+ erofs_blk_t blkaddr;
int ret;
- bool ismt = false;
struct erofs_sb_info *sbi = inode->sbi;
/* initialize per-file compression setting */
@@ -1419,14 +1463,6 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
init_list_head(&ctx.extents);
ctx.fix_dedupedfrag = false;
ctx.fragemitted = false;
- sctx = (struct z_erofs_compress_sctx) { .ictx = &ctx, };
- init_list_head(&sctx.extents);
-
- /* allocate main data buffer */
- bh = erofs_balloc(DATA, 0, 0, 0);
- if (IS_ERR(bh))
- return PTR_ERR(bh);
- blkaddr = erofs_mapbh(bh->block); /* start_blkaddr */
if (cfg.c_all_fragments && !erofs_is_packed_inode(inode) &&
!inode->fragment_size) {
@@ -1434,60 +1470,48 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
if (ret)
goto err_free_idata;
#ifdef EROFS_MT_ENABLED
- } else if (z_erofs_mt_enabled && inode->i_size > cfg.c_segment_size) {
- ismt = true;
- ret = z_erofs_mt_compress(&ctx, blkaddr, &compressed_blocks);
+ } else if (z_erofs_mt_enabled) {
+ ret = z_erofs_mt_compress(&ctx);
if (ret)
goto err_free_idata;
+ return erofs_mt_write_compressed_file(&ctx);
#endif
- } else {
- ctx.seg_num = 1;
- sctx.queue = g_queue;
- sctx.destbuf = NULL;
- sctx.chandle = &ctx.ccfg->handle;
- sctx.remaining = inode->i_size - inode->fragment_size;
- sctx.seg_idx = 0;
- sctx.pivot = &dummy_pivot;
- sctx.pclustersize = z_erofs_get_max_pclustersize(inode);
-
- ret = z_erofs_compress_segment(&sctx, -1, blkaddr);
- if (ret)
- goto err_free_idata;
- compressed_blocks = sctx.blkaddr - blkaddr;
}
-
- /* generate an extent for the deduplicated fragment */
- if (inode->fragment_size && !ctx.fragemitted) {
- struct z_erofs_extent_item *ei;
-
- ei = malloc(sizeof(*ei));
- if (!ei) {
- ret = -ENOMEM;
- goto err_free_idata;
- }
-
- ei->e = (struct z_erofs_inmem_extent) {
- .length = inode->fragment_size,
- .compressedblks = 0,
- .raw = false,
- .partial = false,
- .blkaddr = sctx.blkaddr,
- };
- init_list_head(&ei->list);
- z_erofs_commit_extent(&sctx, ei);
+ /* allocate main data buffer */
+ bh = erofs_balloc(DATA, 0, 0, 0);
+ if (IS_ERR(bh)) {
+ ret = PTR_ERR(bh);
+ goto err_free_idata;
}
- z_erofs_fragments_commit(inode);
- if (!ismt)
- list_splice_tail(&sctx.extents, &ctx.extents);
+ blkaddr = erofs_mapbh(bh->block); /* start_blkaddr */
+
+ ctx.seg_num = 1;
+ sctx = (struct z_erofs_compress_sctx) {
+ .ictx = &ctx,
+ .queue = g_queue,
+ .chandle = &ctx.ccfg->handle,
+ .remaining = inode->i_size - inode->fragment_size,
+ .seg_idx = 0,
+ .pivot = &dummy_pivot,
+ .pclustersize = z_erofs_get_max_pclustersize(inode),
+ };
+ init_list_head(&sctx.extents);
+
+ ret = z_erofs_compress_segment(&sctx, -1, blkaddr);
+ if (ret)
+ goto err_bdrop;
+ list_splice_tail(&sctx.extents, &ctx.extents);
return erofs_commit_compressed_file(&ctx, bh, blkaddr,
- compressed_blocks);
+ sctx.blkaddr - blkaddr);
+
+err_bdrop:
+ erofs_bdrop(bh, true); /* revoke buffer */
err_free_idata:
if (inode->idata) {
free(inode->idata);
inode->idata = NULL;
}
- erofs_bdrop(bh, true); /* revoke buffer */
return ret;
}
--
2.30.2
next prev parent reply other threads:[~2024-04-22 0:36 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-22 0:34 [PATCH v2 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
2024-04-22 0:34 ` [PATCH v2 2/8] erofs-utils: lib: prepare for later deferred work Gao Xiang
2024-04-22 0:34 ` [PATCH v2 3/8] erofs-utils: lib: split out erofs_commit_compressed_file() Gao Xiang
2024-04-22 0:34 ` [PATCH v2 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs Gao Xiang
2024-04-22 0:34 ` Gao Xiang [this message]
2024-04-22 0:34 ` [PATCH v2 6/8] erofs-utils: mkfs: prepare inter-file multi-threaded compression Gao Xiang
2024-04-22 0:34 ` [PATCH v2 7/8] erofs-utils: lib: introduce non-directory jobitem context Gao Xiang
2024-04-22 0:34 ` [PATCH v2 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression Gao Xiang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240422003450.19132-5-xiang@kernel.org \
--to=xiang@kernel.org \
--cc=hsiangkao@linux.alibaba.com \
--cc=linux-erofs@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.