[PATCH v2 5/8] erofs-utils: lib: split up z_erofs_mt_compress()
Gao Xiang
xiang at kernel.org
Mon Apr 22 10:34:47 AEST 2024
From: Gao Xiang <hsiangkao at 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 at 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
More information about the Linux-erofs
mailing list