* [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count
@ 2024-04-16 8:04 Gao Xiang
2024-04-16 8:04 ` [PATCH 2/8] erofs-utils: lib: prepare for later deferred work Gao Xiang
` (6 more replies)
0 siblings, 7 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
From: Gao Xiang <hsiangkao@linux.alibaba.com>
Since it can be touched for more than one thread if multi-threading
is enabled.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
include/erofs/atomic.h | 10 ++++++++++
include/erofs/inode.h | 2 +-
include/erofs/internal.h | 3 ++-
lib/inode.c | 5 +++--
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/erofs/atomic.h b/include/erofs/atomic.h
index 214cdb1..f28687e 100644
--- a/include/erofs/atomic.h
+++ b/include/erofs/atomic.h
@@ -25,4 +25,14 @@ __n;})
#define erofs_atomic_test_and_set(ptr) \
__atomic_test_and_set(ptr, __ATOMIC_RELAXED)
+#define erofs_atomic_add_return(ptr, i) \
+ __atomic_add_fetch(ptr, i, __ATOMIC_RELAXED)
+
+#define erofs_atomic_sub_return(ptr, i) \
+ __atomic_sub_fetch(ptr, i, __ATOMIC_RELAXED)
+
+#define erofs_atomic_inc_return(ptr) erofs_atomic_add_return(ptr, 1)
+
+#define erofs_atomic_dec_return(ptr) erofs_atomic_sub_return(ptr, 1)
+
#endif
diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index d5a732a..5d6bc98 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -17,7 +17,7 @@ extern "C"
static inline struct erofs_inode *erofs_igrab(struct erofs_inode *inode)
{
- ++inode->i_count;
+ (void)erofs_atomic_inc_return(&inode->i_count);
return inode;
}
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 4cd2059..f31e548 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -25,6 +25,7 @@ typedef unsigned short umode_t;
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
+#include "atomic.h"
#ifndef PATH_MAX
#define PATH_MAX 4096 /* # chars in a path name including nul */
@@ -169,7 +170,7 @@ struct erofs_inode {
/* (mkfs.erofs) next pointer for directory dumping */
struct erofs_inode *next_dirwrite;
};
- unsigned int i_count;
+ erofs_atomic_t i_count;
struct erofs_sb_info *sbi;
struct erofs_inode *i_parent;
diff --git a/lib/inode.c b/lib/inode.c
index 7508c74..55969d9 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -129,9 +129,10 @@ struct erofs_inode *erofs_iget_by_nid(erofs_nid_t nid)
unsigned int erofs_iput(struct erofs_inode *inode)
{
struct erofs_dentry *d, *t;
+ unsigned long got = erofs_atomic_dec_return(&inode->i_count);
- if (inode->i_count > 1)
- return --inode->i_count;
+ if (got >= 1)
+ return got;
list_for_each_entry_safe(d, t, &inode->i_subdirs, d_child)
free(d);
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/8] erofs-utils: lib: prepare for later deferred work
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 11:58 ` Yifan Zhao
2024-04-16 8:04 ` [PATCH 3/8] erofs-utils: lib: split out erofs_commit_compressed_file() Gao Xiang
` (5 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
From: Gao Xiang <hsiangkao@linux.alibaba.com>
Split out ordered metadata operations and add the following helpers:
- erofs_mkfs_jobfn()
- erofs_mkfs_go()
to handle these mkfs job items for multi-threadding support.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
lib/inode.c | 68 +++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 58 insertions(+), 10 deletions(-)
diff --git a/lib/inode.c b/lib/inode.c
index 55969d9..8ef0604 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1133,6 +1133,57 @@ static int erofs_mkfs_handle_nondirectory(struct erofs_inode *inode)
return 0;
}
+enum erofs_mkfs_jobtype { /* ordered job types */
+ EROFS_MKFS_JOB_NDIR,
+ EROFS_MKFS_JOB_DIR,
+ EROFS_MKFS_JOB_DIR_BH,
+};
+
+struct erofs_mkfs_jobitem {
+ enum erofs_mkfs_jobtype type;
+ union {
+ struct erofs_inode *inode;
+ } u;
+};
+
+static int erofs_mkfs_jobfn(struct erofs_mkfs_jobitem *item)
+{
+ struct erofs_inode *inode = item->u.inode;
+ int ret;
+
+ if (item->type == EROFS_MKFS_JOB_NDIR)
+ return erofs_mkfs_handle_nondirectory(inode);
+
+ if (item->type == EROFS_MKFS_JOB_DIR) {
+ ret = erofs_prepare_inode_buffer(inode);
+ if (ret)
+ return ret;
+ inode->bh->op = &erofs_skip_write_bhops;
+ if (IS_ROOT(inode))
+ erofs_fixup_meta_blkaddr(inode);
+ return 0;
+ }
+
+ if (item->type == EROFS_MKFS_JOB_DIR_BH) {
+ erofs_write_dir_file(inode);
+ erofs_write_tail_end(inode);
+ inode->bh->op = &erofs_write_inode_bhops;
+ erofs_iput(inode);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int erofs_mkfs_go(struct erofs_sb_info *sbi,
+ enum erofs_mkfs_jobtype type, void *elem, int size)
+{
+ struct erofs_mkfs_jobitem item;
+
+ item.type = type;
+ memcpy(&item.u, elem, size);
+ return erofs_mkfs_jobfn(&item);
+}
+
static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
{
DIR *_dir;
@@ -1213,11 +1264,7 @@ static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
else
dir->i_nlink = i_nlink;
- ret = erofs_prepare_inode_buffer(dir);
- if (ret)
- return ret;
- dir->bh->op = &erofs_skip_write_bhops;
- return 0;
+ return erofs_mkfs_go(dir->sbi, EROFS_MKFS_JOB_DIR, &dir, sizeof(dir));
err_closedir:
closedir(_dir);
@@ -1243,7 +1290,8 @@ static int erofs_mkfs_handle_inode(struct erofs_inode *inode)
return ret;
if (!S_ISDIR(inode->i_mode))
- ret = erofs_mkfs_handle_nondirectory(inode);
+ ret = erofs_mkfs_go(inode->sbi, EROFS_MKFS_JOB_NDIR,
+ &inode, sizeof(inode));
else
ret = erofs_mkfs_handle_directory(inode);
erofs_info("file %s dumped (mode %05o)", erofs_fspath(inode->i_srcpath),
@@ -1302,10 +1350,10 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
}
*last = dumpdir; /* fixup the last (or the only) one */
dumpdir = head;
- erofs_write_dir_file(dir);
- erofs_write_tail_end(dir);
- dir->bh->op = &erofs_write_inode_bhops;
- erofs_iput(dir);
+ err = erofs_mkfs_go(dir->sbi, EROFS_MKFS_JOB_DIR_BH,
+ &dir, sizeof(dir));
+ if (err)
+ return ERR_PTR(err);
} while (dumpdir);
return root;
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/8] erofs-utils: lib: split out erofs_commit_compressed_file()
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
2024-04-16 8:04 ` [PATCH 2/8] erofs-utils: lib: prepare for later deferred work Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 8:04 ` [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs Gao Xiang
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
From: Gao Xiang <hsiangkao@linux.alibaba.com>
Just split out on-disk compressed metadata commit logic.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
lib/compress.c | 191 +++++++++++++++++++++++++++----------------------
1 file changed, 105 insertions(+), 86 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c
index 74c5707..a2e0d0f 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -1026,6 +1026,102 @@ int z_erofs_compress_segment(struct z_erofs_compress_sctx *ctx,
return 0;
}
+int erofs_commit_compressed_file(struct z_erofs_compress_ictx *ictx,
+ struct erofs_buffer_head *bh,
+ erofs_blk_t blkaddr,
+ erofs_blk_t compressed_blocks)
+{
+ struct erofs_inode *inode = ictx->inode;
+ struct erofs_sb_info *sbi = inode->sbi;
+ unsigned int legacymetasize;
+ u8 *compressmeta;
+ int ret;
+
+ /* fall back to no compression mode */
+ DBG_BUGON(compressed_blocks < !!inode->idata_size);
+ compressed_blocks -= !!inode->idata_size;
+
+ compressmeta = malloc(BLK_ROUND_UP(sbi, inode->i_size) *
+ sizeof(struct z_erofs_lcluster_index) +
+ Z_EROFS_LEGACY_MAP_HEADER_SIZE);
+ if (!compressmeta) {
+ ret = -ENOMEM;
+ goto err_free_idata;
+ }
+ ictx->metacur = compressmeta + Z_EROFS_LEGACY_MAP_HEADER_SIZE;
+ z_erofs_write_indexes(ictx);
+
+ legacymetasize = ictx->metacur - compressmeta;
+ /* estimate if data compression saves space or not */
+ if (!inode->fragment_size &&
+ compressed_blocks * erofs_blksiz(sbi) + inode->idata_size +
+ legacymetasize >= inode->i_size) {
+ z_erofs_dedupe_commit(true);
+ ret = -ENOSPC;
+ goto err_free_meta;
+ }
+ z_erofs_dedupe_commit(false);
+ z_erofs_write_mapheader(inode, compressmeta);
+
+ if (!ictx->fragemitted)
+ sbi->saved_by_deduplication += inode->fragment_size;
+
+ /* if the entire file is a fragment, a simplified form is used. */
+ if (inode->i_size <= inode->fragment_size) {
+ DBG_BUGON(inode->i_size < inode->fragment_size);
+ DBG_BUGON(inode->fragmentoff >> 63);
+ *(__le64 *)compressmeta =
+ cpu_to_le64(inode->fragmentoff | 1ULL << 63);
+ inode->datalayout = EROFS_INODE_COMPRESSED_FULL;
+ legacymetasize = Z_EROFS_LEGACY_MAP_HEADER_SIZE;
+ }
+
+ if (compressed_blocks) {
+ ret = erofs_bh_balloon(bh, erofs_pos(sbi, compressed_blocks));
+ DBG_BUGON(ret != erofs_blksiz(sbi));
+ } else {
+ if (!cfg.c_fragments && !cfg.c_dedupe)
+ DBG_BUGON(!inode->idata_size);
+ }
+
+ erofs_info("compressed %s (%llu bytes) into %u blocks",
+ inode->i_srcpath, (unsigned long long)inode->i_size,
+ compressed_blocks);
+
+ if (inode->idata_size) {
+ bh->op = &erofs_skip_write_bhops;
+ inode->bh_data = bh;
+ } else {
+ erofs_bdrop(bh, false);
+ }
+
+ inode->u.i_blocks = compressed_blocks;
+
+ if (inode->datalayout == EROFS_INODE_COMPRESSED_FULL) {
+ inode->extent_isize = legacymetasize;
+ } else {
+ ret = z_erofs_convert_to_compacted_format(inode, blkaddr,
+ legacymetasize,
+ compressmeta);
+ DBG_BUGON(ret);
+ }
+ inode->compressmeta = compressmeta;
+ if (!erofs_is_packed_inode(inode))
+ erofs_droid_blocklist_write(inode, blkaddr, compressed_blocks);
+ return 0;
+
+err_free_meta:
+ free(compressmeta);
+ inode->compressmeta = NULL;
+err_free_idata:
+ if (inode->idata) {
+ free(inode->idata);
+ inode->idata = NULL;
+ }
+ erofs_bdrop(bh, true); /* revoke buffer */
+ return ret;
+}
+
#ifdef EROFS_MT_ENABLED
void *z_erofs_mt_wq_tls_alloc(struct erofs_workqueue *wq, void *ptr)
{
@@ -1252,23 +1348,9 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
static struct z_erofs_compress_sctx sctx;
struct erofs_compress_cfg *ccfg;
erofs_blk_t blkaddr, compressed_blocks = 0;
- unsigned int legacymetasize;
int ret;
bool ismt = false;
struct erofs_sb_info *sbi = inode->sbi;
- u8 *compressmeta = malloc(BLK_ROUND_UP(sbi, inode->i_size) *
- sizeof(struct z_erofs_lcluster_index) +
- Z_EROFS_LEGACY_MAP_HEADER_SIZE);
-
- if (!compressmeta)
- return -ENOMEM;
-
- /* allocate main data buffer */
- bh = erofs_balloc(DATA, 0, 0, 0);
- if (IS_ERR(bh)) {
- ret = PTR_ERR(bh);
- goto err_free_meta;
- }
/* initialize per-file compression setting */
inode->z_advise = 0;
@@ -1313,20 +1395,24 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
if (cfg.c_fragments && !erofs_is_packed_inode(inode)) {
ret = z_erofs_fragments_dedupe(inode, fd, &ctx.tof_chksum);
if (ret < 0)
- goto err_bdrop;
+ return ret;
}
- blkaddr = erofs_mapbh(bh->block); /* start_blkaddr */
ctx.inode = inode;
ctx.fd = fd;
ctx.fpos = fpos;
- ctx.metacur = compressmeta + Z_EROFS_LEGACY_MAP_HEADER_SIZE;
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);
@@ -1355,10 +1441,6 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
compressed_blocks = sctx.blkaddr - blkaddr;
}
- /* fall back to no compression mode */
- DBG_BUGON(compressed_blocks < !!inode->idata_size);
- compressed_blocks -= !!inode->idata_size;
-
/* generate an extent for the deduplicated fragment */
if (inode->fragment_size && !ctx.fragemitted) {
struct z_erofs_extent_item *ei;
@@ -1380,80 +1462,17 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
z_erofs_commit_extent(&sctx, ei);
}
z_erofs_fragments_commit(inode);
-
if (!ismt)
list_splice_tail(&sctx.extents, &ctx.extents);
- z_erofs_write_indexes(&ctx);
- legacymetasize = ctx.metacur - compressmeta;
- /* estimate if data compression saves space or not */
- if (!inode->fragment_size &&
- compressed_blocks * erofs_blksiz(sbi) + inode->idata_size +
- legacymetasize >= inode->i_size) {
- z_erofs_dedupe_commit(true);
- ret = -ENOSPC;
- goto err_free_idata;
- }
- z_erofs_dedupe_commit(false);
- z_erofs_write_mapheader(inode, compressmeta);
-
- if (!ctx.fragemitted)
- sbi->saved_by_deduplication += inode->fragment_size;
-
- /* if the entire file is a fragment, a simplified form is used. */
- if (inode->i_size <= inode->fragment_size) {
- DBG_BUGON(inode->i_size < inode->fragment_size);
- DBG_BUGON(inode->fragmentoff >> 63);
- *(__le64 *)compressmeta =
- cpu_to_le64(inode->fragmentoff | 1ULL << 63);
- inode->datalayout = EROFS_INODE_COMPRESSED_FULL;
- legacymetasize = Z_EROFS_LEGACY_MAP_HEADER_SIZE;
- }
-
- if (compressed_blocks) {
- ret = erofs_bh_balloon(bh, erofs_pos(sbi, compressed_blocks));
- DBG_BUGON(ret != erofs_blksiz(sbi));
- } else {
- if (!cfg.c_fragments && !cfg.c_dedupe)
- DBG_BUGON(!inode->idata_size);
- }
-
- erofs_info("compressed %s (%llu bytes) into %u blocks",
- inode->i_srcpath, (unsigned long long)inode->i_size,
- compressed_blocks);
-
- if (inode->idata_size) {
- bh->op = &erofs_skip_write_bhops;
- inode->bh_data = bh;
- } else {
- erofs_bdrop(bh, false);
- }
-
- inode->u.i_blocks = compressed_blocks;
-
- if (inode->datalayout == EROFS_INODE_COMPRESSED_FULL) {
- inode->extent_isize = legacymetasize;
- } else {
- ret = z_erofs_convert_to_compacted_format(inode, blkaddr,
- legacymetasize,
- compressmeta);
- DBG_BUGON(ret);
- }
- inode->compressmeta = compressmeta;
- if (!erofs_is_packed_inode(inode))
- erofs_droid_blocklist_write(inode, blkaddr, compressed_blocks);
- return 0;
-
+ return erofs_commit_compressed_file(&ctx, bh, blkaddr,
+ compressed_blocks);
err_free_idata:
if (inode->idata) {
free(inode->idata);
inode->idata = NULL;
}
-err_bdrop:
erofs_bdrop(bh, true); /* revoke buffer */
-err_free_meta:
- free(compressmeta);
- inode->compressmeta = NULL;
return ret;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
2024-04-16 8:04 ` [PATCH 2/8] erofs-utils: lib: prepare for later deferred work Gao Xiang
2024-04-16 8:04 ` [PATCH 3/8] erofs-utils: lib: split out erofs_commit_compressed_file() Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 11:55 ` Yifan Zhao
2024-04-16 8:04 ` [PATCH 5/8] erofs-utils: lib: split up z_erofs_mt_compress() Gao Xiang
` (3 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
From: Gao Xiang <hsiangkao@linux.alibaba.com>
They should be located in `struct z_erofs_compress_ictx`.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
lib/compress.c | 55 ++++++++++++++++++++++++++++----------------------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c
index a2e0d0f..72f33d2 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -38,6 +38,7 @@ struct z_erofs_extent_item {
struct z_erofs_compress_ictx { /* inode context */
struct erofs_inode *inode;
+ struct erofs_compress_cfg *ccfg;
int fd;
u64 fpos;
@@ -49,6 +50,14 @@ struct z_erofs_compress_ictx { /* inode context */
u8 *metacur;
struct list_head extents;
u16 clusterofs;
+
+ int seg_num;
+
+#if EROFS_MT_ENABLED
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int nfini;
+#endif
};
struct z_erofs_compress_sctx { /* segment context */
@@ -68,7 +77,7 @@ struct z_erofs_compress_sctx { /* segment context */
erofs_blk_t blkaddr; /* pointing to the next blkaddr */
u16 clusterofs;
- int seg_num, seg_idx;
+ int seg_idx;
void *membuf;
erofs_off_t memoff;
@@ -99,8 +108,6 @@ static struct {
struct erofs_workqueue wq;
struct erofs_compress_work *idle;
pthread_mutex_t mutex;
- pthread_cond_t cond;
- int nfini;
} z_erofs_mt_ctrl;
#endif
@@ -512,7 +519,7 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
struct erofs_compress *const h = ctx->chandle;
unsigned int len = ctx->tail - ctx->head;
bool is_packed_inode = erofs_is_packed_inode(inode);
- bool tsg = (ctx->seg_idx + 1 >= ctx->seg_num), final = !ctx->remaining;
+ bool tsg = (ctx->seg_idx + 1 >= ictx->seg_num), final = !ctx->remaining;
bool may_packing = (cfg.c_fragments && tsg && final &&
!is_packed_inode && !z_erofs_mt_enabled);
bool may_inline = (cfg.c_ztailpacking && tsg && final && !may_packing);
@@ -1196,7 +1203,8 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp)
struct erofs_compress_work *cwork = (struct erofs_compress_work *)work;
struct erofs_compress_wq_tls *tls = tlsp;
struct z_erofs_compress_sctx *sctx = &cwork->ctx;
- struct erofs_inode *inode = sctx->ictx->inode;
+ struct z_erofs_compress_ictx *ictx = sctx->ictx;
+ struct erofs_inode *inode = ictx->inode;
struct erofs_sb_info *sbi = inode->sbi;
int ret = 0;
@@ -1223,10 +1231,10 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp)
out:
cwork->errcode = ret;
- pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
- ++z_erofs_mt_ctrl.nfini;
- pthread_cond_signal(&z_erofs_mt_ctrl.cond);
- pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
+ pthread_mutex_lock(&ictx->mutex);
+ ++ictx->nfini;
+ pthread_cond_signal(&ictx->cond);
+ pthread_mutex_unlock(&ictx->mutex);
}
int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
@@ -1260,16 +1268,19 @@ int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
}
int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
- struct erofs_compress_cfg *ccfg,
erofs_blk_t blkaddr,
erofs_blk_t *compressed_blocks)
{
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;
- z_erofs_mt_ctrl.nfini = 0;
+ ictx->seg_num = nsegs;
+ ictx->nfini = 0;
+ pthread_mutex_init(&ictx->mutex, NULL);
+ pthread_cond_init(&ictx->cond, NULL);
for (i = 0; i < nsegs; i++) {
if (z_erofs_mt_ctrl.idle) {
@@ -1286,7 +1297,6 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
cur->ctx = (struct z_erofs_compress_sctx) {
.ictx = ictx,
- .seg_num = nsegs,
.seg_idx = i,
.pivot = &dummy_pivot,
};
@@ -1308,11 +1318,10 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
erofs_queue_work(&z_erofs_mt_ctrl.wq, &cur->work);
}
- pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
- while (z_erofs_mt_ctrl.nfini != nsegs)
- pthread_cond_wait(&z_erofs_mt_ctrl.cond,
- &z_erofs_mt_ctrl.mutex);
- pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
+ pthread_mutex_lock(&ictx->mutex);
+ while (ictx->nfini < ictx->seg_num)
+ pthread_cond_wait(&ictx->cond, &ictx->mutex);
+ pthread_mutex_unlock(&ictx->mutex);
ret = 0;
while (head) {
@@ -1346,7 +1355,6 @@ 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;
- struct erofs_compress_cfg *ccfg;
erofs_blk_t blkaddr, compressed_blocks = 0;
int ret;
bool ismt = false;
@@ -1381,8 +1389,8 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
}
}
#endif
- ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
- inode->z_algorithmtype[0] = ccfg[0].algorithmtype;
+ ctx.ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
+ inode->z_algorithmtype[0] = ctx.ccfg->algorithmtype;
inode->z_algorithmtype[1] = 0;
inode->idata_size = 0;
@@ -1421,16 +1429,16 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
#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, ccfg, blkaddr, &compressed_blocks);
+ ret = z_erofs_mt_compress(&ctx, blkaddr, &compressed_blocks);
if (ret)
goto err_free_idata;
#endif
} else {
+ ctx.seg_num = 1;
sctx.queue = g_queue;
sctx.destbuf = NULL;
- sctx.chandle = &ccfg->handle;
+ sctx.chandle = &ctx.ccfg->handle;
sctx.remaining = inode->i_size - inode->fragment_size;
- sctx.seg_num = 1;
sctx.seg_idx = 0;
sctx.pivot = &dummy_pivot;
sctx.pclustersize = z_erofs_get_max_pclustersize(inode);
@@ -1621,7 +1629,6 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
#ifdef EROFS_MT_ENABLED
if (cfg.c_mt_workers > 1) {
pthread_mutex_init(&z_erofs_mt_ctrl.mutex, NULL);
- pthread_cond_init(&z_erofs_mt_ctrl.cond, NULL);
ret = erofs_alloc_workqueue(&z_erofs_mt_ctrl.wq,
cfg.c_mt_workers,
cfg.c_mt_workers << 2,
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/8] erofs-utils: lib: split up z_erofs_mt_compress()
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
` (2 preceding siblings ...)
2024-04-16 8:04 ` [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 8:04 ` [PATCH 6/8] erofs-utils: mkfs: prepare inter-file multi-threaded compression Gao Xiang
` (2 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
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 | 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
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/8] erofs-utils: mkfs: prepare inter-file multi-threaded compression
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
` (3 preceding siblings ...)
2024-04-16 8:04 ` [PATCH 5/8] erofs-utils: lib: split up z_erofs_mt_compress() Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 8:04 ` [PATCH 7/8] erofs-utils: lib: introduce non-directory jobitem context Gao Xiang
2024-04-16 8:04 ` [PATCH 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression Gao Xiang
6 siblings, 0 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao, Tong Xin
From: Yifan Zhao <zhaoyifan@sjtu.edu.cn>
This patch separate compression process into two parts.
Specifically, erofs_begin_compressed_file() will trigger compression.
erofs_write_compressed_file() will wait for compression finish and
write compressed (meta)data.
Signed-off-by: Yifan Zhao <zhaoyifan@sjtu.edu.cn>
Co-authored-by: Tong Xin <xin_tong@sjtu.edu.cn>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
include/erofs/compress.h | 5 +-
lib/compress.c | 115 ++++++++++++++++++++++++++-------------
lib/inode.c | 17 +++++-
3 files changed, 95 insertions(+), 42 deletions(-)
diff --git a/include/erofs/compress.h b/include/erofs/compress.h
index 871db54..c9831a7 100644
--- a/include/erofs/compress.h
+++ b/include/erofs/compress.h
@@ -17,8 +17,11 @@ extern "C"
#define EROFS_CONFIG_COMPR_MAX_SZ (4000 * 1024)
#define Z_EROFS_COMPR_QUEUE_SZ (EROFS_CONFIG_COMPR_MAX_SZ * 2)
+struct z_erofs_compress_ictx;
+
void z_erofs_drop_inline_pcluster(struct erofs_inode *inode);
-int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos);
+void *erofs_begin_compressed_file(struct erofs_inode *inode, int fd, u64 fpos);
+int erofs_write_compressed_file(struct z_erofs_compress_ictx *ictx);
int z_erofs_compress_init(struct erofs_sb_info *sbi,
struct erofs_buffer_head *bh);
diff --git a/lib/compress.c b/lib/compress.c
index 3fd3874..45ff128 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -1359,8 +1359,10 @@ int erofs_mt_write_compressed_file(struct z_erofs_compress_ictx *ictx)
pthread_mutex_unlock(&ictx->mutex);
bh = erofs_balloc(DATA, 0, 0, 0);
- if (IS_ERR(bh))
- return PTR_ERR(bh);
+ if (IS_ERR(bh)) {
+ ret = PTR_ERR(bh);
+ goto out;
+ }
DBG_BUGON(!head);
blkaddr = erofs_mapbh(bh->block);
@@ -1384,27 +1386,31 @@ int erofs_mt_write_compressed_file(struct z_erofs_compress_ictx *ictx)
blkaddr = cur->ctx.blkaddr;
}
+ pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
cur->next = z_erofs_mt_ctrl.idle;
z_erofs_mt_ctrl.idle = cur;
- } while(head);
+ pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
+ } while (head);
if (ret)
- return ret;
-
- return erofs_commit_compressed_file(ictx, bh,
+ goto out;
+ ret = erofs_commit_compressed_file(ictx, bh,
blkaddr - compressed_blocks, compressed_blocks);
+
+out:
+ close(ictx->fd);
+ free(ictx);
+ return ret;
}
#endif
-int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
+static struct z_erofs_compress_ictx g_ictx;
+
+void *erofs_begin_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
{
- static u8 g_queue[Z_EROFS_COMPR_QUEUE_SZ];
- struct erofs_buffer_head *bh;
- static struct z_erofs_compress_ictx ctx;
- static struct z_erofs_compress_sctx sctx;
- erofs_blk_t blkaddr;
- int ret;
struct erofs_sb_info *sbi = inode->sbi;
+ struct z_erofs_compress_ictx *ictx;
+ int ret;
/* initialize per-file compression setting */
inode->z_advise = 0;
@@ -1435,45 +1441,79 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
}
}
#endif
- ctx.ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
- inode->z_algorithmtype[0] = ctx.ccfg->algorithmtype;
- inode->z_algorithmtype[1] = 0;
-
inode->idata_size = 0;
inode->fragment_size = 0;
+ if (z_erofs_mt_enabled) {
+ ictx = malloc(sizeof(*ictx));
+ if (!ictx)
+ return ERR_PTR(-ENOMEM);
+ ictx->fd = dup(fd);
+ } else {
+ ictx = &g_ictx;
+ ictx->fd = fd;
+ }
+
+ ictx->ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
+ inode->z_algorithmtype[0] = ictx->ccfg->algorithmtype;
+ inode->z_algorithmtype[1] = 0;
+
/*
* Handle tails in advance to avoid writing duplicated
* parts into the packed inode.
*/
if (cfg.c_fragments && !erofs_is_packed_inode(inode)) {
- ret = z_erofs_fragments_dedupe(inode, fd, &ctx.tof_chksum);
+ ret = z_erofs_fragments_dedupe(inode, fd, &ictx->tof_chksum);
if (ret < 0)
- return ret;
+ goto err_free_ictx;
}
- ctx.inode = inode;
- ctx.fd = fd;
- ctx.fpos = fpos;
- init_list_head(&ctx.extents);
- ctx.fix_dedupedfrag = false;
- ctx.fragemitted = false;
+ ictx->inode = inode;
+ ictx->fpos = fpos;
+ init_list_head(&ictx->extents);
+ ictx->fix_dedupedfrag = false;
+ ictx->fragemitted = false;
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);
+ ret = z_erofs_pack_file_from_fd(inode, fd, ictx->tof_chksum);
if (ret)
goto err_free_idata;
- }
#ifdef EROFS_MT_ENABLED
- if (z_erofs_mt_enabled) {
- ret = z_erofs_mt_compress(&ctx);
+ } else if (ictx != &g_ictx) {
+ ret = z_erofs_mt_compress(ictx);
if (ret)
goto err_free_idata;
- return erofs_mt_write_compressed_file(&ctx);
+#endif
+ }
+ return ictx;
+err_free_idata:
+ if (inode->idata) {
+ free(inode->idata);
+ inode->idata = NULL;
}
+err_free_ictx:
+ if (ictx != &g_ictx)
+ free(ictx);
+ return ERR_PTR(ret);
+}
+
+int erofs_write_compressed_file(struct z_erofs_compress_ictx *ictx)
+{
+ static u8 g_queue[Z_EROFS_COMPR_QUEUE_SZ];
+ struct erofs_buffer_head *bh;
+ static struct z_erofs_compress_sctx sctx;
+ struct erofs_compress_cfg *ccfg = ictx->ccfg;
+ struct erofs_inode *inode = ictx->inode;
+ erofs_blk_t blkaddr;
+ int ret;
+
+#ifdef EROFS_MT_ENABLED
+ if (ictx != &g_ictx)
+ return erofs_mt_write_compressed_file(ictx);
#endif
+
/* allocate main data buffer */
bh = erofs_balloc(DATA, 0, 0, 0);
if (IS_ERR(bh)) {
@@ -1482,11 +1522,11 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
}
blkaddr = erofs_mapbh(bh->block); /* start_blkaddr */
- ctx.seg_num = 1;
+ ictx->seg_num = 1;
sctx = (struct z_erofs_compress_sctx) {
- .ictx = &ctx,
+ .ictx = ictx,
.queue = g_queue,
- .chandle = &ctx.ccfg->handle,
+ .chandle = &ccfg->handle,
.remaining = inode->i_size - inode->fragment_size,
.seg_idx = 0,
.pivot = &dummy_pivot,
@@ -1496,15 +1536,14 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
ret = z_erofs_compress_segment(&sctx, -1, blkaddr);
if (ret)
- goto err_bdrop;
- list_splice_tail(&sctx.extents, &ctx.extents);
+ goto err_free_idata;
- return erofs_commit_compressed_file(&ctx, bh, blkaddr,
+ list_splice_tail(&sctx.extents, &ictx->extents);
+ return erofs_commit_compressed_file(ictx, bh, blkaddr,
sctx.blkaddr - blkaddr);
-err_bdrop:
- erofs_bdrop(bh, true); /* revoke buffer */
err_free_idata:
+ erofs_bdrop(bh, true); /* revoke buffer */
if (inode->idata) {
free(inode->idata);
inode->idata = NULL;
diff --git a/lib/inode.c b/lib/inode.c
index 8ef0604..66eacab 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -499,10 +499,15 @@ int erofs_write_file(struct erofs_inode *inode, int fd, u64 fpos)
DBG_BUGON(!inode->i_size);
if (cfg.c_compr_opts[0].alg && erofs_file_is_compressible(inode)) {
+ void *ictx;
int ret;
- ret = erofs_write_compressed_file(inode, fd, fpos);
- if (!ret || ret != -ENOSPC)
+ ictx = erofs_begin_compressed_file(inode, fd, fpos);
+ if (IS_ERR(ictx))
+ return PTR_ERR(ictx);
+
+ ret = erofs_write_compressed_file(ictx);
+ if (ret != -ENOSPC)
return ret;
if (lseek(fd, fpos, SEEK_SET) < 0)
@@ -1363,6 +1368,7 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(int fd, const char *name)
{
struct stat st;
struct erofs_inode *inode;
+ void *ictx;
int ret;
ret = lseek(fd, 0, SEEK_SET);
@@ -1393,7 +1399,12 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(int fd, const char *name)
inode->nid = inode->sbi->packed_nid;
}
- ret = erofs_write_compressed_file(inode, fd, 0);
+ ictx = erofs_begin_compressed_file(inode, fd, 0);
+ if (IS_ERR(ictx))
+ return ERR_CAST(ictx);
+
+ DBG_BUGON(!ictx);
+ ret = erofs_write_compressed_file(ictx);
if (ret == -ENOSPC) {
ret = lseek(fd, 0, SEEK_SET);
if (ret < 0)
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/8] erofs-utils: lib: introduce non-directory jobitem context
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
` (4 preceding siblings ...)
2024-04-16 8:04 ` [PATCH 6/8] erofs-utils: mkfs: prepare inter-file multi-threaded compression Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 8:04 ` [PATCH 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression Gao Xiang
6 siblings, 0 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
From: Gao Xiang <hsiangkao@linux.alibaba.com>
It will describe EROFS_MKFS_JOB_NDIR defer work. Also start
compression before queueing EROFS_MKFS_JOB_NDIR.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
lib/inode.c | 62 +++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 11 deletions(-)
diff --git a/lib/inode.c b/lib/inode.c
index 66eacab..681460c 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1107,8 +1107,36 @@ static void erofs_fixup_meta_blkaddr(struct erofs_inode *rootdir)
rootdir->nid = (off - meta_offset) >> EROFS_ISLOTBITS;
}
-static int erofs_mkfs_handle_nondirectory(struct erofs_inode *inode)
+struct erofs_mkfs_job_ndir_ctx {
+ struct erofs_inode *inode;
+ void *ictx;
+ int fd;
+};
+
+static int erofs_mkfs_job_write_file(struct erofs_mkfs_job_ndir_ctx *ctx)
{
+ struct erofs_inode *inode = ctx->inode;
+ int ret;
+
+ if (ctx->ictx) {
+ ret = erofs_write_compressed_file(ctx->ictx);
+ if (ret != -ENOSPC)
+ goto out;
+ if (lseek(ctx->fd, 0, SEEK_SET) < 0) {
+ ret = -errno;
+ goto out;
+ }
+ }
+ /* fallback to all data uncompressed */
+ ret = erofs_write_unencoded_file(inode, ctx->fd, 0);
+out:
+ close(ctx->fd);
+ return ret;
+}
+
+static int erofs_mkfs_handle_nondirectory(struct erofs_mkfs_job_ndir_ctx *ctx)
+{
+ struct erofs_inode *inode = ctx->inode;
int ret = 0;
if (S_ISLNK(inode->i_mode)) {
@@ -1124,12 +1152,7 @@ static int erofs_mkfs_handle_nondirectory(struct erofs_inode *inode)
ret = erofs_write_file_from_buffer(inode, symlink);
free(symlink);
} else if (inode->i_size) {
- int fd = open(inode->i_srcpath, O_RDONLY | O_BINARY);
-
- if (fd < 0)
- return -errno;
- ret = erofs_write_file(inode, fd, 0);
- close(fd);
+ ret = erofs_mkfs_job_write_file(ctx);
}
if (ret)
return ret;
@@ -1148,6 +1171,7 @@ struct erofs_mkfs_jobitem {
enum erofs_mkfs_jobtype type;
union {
struct erofs_inode *inode;
+ struct erofs_mkfs_job_ndir_ctx ndir;
} u;
};
@@ -1157,7 +1181,7 @@ static int erofs_mkfs_jobfn(struct erofs_mkfs_jobitem *item)
int ret;
if (item->type == EROFS_MKFS_JOB_NDIR)
- return erofs_mkfs_handle_nondirectory(inode);
+ return erofs_mkfs_handle_nondirectory(&item->u.ndir);
if (item->type == EROFS_MKFS_JOB_DIR) {
ret = erofs_prepare_inode_buffer(inode);
@@ -1294,11 +1318,27 @@ static int erofs_mkfs_handle_inode(struct erofs_inode *inode)
if (ret < 0)
return ret;
- if (!S_ISDIR(inode->i_mode))
+ if (!S_ISDIR(inode->i_mode)) {
+ struct erofs_mkfs_job_ndir_ctx ctx = { .inode = inode };
+
+ if (!S_ISLNK(inode->i_mode) && inode->i_size) {
+ ctx.fd = open(inode->i_srcpath, O_RDONLY | O_BINARY);
+ if (ctx.fd < 0)
+ return -errno;
+
+ if (cfg.c_compr_opts[0].alg &&
+ erofs_file_is_compressible(inode)) {
+ ctx.ictx = erofs_begin_compressed_file(inode,
+ ctx.fd, 0);
+ if (IS_ERR(ctx.ictx))
+ return PTR_ERR(ctx.ictx);
+ }
+ }
ret = erofs_mkfs_go(inode->sbi, EROFS_MKFS_JOB_NDIR,
- &inode, sizeof(inode));
- else
+ &ctx, sizeof(ctx));
+ } else {
ret = erofs_mkfs_handle_directory(inode);
+ }
erofs_info("file %s dumped (mode %05o)", erofs_fspath(inode->i_srcpath),
inode->i_mode);
return ret;
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
` (5 preceding siblings ...)
2024-04-16 8:04 ` [PATCH 7/8] erofs-utils: lib: introduce non-directory jobitem context Gao Xiang
@ 2024-04-16 8:04 ` Gao Xiang
2024-04-16 14:14 ` Yifan Zhao
6 siblings, 1 reply; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 8:04 UTC (permalink / raw)
To: linux-erofs; +Cc: Gao Xiang, Yifan Zhao
From: Gao Xiang <hsiangkao@linux.alibaba.com>
Dispatch deferred ops in another per-sb worker thread. Note that
deferred ops are strictly FIFOed.
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
---
include/erofs/internal.h | 6 ++
lib/inode.c | 121 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 124 insertions(+), 3 deletions(-)
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index f31e548..ecbbdf6 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -71,6 +71,7 @@ struct erofs_xattr_prefix_item {
#define EROFS_PACKED_NID_UNALLOCATED -1
+struct erofs_mkfs_dfops;
struct erofs_sb_info {
struct erofs_device_info *devs;
char *devname;
@@ -124,6 +125,11 @@ struct erofs_sb_info {
struct list_head list;
u64 saved_by_deduplication;
+
+#ifdef EROFS_MT_ENABLED
+ pthread_t dfops_worker;
+ struct erofs_mkfs_dfops *mkfs_dfops;
+#endif
};
/* make sure that any user of the erofs headers has atleast 64bit off_t type */
diff --git a/lib/inode.c b/lib/inode.c
index 681460c..3c952b2 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1165,6 +1165,7 @@ enum erofs_mkfs_jobtype { /* ordered job types */
EROFS_MKFS_JOB_NDIR,
EROFS_MKFS_JOB_DIR,
EROFS_MKFS_JOB_DIR_BH,
+ EROFS_MKFS_JOB_MAX
};
struct erofs_mkfs_jobitem {
@@ -1203,6 +1204,74 @@ static int erofs_mkfs_jobfn(struct erofs_mkfs_jobitem *item)
return -EINVAL;
}
+#ifdef EROFS_MT_ENABLED
+
+struct erofs_mkfs_dfops {
+ pthread_t worker;
+ pthread_mutex_t lock;
+ pthread_cond_t full, empty;
+ struct erofs_mkfs_jobitem *queue;
+ size_t size, elem_size;
+ size_t head, tail;
+};
+
+#define EROFS_MT_QUEUE_SIZE 256
+
+void *erofs_mkfs_pop_jobitem(struct erofs_mkfs_dfops *q)
+{
+ struct erofs_mkfs_jobitem *item;
+
+ pthread_mutex_lock(&q->lock);
+ while (q->head == q->tail)
+ pthread_cond_wait(&q->empty, &q->lock);
+
+ item = q->queue + q->head;
+ q->head = (q->head + 1) % q->size;
+
+ pthread_cond_signal(&q->full);
+ pthread_mutex_unlock(&q->lock);
+ return item;
+}
+
+void *z_erofs_mt_dfops_worker(void *arg)
+{
+ struct erofs_sb_info *sbi = arg;
+ int ret = 0;
+
+ while (1) {
+ struct erofs_mkfs_jobitem *item;
+
+ item = erofs_mkfs_pop_jobitem(sbi->mkfs_dfops);
+ if (item->type >= EROFS_MKFS_JOB_MAX)
+ break;
+ ret = erofs_mkfs_jobfn(item);
+ if (ret)
+ break;
+ }
+ pthread_exit((void *)(uintptr_t)ret);
+}
+
+int erofs_mkfs_go(struct erofs_sb_info *sbi,
+ enum erofs_mkfs_jobtype type, void *elem, int size)
+{
+ struct erofs_mkfs_jobitem *item;
+ struct erofs_mkfs_dfops *q = sbi->mkfs_dfops;
+
+ pthread_mutex_lock(&q->lock);
+
+ while ((q->tail + 1) % q->size == q->head)
+ pthread_cond_wait(&q->full, &q->lock);
+
+ item = q->queue + q->tail;
+ item->type = type;
+ memcpy(&item->u, elem, size);
+ q->tail = (q->tail + 1) % q->size;
+
+ pthread_cond_signal(&q->empty);
+ pthread_mutex_unlock(&q->lock);
+ return 0;
+}
+#else
int erofs_mkfs_go(struct erofs_sb_info *sbi,
enum erofs_mkfs_jobtype type, void *elem, int size)
{
@@ -1212,6 +1281,7 @@ int erofs_mkfs_go(struct erofs_sb_info *sbi,
memcpy(&item.u, elem, size);
return erofs_mkfs_jobfn(&item);
}
+#endif
static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
{
@@ -1344,7 +1414,11 @@ static int erofs_mkfs_handle_inode(struct erofs_inode *inode)
return ret;
}
-struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
+#ifndef EROFS_MT_ENABLED
+#define __erofs_mkfs_build_tree_from_path erofs_mkfs_build_tree_from_path
+#endif
+
+struct erofs_inode *__erofs_mkfs_build_tree_from_path(const char *path)
{
struct erofs_inode *root, *dumpdir;
int err;
@@ -1361,7 +1435,6 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
err = erofs_mkfs_handle_inode(root);
if (err)
return ERR_PTR(err);
- erofs_fixup_meta_blkaddr(root);
do {
int err;
@@ -1400,10 +1473,52 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
if (err)
return ERR_PTR(err);
} while (dumpdir);
-
return root;
}
+#ifdef EROFS_MT_ENABLED
+struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
+{
+ struct erofs_mkfs_dfops *q;
+ struct erofs_inode *root;
+ int err;
+
+ q = malloc(sizeof(*q));
+ if (!q)
+ return ERR_PTR(-ENOMEM);
+
+ q->queue = malloc(q->size * sizeof(*q->queue));
+ if (!q->queue) {
+ free(q);
+ return ERR_PTR(-ENOMEM);
+ }
+ pthread_mutex_init(&q->lock, NULL);
+ pthread_cond_init(&q->empty, NULL);
+ pthread_cond_init(&q->full, NULL);
+
+ q->size = EROFS_MT_QUEUE_SIZE;
+ q->head = 0;
+ q->tail = 0;
+ sbi.mkfs_dfops = q;
+ err = pthread_create(&sbi.dfops_worker, NULL,
+ z_erofs_mt_dfops_worker, &sbi);
+ if (err)
+ goto fail;
+ root = __erofs_mkfs_build_tree_from_path(path);
+
+ erofs_mkfs_go(&sbi, ~0, NULL, 0);
+ err = pthread_join(sbi.dfops_worker, NULL);
+
+fail:
+ pthread_cond_destroy(&q->empty);
+ pthread_cond_destroy(&q->full);
+ pthread_mutex_destroy(&q->lock);
+ free(q->queue);
+ free(q);
+ return err ? ERR_PTR(err) : root;
+}
+#endif
+
struct erofs_inode *erofs_mkfs_build_special_from_fd(int fd, const char *name)
{
struct stat st;
--
2.30.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs
2024-04-16 8:04 ` [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs Gao Xiang
@ 2024-04-16 11:55 ` Yifan Zhao
2024-04-16 14:58 ` Gao Xiang
0 siblings, 1 reply; 13+ messages in thread
From: Yifan Zhao @ 2024-04-16 11:55 UTC (permalink / raw)
To: Gao Xiang; +Cc: linux-erofs
On 4/16/24 4:04 PM, Gao Xiang wrote:
> From: Gao Xiang <hsiangkao@linux.alibaba.com>
>
> They should be located in `struct z_erofs_compress_ictx`.
>
> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
> ---
> lib/compress.c | 55 ++++++++++++++++++++++++++++----------------------
> 1 file changed, 31 insertions(+), 24 deletions(-)
>
> diff --git a/lib/compress.c b/lib/compress.c
> index a2e0d0f..72f33d2 100644
> --- a/lib/compress.c
> +++ b/lib/compress.c
> @@ -38,6 +38,7 @@ struct z_erofs_extent_item {
>
> struct z_erofs_compress_ictx { /* inode context */
> struct erofs_inode *inode;
> + struct erofs_compress_cfg *ccfg;
> int fd;
> u64 fpos;
>
> @@ -49,6 +50,14 @@ struct z_erofs_compress_ictx { /* inode context */
> u8 *metacur;
> struct list_head extents;
> u16 clusterofs;
> +
> + int seg_num;
> +
> +#if EROFS_MT_ENABLED
> + pthread_mutex_t mutex;
> + pthread_cond_t cond;
> + int nfini;
> +#endif
> };
>
> struct z_erofs_compress_sctx { /* segment context */
> @@ -68,7 +77,7 @@ struct z_erofs_compress_sctx { /* segment context */
> erofs_blk_t blkaddr; /* pointing to the next blkaddr */
> u16 clusterofs;
>
> - int seg_num, seg_idx;
> + int seg_idx;
>
> void *membuf;
> erofs_off_t memoff;
> @@ -99,8 +108,6 @@ static struct {
> struct erofs_workqueue wq;
> struct erofs_compress_work *idle;
> pthread_mutex_t mutex;
I think `mutex` should also be removed. Do you miss it?
> - pthread_cond_t cond;
> - int nfini;
> } z_erofs_mt_ctrl;
> #endif
>
> @@ -512,7 +519,7 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
> struct erofs_compress *const h = ctx->chandle;
> unsigned int len = ctx->tail - ctx->head;
> bool is_packed_inode = erofs_is_packed_inode(inode);
> - bool tsg = (ctx->seg_idx + 1 >= ctx->seg_num), final = !ctx->remaining;
> + bool tsg = (ctx->seg_idx + 1 >= ictx->seg_num), final = !ctx->remaining;
> bool may_packing = (cfg.c_fragments && tsg && final &&
> !is_packed_inode && !z_erofs_mt_enabled);
> bool may_inline = (cfg.c_ztailpacking && tsg && final && !may_packing);
> @@ -1196,7 +1203,8 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp)
> struct erofs_compress_work *cwork = (struct erofs_compress_work *)work;
> struct erofs_compress_wq_tls *tls = tlsp;
> struct z_erofs_compress_sctx *sctx = &cwork->ctx;
> - struct erofs_inode *inode = sctx->ictx->inode;
> + struct z_erofs_compress_ictx *ictx = sctx->ictx;
> + struct erofs_inode *inode = ictx->inode;
> struct erofs_sb_info *sbi = inode->sbi;
> int ret = 0;
>
> @@ -1223,10 +1231,10 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp)
>
> out:
> cwork->errcode = ret;
> - pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
> - ++z_erofs_mt_ctrl.nfini;
> - pthread_cond_signal(&z_erofs_mt_ctrl.cond);
> - pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
> + pthread_mutex_lock(&ictx->mutex);
> + ++ictx->nfini;
> + pthread_cond_signal(&ictx->cond);
> + pthread_mutex_unlock(&ictx->mutex);
> }
>
> int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
> @@ -1260,16 +1268,19 @@ int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
> }
>
> int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
> - struct erofs_compress_cfg *ccfg,
> erofs_blk_t blkaddr,
> erofs_blk_t *compressed_blocks)
> {
> 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;
>
> - z_erofs_mt_ctrl.nfini = 0;
> + ictx->seg_num = nsegs;
> + ictx->nfini = 0;
> + pthread_mutex_init(&ictx->mutex, NULL);
> + pthread_cond_init(&ictx->cond, NULL);
>
> for (i = 0; i < nsegs; i++) {
> if (z_erofs_mt_ctrl.idle) {
> @@ -1286,7 +1297,6 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
>
> cur->ctx = (struct z_erofs_compress_sctx) {
> .ictx = ictx,
> - .seg_num = nsegs,
> .seg_idx = i,
> .pivot = &dummy_pivot,
> };
> @@ -1308,11 +1318,10 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
> erofs_queue_work(&z_erofs_mt_ctrl.wq, &cur->work);
> }
>
> - pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
> - while (z_erofs_mt_ctrl.nfini != nsegs)
> - pthread_cond_wait(&z_erofs_mt_ctrl.cond,
> - &z_erofs_mt_ctrl.mutex);
> - pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
> + pthread_mutex_lock(&ictx->mutex);
> + while (ictx->nfini < ictx->seg_num)
> + pthread_cond_wait(&ictx->cond, &ictx->mutex);
> + pthread_mutex_unlock(&ictx->mutex);
>
> ret = 0;
> while (head) {
> @@ -1346,7 +1355,6 @@ 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;
> - struct erofs_compress_cfg *ccfg;
> erofs_blk_t blkaddr, compressed_blocks = 0;
> int ret;
> bool ismt = false;
> @@ -1381,8 +1389,8 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
> }
> }
> #endif
> - ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
> - inode->z_algorithmtype[0] = ccfg[0].algorithmtype;
> + ctx.ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
> + inode->z_algorithmtype[0] = ctx.ccfg->algorithmtype;
> inode->z_algorithmtype[1] = 0;
>
> inode->idata_size = 0;
> @@ -1421,16 +1429,16 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
> #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, ccfg, blkaddr, &compressed_blocks);
> + ret = z_erofs_mt_compress(&ctx, blkaddr, &compressed_blocks);
> if (ret)
> goto err_free_idata;
> #endif
> } else {
> + ctx.seg_num = 1;
> sctx.queue = g_queue;
> sctx.destbuf = NULL;
> - sctx.chandle = &ccfg->handle;
> + sctx.chandle = &ctx.ccfg->handle;
> sctx.remaining = inode->i_size - inode->fragment_size;
> - sctx.seg_num = 1;
> sctx.seg_idx = 0;
> sctx.pivot = &dummy_pivot;
> sctx.pclustersize = z_erofs_get_max_pclustersize(inode);
> @@ -1621,7 +1629,6 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
> #ifdef EROFS_MT_ENABLED
> if (cfg.c_mt_workers > 1) {
> pthread_mutex_init(&z_erofs_mt_ctrl.mutex, NULL);
Remove this line too.
Thanks,
Yifan Zhao
> - pthread_cond_init(&z_erofs_mt_ctrl.cond, NULL);
> ret = erofs_alloc_workqueue(&z_erofs_mt_ctrl.wq,
> cfg.c_mt_workers,
> cfg.c_mt_workers << 2,
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/8] erofs-utils: lib: prepare for later deferred work
2024-04-16 8:04 ` [PATCH 2/8] erofs-utils: lib: prepare for later deferred work Gao Xiang
@ 2024-04-16 11:58 ` Yifan Zhao
2024-04-16 14:57 ` Gao Xiang
0 siblings, 1 reply; 13+ messages in thread
From: Yifan Zhao @ 2024-04-16 11:58 UTC (permalink / raw)
To: Gao Xiang; +Cc: linux-erofs
On 4/16/24 4:04 PM, Gao Xiang wrote:
> From: Gao Xiang <hsiangkao@linux.alibaba.com>
>
> Split out ordered metadata operations and add the following helpers:
>
> - erofs_mkfs_jobfn()
>
> - erofs_mkfs_go()
>
> to handle these mkfs job items for multi-threadding support.
>
> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
> ---
> lib/inode.c | 68 +++++++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 58 insertions(+), 10 deletions(-)
>
> diff --git a/lib/inode.c b/lib/inode.c
> index 55969d9..8ef0604 100644
> --- a/lib/inode.c
> +++ b/lib/inode.c
> @@ -1133,6 +1133,57 @@ static int erofs_mkfs_handle_nondirectory(struct erofs_inode *inode)
> return 0;
> }
>
> +enum erofs_mkfs_jobtype { /* ordered job types */
> + EROFS_MKFS_JOB_NDIR,
> + EROFS_MKFS_JOB_DIR,
> + EROFS_MKFS_JOB_DIR_BH,
> +};
> +
> +struct erofs_mkfs_jobitem {
> + enum erofs_mkfs_jobtype type;
> + union {
> + struct erofs_inode *inode;
> + } u;
> +};
> +
> +static int erofs_mkfs_jobfn(struct erofs_mkfs_jobitem *item)
> +{
> + struct erofs_inode *inode = item->u.inode;
> + int ret;
> +
> + if (item->type == EROFS_MKFS_JOB_NDIR)
> + return erofs_mkfs_handle_nondirectory(inode);
> +
> + if (item->type == EROFS_MKFS_JOB_DIR) {
> + ret = erofs_prepare_inode_buffer(inode);
> + if (ret)
> + return ret;
> + inode->bh->op = &erofs_skip_write_bhops;
> + if (IS_ROOT(inode))
> + erofs_fixup_meta_blkaddr(inode);
I think this 2 line above does not exist in the logic replaced by
`erofs_mkfs_jobfn`, should it appear in this patch, or need further
explanation in the commit msg?
Thanks,
Yifan Zhao
> + return 0;
> + }
> +
> + if (item->type == EROFS_MKFS_JOB_DIR_BH) {
> + erofs_write_dir_file(inode);
> + erofs_write_tail_end(inode);
> + inode->bh->op = &erofs_write_inode_bhops;
> + erofs_iput(inode);
> + return 0;
> + }
> + return -EINVAL;
> +}
> +
> +int erofs_mkfs_go(struct erofs_sb_info *sbi,
> + enum erofs_mkfs_jobtype type, void *elem, int size)
> +{
> + struct erofs_mkfs_jobitem item;
> +
> + item.type = type;
> + memcpy(&item.u, elem, size);
> + return erofs_mkfs_jobfn(&item);
> +}
> +
> static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
> {
> DIR *_dir;
> @@ -1213,11 +1264,7 @@ static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
> else
> dir->i_nlink = i_nlink;
>
> - ret = erofs_prepare_inode_buffer(dir);
> - if (ret)
> - return ret;
> - dir->bh->op = &erofs_skip_write_bhops;
> - return 0;
> + return erofs_mkfs_go(dir->sbi, EROFS_MKFS_JOB_DIR, &dir, sizeof(dir));
>
> err_closedir:
> closedir(_dir);
> @@ -1243,7 +1290,8 @@ static int erofs_mkfs_handle_inode(struct erofs_inode *inode)
> return ret;
>
> if (!S_ISDIR(inode->i_mode))
> - ret = erofs_mkfs_handle_nondirectory(inode);
> + ret = erofs_mkfs_go(inode->sbi, EROFS_MKFS_JOB_NDIR,
> + &inode, sizeof(inode));
> else
> ret = erofs_mkfs_handle_directory(inode);
> erofs_info("file %s dumped (mode %05o)", erofs_fspath(inode->i_srcpath),
> @@ -1302,10 +1350,10 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
> }
> *last = dumpdir; /* fixup the last (or the only) one */
> dumpdir = head;
> - erofs_write_dir_file(dir);
> - erofs_write_tail_end(dir);
> - dir->bh->op = &erofs_write_inode_bhops;
> - erofs_iput(dir);
> + err = erofs_mkfs_go(dir->sbi, EROFS_MKFS_JOB_DIR_BH,
> + &dir, sizeof(dir));
> + if (err)
> + return ERR_PTR(err);
> } while (dumpdir);
>
> return root;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression
2024-04-16 8:04 ` [PATCH 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression Gao Xiang
@ 2024-04-16 14:14 ` Yifan Zhao
0 siblings, 0 replies; 13+ messages in thread
From: Yifan Zhao @ 2024-04-16 14:14 UTC (permalink / raw)
To: Gao Xiang; +Cc: linux-erofs
On 4/16/24 4:04 PM, Gao Xiang wrote:
> From: Gao Xiang <hsiangkao@linux.alibaba.com>
>
> Dispatch deferred ops in another per-sb worker thread. Note that
> deferred ops are strictly FIFOed.
>
> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
> ---
> include/erofs/internal.h | 6 ++
> lib/inode.c | 121 ++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 124 insertions(+), 3 deletions(-)
>
> diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> index f31e548..ecbbdf6 100644
> --- a/include/erofs/internal.h
> +++ b/include/erofs/internal.h
> @@ -71,6 +71,7 @@ struct erofs_xattr_prefix_item {
>
> #define EROFS_PACKED_NID_UNALLOCATED -1
>
> +struct erofs_mkfs_dfops;
> struct erofs_sb_info {
> struct erofs_device_info *devs;
> char *devname;
> @@ -124,6 +125,11 @@ struct erofs_sb_info {
> struct list_head list;
>
> u64 saved_by_deduplication;
> +
> +#ifdef EROFS_MT_ENABLED
> + pthread_t dfops_worker;
> + struct erofs_mkfs_dfops *mkfs_dfops;
> +#endif
> };
>
> /* make sure that any user of the erofs headers has atleast 64bit off_t type */
> diff --git a/lib/inode.c b/lib/inode.c
> index 681460c..3c952b2 100644
> --- a/lib/inode.c
> +++ b/lib/inode.c
> @@ -1165,6 +1165,7 @@ enum erofs_mkfs_jobtype { /* ordered job types */
> EROFS_MKFS_JOB_NDIR,
> EROFS_MKFS_JOB_DIR,
> EROFS_MKFS_JOB_DIR_BH,
> + EROFS_MKFS_JOB_MAX
> };
>
> struct erofs_mkfs_jobitem {
> @@ -1203,6 +1204,74 @@ static int erofs_mkfs_jobfn(struct erofs_mkfs_jobitem *item)
> return -EINVAL;
> }
>
> +#ifdef EROFS_MT_ENABLED
> +
> +struct erofs_mkfs_dfops {
> + pthread_t worker;
> + pthread_mutex_t lock;
> + pthread_cond_t full, empty;
> + struct erofs_mkfs_jobitem *queue;
> + size_t size, elem_size;
> + size_t head, tail;
> +};
> +
> +#define EROFS_MT_QUEUE_SIZE 256
> +
> +void *erofs_mkfs_pop_jobitem(struct erofs_mkfs_dfops *q)
> +{
> + struct erofs_mkfs_jobitem *item;
> +
> + pthread_mutex_lock(&q->lock);
> + while (q->head == q->tail)
> + pthread_cond_wait(&q->empty, &q->lock);
> +
> + item = q->queue + q->head;
> + q->head = (q->head + 1) % q->size;
> +
> + pthread_cond_signal(&q->full);
> + pthread_mutex_unlock(&q->lock);
> + return item;
> +}
> +
> +void *z_erofs_mt_dfops_worker(void *arg)
> +{
> + struct erofs_sb_info *sbi = arg;
> + int ret = 0;
> +
> + while (1) {
> + struct erofs_mkfs_jobitem *item;
> +
> + item = erofs_mkfs_pop_jobitem(sbi->mkfs_dfops);
> + if (item->type >= EROFS_MKFS_JOB_MAX)
> + break;
> + ret = erofs_mkfs_jobfn(item);
> + if (ret)
> + break;
> + }
> + pthread_exit((void *)(uintptr_t)ret);
> +}
> +
> +int erofs_mkfs_go(struct erofs_sb_info *sbi,
> + enum erofs_mkfs_jobtype type, void *elem, int size)
> +{
> + struct erofs_mkfs_jobitem *item;
> + struct erofs_mkfs_dfops *q = sbi->mkfs_dfops;
> +
> + pthread_mutex_lock(&q->lock);
> +
> + while ((q->tail + 1) % q->size == q->head)
> + pthread_cond_wait(&q->full, &q->lock);
> +
> + item = q->queue + q->tail;
> + item->type = type;
> + memcpy(&item->u, elem, size);
> + q->tail = (q->tail + 1) % q->size;
> +
> + pthread_cond_signal(&q->empty);
> + pthread_mutex_unlock(&q->lock);
> + return 0;
> +}
> +#else
> int erofs_mkfs_go(struct erofs_sb_info *sbi,
> enum erofs_mkfs_jobtype type, void *elem, int size)
> {
> @@ -1212,6 +1281,7 @@ int erofs_mkfs_go(struct erofs_sb_info *sbi,
> memcpy(&item.u, elem, size);
> return erofs_mkfs_jobfn(&item);
> }
> +#endif
>
> static int erofs_mkfs_handle_directory(struct erofs_inode *dir)
> {
> @@ -1344,7 +1414,11 @@ static int erofs_mkfs_handle_inode(struct erofs_inode *inode)
> return ret;
> }
>
> -struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
> +#ifndef EROFS_MT_ENABLED
> +#define __erofs_mkfs_build_tree_from_path erofs_mkfs_build_tree_from_path
> +#endif
> +
> +struct erofs_inode *__erofs_mkfs_build_tree_from_path(const char *path)
> {
> struct erofs_inode *root, *dumpdir;
> int err;
> @@ -1361,7 +1435,6 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
> err = erofs_mkfs_handle_inode(root);
> if (err)
> return ERR_PTR(err);
> - erofs_fixup_meta_blkaddr(root);
>
> do {
> int err;
> @@ -1400,10 +1473,52 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
> if (err)
> return ERR_PTR(err);
> } while (dumpdir);
> -
> return root;
> }
>
> +#ifdef EROFS_MT_ENABLED
> +struct erofs_inode *erofs_mkfs_build_tree_from_path(const char *path)
> +{
> + struct erofs_mkfs_dfops *q;
> + struct erofs_inode *root;
> + int err;
> +
> + q = malloc(sizeof(*q));
> + if (!q)
> + return ERR_PTR(-ENOMEM);
> +
> + q->queue = malloc(q->size * sizeof(*q->queue));
q->size is not initialized here. Should move `q->size =
EROFS_MT_QUEUE_SIZE;` before it.
Thanks,
Yifan Zhao
> + if (!q->queue) {
> + free(q);
> + return ERR_PTR(-ENOMEM);
> + }
> + pthread_mutex_init(&q->lock, NULL);
> + pthread_cond_init(&q->empty, NULL);
> + pthread_cond_init(&q->full, NULL);
> +
> + q->size = EROFS_MT_QUEUE_SIZE;
> + q->head = 0;
> + q->tail = 0;
> + sbi.mkfs_dfops = q;
> + err = pthread_create(&sbi.dfops_worker, NULL,
> + z_erofs_mt_dfops_worker, &sbi);
> + if (err)
> + goto fail;
> + root = __erofs_mkfs_build_tree_from_path(path);
> +
> + erofs_mkfs_go(&sbi, ~0, NULL, 0);
> + err = pthread_join(sbi.dfops_worker, NULL);
> +
> +fail:
> + pthread_cond_destroy(&q->empty);
> + pthread_cond_destroy(&q->full);
> + pthread_mutex_destroy(&q->lock);
> + free(q->queue);
> + free(q);
> + return err ? ERR_PTR(err) : root;
> +}
> +#endif
> +
> struct erofs_inode *erofs_mkfs_build_special_from_fd(int fd, const char *name)
> {
> struct stat st;
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/8] erofs-utils: lib: prepare for later deferred work
2024-04-16 11:58 ` Yifan Zhao
@ 2024-04-16 14:57 ` Gao Xiang
0 siblings, 0 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 14:57 UTC (permalink / raw)
To: Yifan Zhao; +Cc: linux-erofs
Hi Yifan,
On Tue, Apr 16, 2024 at 07:58:30PM +0800, Yifan Zhao wrote:
>
> On 4/16/24 4:04 PM, Gao Xiang wrote:
> > From: Gao Xiang <hsiangkao@linux.alibaba.com>
> >
> > Split out ordered metadata operations and add the following helpers:
> >
> > - erofs_mkfs_jobfn()
> >
> > - erofs_mkfs_go()
> >
> > to handle these mkfs job items for multi-threadding support.
> >
> > Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
> > ---
> > lib/inode.c | 68 +++++++++++++++++++++++++++++++++++++++++++++--------
> > 1 file changed, 58 insertions(+), 10 deletions(-)
> >
> > diff --git a/lib/inode.c b/lib/inode.c
> > index 55969d9..8ef0604 100644
> > --- a/lib/inode.c
> > +++ b/lib/inode.c
> > @@ -1133,6 +1133,57 @@ static int erofs_mkfs_handle_nondirectory(struct erofs_inode *inode)
> > return 0;
> > }
> > +enum erofs_mkfs_jobtype { /* ordered job types */
> > + EROFS_MKFS_JOB_NDIR,
> > + EROFS_MKFS_JOB_DIR,
> > + EROFS_MKFS_JOB_DIR_BH,
> > +};
> > +
> > +struct erofs_mkfs_jobitem {
> > + enum erofs_mkfs_jobtype type;
> > + union {
> > + struct erofs_inode *inode;
> > + } u;
> > +};
> > +
> > +static int erofs_mkfs_jobfn(struct erofs_mkfs_jobitem *item)
> > +{
> > + struct erofs_inode *inode = item->u.inode;
> > + int ret;
> > +
> > + if (item->type == EROFS_MKFS_JOB_NDIR)
> > + return erofs_mkfs_handle_nondirectory(inode);
> > +
> > + if (item->type == EROFS_MKFS_JOB_DIR) {
> > + ret = erofs_prepare_inode_buffer(inode);
> > + if (ret)
> > + return ret;
> > + inode->bh->op = &erofs_skip_write_bhops;
> > + if (IS_ROOT(inode))
> > + erofs_fixup_meta_blkaddr(inode);
>
> I think this 2 line above does not exist in the logic replaced by
> `erofs_mkfs_jobfn`, should it appear in this patch, or need further
> explanation in the commit msg?
Because erofs_fixup_meta_blkaddr() needs to be called
strictly after erofs_prepare_inode_buffer(root) is
done, which allocates on-disk inode so NID is also
meaningful then.
But you're right. This part is not quite good, let me
think more about it.
Thanks,
Gao Xiang
>
>
> Thanks,
>
> Yifan Zhao
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs
2024-04-16 11:55 ` Yifan Zhao
@ 2024-04-16 14:58 ` Gao Xiang
0 siblings, 0 replies; 13+ messages in thread
From: Gao Xiang @ 2024-04-16 14:58 UTC (permalink / raw)
To: Yifan Zhao; +Cc: linux-erofs
On Tue, Apr 16, 2024 at 07:55:05PM +0800, Yifan Zhao wrote:
>
> On 4/16/24 4:04 PM, Gao Xiang wrote:
> > From: Gao Xiang <hsiangkao@linux.alibaba.com>
> >
> > They should be located in `struct z_erofs_compress_ictx`.
> >
> > Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
> > ---
> > lib/compress.c | 55 ++++++++++++++++++++++++++++----------------------
> > 1 file changed, 31 insertions(+), 24 deletions(-)
> >
> > diff --git a/lib/compress.c b/lib/compress.c
> > index a2e0d0f..72f33d2 100644
> > --- a/lib/compress.c
> > +++ b/lib/compress.c
> > @@ -38,6 +38,7 @@ struct z_erofs_extent_item {
> > struct z_erofs_compress_ictx { /* inode context */
> > struct erofs_inode *inode;
> > + struct erofs_compress_cfg *ccfg;
> > int fd;
> > u64 fpos;
> > @@ -49,6 +50,14 @@ struct z_erofs_compress_ictx { /* inode context */
> > u8 *metacur;
> > struct list_head extents;
> > u16 clusterofs;
> > +
> > + int seg_num;
> > +
> > +#if EROFS_MT_ENABLED
> > + pthread_mutex_t mutex;
> > + pthread_cond_t cond;
> > + int nfini;
> > +#endif
> > };
> > struct z_erofs_compress_sctx { /* segment context */
> > @@ -68,7 +77,7 @@ struct z_erofs_compress_sctx { /* segment context */
> > erofs_blk_t blkaddr; /* pointing to the next blkaddr */
> > u16 clusterofs;
> > - int seg_num, seg_idx;
> > + int seg_idx;
> > void *membuf;
> > erofs_off_t memoff;
> > @@ -99,8 +108,6 @@ static struct {
> > struct erofs_workqueue wq;
> > struct erofs_compress_work *idle;
> > pthread_mutex_t mutex;
> I think `mutex` should also be removed. Do you miss it?
Yeah, will fix in the next version.
> > - pthread_cond_t cond;
> > - int nfini;
> > } z_erofs_mt_ctrl;
> > #endif
> > @@ -512,7 +519,7 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
> > struct erofs_compress *const h = ctx->chandle;
> > unsigned int len = ctx->tail - ctx->head;
> > bool is_packed_inode = erofs_is_packed_inode(inode);
> > - bool tsg = (ctx->seg_idx + 1 >= ctx->seg_num), final = !ctx->remaining;
> > + bool tsg = (ctx->seg_idx + 1 >= ictx->seg_num), final = !ctx->remaining;
> > bool may_packing = (cfg.c_fragments && tsg && final &&
> > !is_packed_inode && !z_erofs_mt_enabled);
> > bool may_inline = (cfg.c_ztailpacking && tsg && final && !may_packing);
> > @@ -1196,7 +1203,8 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp)
> > struct erofs_compress_work *cwork = (struct erofs_compress_work *)work;
> > struct erofs_compress_wq_tls *tls = tlsp;
> > struct z_erofs_compress_sctx *sctx = &cwork->ctx;
> > - struct erofs_inode *inode = sctx->ictx->inode;
> > + struct z_erofs_compress_ictx *ictx = sctx->ictx;
> > + struct erofs_inode *inode = ictx->inode;
> > struct erofs_sb_info *sbi = inode->sbi;
> > int ret = 0;
> > @@ -1223,10 +1231,10 @@ void z_erofs_mt_workfn(struct erofs_work *work, void *tlsp)
> > out:
> > cwork->errcode = ret;
> > - pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
> > - ++z_erofs_mt_ctrl.nfini;
> > - pthread_cond_signal(&z_erofs_mt_ctrl.cond);
> > - pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
> > + pthread_mutex_lock(&ictx->mutex);
> > + ++ictx->nfini;
> > + pthread_cond_signal(&ictx->cond);
> > + pthread_mutex_unlock(&ictx->mutex);
> > }
> > int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
> > @@ -1260,16 +1268,19 @@ int z_erofs_merge_segment(struct z_erofs_compress_ictx *ictx,
> > }
> > int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
> > - struct erofs_compress_cfg *ccfg,
> > erofs_blk_t blkaddr,
> > erofs_blk_t *compressed_blocks)
> > {
> > 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;
> > - z_erofs_mt_ctrl.nfini = 0;
> > + ictx->seg_num = nsegs;
> > + ictx->nfini = 0;
> > + pthread_mutex_init(&ictx->mutex, NULL);
> > + pthread_cond_init(&ictx->cond, NULL);
> > for (i = 0; i < nsegs; i++) {
> > if (z_erofs_mt_ctrl.idle) {
> > @@ -1286,7 +1297,6 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
> > cur->ctx = (struct z_erofs_compress_sctx) {
> > .ictx = ictx,
> > - .seg_num = nsegs,
> > .seg_idx = i,
> > .pivot = &dummy_pivot,
> > };
> > @@ -1308,11 +1318,10 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx,
> > erofs_queue_work(&z_erofs_mt_ctrl.wq, &cur->work);
> > }
> > - pthread_mutex_lock(&z_erofs_mt_ctrl.mutex);
> > - while (z_erofs_mt_ctrl.nfini != nsegs)
> > - pthread_cond_wait(&z_erofs_mt_ctrl.cond,
> > - &z_erofs_mt_ctrl.mutex);
> > - pthread_mutex_unlock(&z_erofs_mt_ctrl.mutex);
> > + pthread_mutex_lock(&ictx->mutex);
> > + while (ictx->nfini < ictx->seg_num)
> > + pthread_cond_wait(&ictx->cond, &ictx->mutex);
> > + pthread_mutex_unlock(&ictx->mutex);
> > ret = 0;
> > while (head) {
> > @@ -1346,7 +1355,6 @@ 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;
> > - struct erofs_compress_cfg *ccfg;
> > erofs_blk_t blkaddr, compressed_blocks = 0;
> > int ret;
> > bool ismt = false;
> > @@ -1381,8 +1389,8 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
> > }
> > }
> > #endif
> > - ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
> > - inode->z_algorithmtype[0] = ccfg[0].algorithmtype;
> > + ctx.ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
> > + inode->z_algorithmtype[0] = ctx.ccfg->algorithmtype;
> > inode->z_algorithmtype[1] = 0;
> > inode->idata_size = 0;
> > @@ -1421,16 +1429,16 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
> > #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, ccfg, blkaddr, &compressed_blocks);
> > + ret = z_erofs_mt_compress(&ctx, blkaddr, &compressed_blocks);
> > if (ret)
> > goto err_free_idata;
> > #endif
> > } else {
> > + ctx.seg_num = 1;
> > sctx.queue = g_queue;
> > sctx.destbuf = NULL;
> > - sctx.chandle = &ccfg->handle;
> > + sctx.chandle = &ctx.ccfg->handle;
> > sctx.remaining = inode->i_size - inode->fragment_size;
> > - sctx.seg_num = 1;
> > sctx.seg_idx = 0;
> > sctx.pivot = &dummy_pivot;
> > sctx.pclustersize = z_erofs_get_max_pclustersize(inode);
> > @@ -1621,7 +1629,6 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
> > #ifdef EROFS_MT_ENABLED
> > if (cfg.c_mt_workers > 1) {
> > pthread_mutex_init(&z_erofs_mt_ctrl.mutex, NULL);
>
> Remove this line too.
Will fix too.
Thanks,
Gao Xiang
>
>
> Thanks,
>
> Yifan Zhao
>
> > - pthread_cond_init(&z_erofs_mt_ctrl.cond, NULL);
> > ret = erofs_alloc_workqueue(&z_erofs_mt_ctrl.wq,
> > cfg.c_mt_workers,
> > cfg.c_mt_workers << 2,
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-04-16 14:59 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-16 8:04 [PATCH 1/8] erofs-utils: use erofs_atomic_t for inode->i_count Gao Xiang
2024-04-16 8:04 ` [PATCH 2/8] erofs-utils: lib: prepare for later deferred work Gao Xiang
2024-04-16 11:58 ` Yifan Zhao
2024-04-16 14:57 ` Gao Xiang
2024-04-16 8:04 ` [PATCH 3/8] erofs-utils: lib: split out erofs_commit_compressed_file() Gao Xiang
2024-04-16 8:04 ` [PATCH 4/8] erofs-utils: rearrange several fields for multi-threaded mkfs Gao Xiang
2024-04-16 11:55 ` Yifan Zhao
2024-04-16 14:58 ` Gao Xiang
2024-04-16 8:04 ` [PATCH 5/8] erofs-utils: lib: split up z_erofs_mt_compress() Gao Xiang
2024-04-16 8:04 ` [PATCH 6/8] erofs-utils: mkfs: prepare inter-file multi-threaded compression Gao Xiang
2024-04-16 8:04 ` [PATCH 7/8] erofs-utils: lib: introduce non-directory jobitem context Gao Xiang
2024-04-16 8:04 ` [PATCH 8/8] erofs-utils: mkfs: enable inter-file multi-threaded compression Gao Xiang
2024-04-16 14:14 ` Yifan Zhao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).