From: Gao Xiang <hsiang...@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 <hsiang...@linux.alibaba.com> --- lib/compress.c | 172 ++++++++++++++++++++++++++++--------------------- 1 file changed, 99 insertions(+), 73 deletions(-) diff --git a/lib/compress.c b/lib/compress.c index 72f33d2..3fd3874 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 }; @@ -1030,6 +1032,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; } @@ -1044,6 +1066,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; @@ -1121,11 +1145,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; } @@ -1267,15 +1291,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; @@ -1283,11 +1305,14 @@ 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; + pthread_mutex_lock(&z_erofs_mt_ctrl.mutex); + cur = z_erofs_mt_ctrl.idle; + if (cur) { z_erofs_mt_ctrl.idle = cur->next; cur->next = NULL; - } else { + } + pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex); + if (!cur) { cur = calloc(1, sizeof(*cur)); if (!cur) return -ENOMEM; @@ -1317,14 +1342,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; @@ -1338,14 +1380,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 @@ -1355,9 +1402,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 */ @@ -1412,75 +1458,57 @@ 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) { ret = z_erofs_pack_file_from_fd(inode, fd, ctx.tof_chksum); 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); + 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; + /* allocate main data buffer */ + bh = erofs_balloc(DATA, 0, 0, 0); + if (IS_ERR(bh)) { + ret = PTR_ERR(bh); + goto err_free_idata; } + 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); - /* 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); - } - z_erofs_fragments_commit(inode); - if (!ismt) - list_splice_tail(&sctx.extents, &ctx.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; } @@ -1627,15 +1655,13 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s z_erofs_mt_enabled = false; #ifdef EROFS_MT_ENABLED - if (cfg.c_mt_workers > 1) { - pthread_mutex_init(&z_erofs_mt_ctrl.mutex, NULL); - ret = erofs_alloc_workqueue(&z_erofs_mt_ctrl.wq, - cfg.c_mt_workers, - cfg.c_mt_workers << 2, - z_erofs_mt_wq_tls_alloc, - z_erofs_mt_wq_tls_free); - z_erofs_mt_enabled = !ret; - } + pthread_mutex_init(&z_erofs_mt_ctrl.mutex, NULL); + ret = erofs_alloc_workqueue(&z_erofs_mt_ctrl.wq, + cfg.c_mt_workers, + cfg.c_mt_workers << 2, + z_erofs_mt_wq_tls_alloc, + z_erofs_mt_wq_tls_free); + z_erofs_mt_enabled = !ret; #endif return 0; } -- 2.30.2