[PATCH 3/5] erofs-utils: lib: introduce per-FS compression context

Gao Xiang hsiangkao at linux.alibaba.com
Tue Jun 3 13:56:55 AEST 2025


Add a per-FS context for the compression process to maintain
multi-bucket fragment queues.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/compress.h |  2 +-
 include/erofs/internal.h |  2 ++
 lib/compress.c           | 49 +++++++++++++++++++++++++++-------------
 mkfs/main.c              |  2 +-
 4 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/include/erofs/compress.h b/include/erofs/compress.h
index c9831a7..4731a8b 100644
--- a/include/erofs/compress.h
+++ b/include/erofs/compress.h
@@ -25,7 +25,7 @@ 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);
-int z_erofs_compress_exit(void);
+int z_erofs_compress_exit(struct erofs_sb_info *sbi);
 
 const char *z_erofs_list_supported_algorithms(int i, unsigned int *mask);
 const struct erofs_algorithm *z_erofs_list_available_compressors(int *i);
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 73845f1..e89a1e4 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -82,6 +82,7 @@ struct erofs_xattr_prefix_item {
 
 struct erofs_mkfs_dfops;
 struct erofs_packed_inode;
+struct z_erofs_mgr;
 
 struct erofs_sb_info {
 	struct erofs_sb_lz4_info lz4;
@@ -141,6 +142,7 @@ struct erofs_sb_info {
 	struct erofs_mkfs_dfops *mkfs_dfops;
 #endif
 	struct erofs_bufmgr *bmgr;
+	struct z_erofs_mgr *zmgr;
 	struct erofs_packed_inode *packedinode;
 	bool useqpl;
 };
diff --git a/lib/compress.c b/lib/compress.c
index 706a756..cbc51ca 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -28,13 +28,6 @@
 
 #define Z_EROFS_DESTBUF_SZ	(Z_EROFS_PCLUSTER_MAX_SIZE + EROFS_MAX_BLOCK_SIZE * 2)
 
-/* compressing configuration specified by users */
-struct erofs_compress_cfg {
-	struct erofs_compress handle;
-	unsigned int algorithmtype;
-	bool enable;
-} erofs_ccfg[EROFS_MAX_COMPR_CFGS];
-
 struct z_erofs_extent_item {
 	struct list_head list;
 	struct z_erofs_inmem_extent e;
@@ -118,6 +111,17 @@ static struct {
 } z_erofs_mt_ctrl;
 #endif
 
+/* compressing configuration specified by users */
+struct erofs_compress_cfg {
+	struct erofs_compress handle;
+	unsigned int algorithmtype;
+	bool enable;
+};
+
+struct z_erofs_mgr {
+	struct erofs_compress_cfg ccfg[EROFS_MAX_COMPR_CFGS];
+};
+
 static bool z_erofs_mt_enabled;
 
 #define Z_EROFS_LEGACY_MAP_HEADER_SIZE	Z_EROFS_FULL_INDEX_ALIGN(0)
@@ -1463,6 +1467,7 @@ int z_erofs_mt_compress(struct z_erofs_compress_ictx *ictx)
 		if (i >= nsegs - 1) {
 			cur->ctx.remaining = inode->i_size -
 					inode->fragment_size - (u64)i * segsz;
+
 			if (z_erofs_mt_ctrl.hasfwq) {
 				erofs_queue_work(&z_erofs_mt_ctrl.fwq,
 						 &cur->work);
@@ -1591,7 +1596,7 @@ void *erofs_begin_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
 		while (1) {
 			inode->z_algorithmtype[0] =
 				rand() % EROFS_MAX_COMPR_CFGS;
-			if (erofs_ccfg[inode->z_algorithmtype[0]].enable)
+			if (sbi->zmgr->ccfg[inode->z_algorithmtype[0]].enable)
 				break;
 		}
 	}
@@ -1616,7 +1621,7 @@ void *erofs_begin_compressed_file(struct erofs_inode *inode, int fd, u64 fpos)
 		ictx->fd = dup(fd);
 	}
 
-	ictx->ccfg = &erofs_ccfg[inode->z_algorithmtype[0]];
+	ictx->ccfg = &sbi->zmgr->ccfg[inode->z_algorithmtype[0]];
 	inode->z_algorithmtype[0] = ictx->ccfg->algorithmtype;
 	inode->z_algorithmtype[1] = 0;
 
@@ -1844,8 +1849,15 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
 	u32 max_dict_size[Z_EROFS_COMPRESSION_MAX] = {};
 	u32 available_compr_algs = 0;
 
+	if (!sbi->zmgr) {
+		sbi->zmgr = calloc(1, sizeof(*sbi->zmgr));
+		if (!sbi->zmgr)
+			return -ENOMEM;
+	}
+
 	for (i = 0; cfg.c_compr_opts[i].alg; ++i) {
-		struct erofs_compress *c = &erofs_ccfg[i].handle;
+		struct erofs_compress_cfg *ccfg = &sbi->zmgr->ccfg[i];
+		struct erofs_compress *c = &ccfg->handle;
 
 		ret = erofs_compressor_init(sbi, c, cfg.c_compr_opts[i].alg,
 					    cfg.c_compr_opts[i].level,
@@ -1854,10 +1866,10 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
 			return ret;
 
 		id = z_erofs_get_compress_algorithm_id(c);
-		erofs_ccfg[i].algorithmtype = id;
-		erofs_ccfg[i].enable = true;
-		available_compr_algs |= 1 << erofs_ccfg[i].algorithmtype;
-		if (erofs_ccfg[i].algorithmtype != Z_EROFS_COMPRESSION_LZ4)
+		ccfg->algorithmtype = id;
+		ccfg->enable = true;
+		available_compr_algs |= 1 << ccfg->algorithmtype;
+		if (ccfg->algorithmtype != Z_EROFS_COMPRESSION_LZ4)
 			erofs_sb_set_compr_cfgs(sbi);
 		if (c->dict_size > max_dict_size[id])
 			max_dict_size[id] = c->dict_size;
@@ -1921,12 +1933,17 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi, struct erofs_buffer_head *s
 	return z_erofs_mt_init();
 }
 
-int z_erofs_compress_exit(void)
+int z_erofs_compress_exit(struct erofs_sb_info *sbi)
 {
 	int i, ret;
 
+	if (!sbi->zmgr) {
+		DBG_BUGON(1);
+		return -EINVAL;
+	}
+
 	for (i = 0; cfg.c_compr_opts[i].alg; ++i) {
-		ret = erofs_compressor_exit(&erofs_ccfg[i].handle);
+		ret = erofs_compressor_exit(&sbi->zmgr->ccfg[i].handle);
 		if (ret)
 			return ret;
 	}
diff --git a/mkfs/main.c b/mkfs/main.c
index 2907789..b2eff9d 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1491,7 +1491,7 @@ int main(int argc, char **argv)
 exit:
 	if (root)
 		erofs_iput(root);
-	z_erofs_compress_exit();
+	z_erofs_compress_exit(&g_sbi);
 	z_erofs_dedupe_exit();
 	z_erofs_dedupe_ext_exit();
 	blklst = erofs_blocklist_close();
-- 
2.43.5



More information about the Linux-erofs mailing list