[PATCH 1/2] erofs-utils: lib: migrate `c_max_decompressed_extent_bytes`

Gao Xiang hsiangkao at linux.alibaba.com
Wed Feb 18 15:54:06 AEDT 2026


Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/config.h   |  1 -
 include/erofs/importer.h |  3 +++
 lib/compress.c           | 45 ++++++++++++++++++++++++++++++++++++----
 lib/config.c             |  1 -
 lib/importer.c           |  2 ++
 mkfs/main.c              |  8 +++----
 6 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/include/erofs/config.h b/include/erofs/config.h
index 3758cc7c198e..bb303c48a0db 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -50,7 +50,6 @@ struct erofs_configure {
 	char *c_compress_hints_file;
 	char c_force_chunkformat;
 	u8 c_mkfs_metabox_algid;
-	u32 c_max_decompressed_extent_bytes;
 	const char *mount_point;
 	u32 c_root_xattr_isize;
 #ifdef EROFS_MT_ENABLED
diff --git a/include/erofs/importer.h b/include/erofs/importer.h
index a7a540d4d182..920488453c34 100644
--- a/include/erofs/importer.h
+++ b/include/erofs/importer.h
@@ -29,6 +29,8 @@ enum {
 	EROFS_FRAGDEDUPE_OFF,
 };
 
+#define EROFS_COMPRESSED_EXTENT_UNSPECIFIED	0
+
 struct erofs_importer_params {
 	struct z_erofs_paramset *z_paramsets;
 	char *source;
@@ -42,6 +44,7 @@ struct erofs_importer_params {
 	u32 pclusterblks_def;
 	u32 pclusterblks_packed;
 	s32 pclusterblks_metabox;
+	s32 max_compressed_extent_size;
 	s64 build_time;
 	char force_inodeversion;
 	bool ignore_mtime;
diff --git a/lib/compress.c b/lib/compress.c
index bbbf0e43d3fb..995bc602b145 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -53,6 +53,7 @@ struct z_erofs_compress_ictx {		/* inode context */
 	struct list_head extents;
 	u16 clusterofs;
 	int seg_num;
+	u32 max_compressed_extent_size;
 
 #if EROFS_MT_ENABLED
 	pthread_mutex_t mutex;
@@ -595,7 +596,7 @@ static int __z_erofs_compress_one(struct z_erofs_compress_sctx *ctx,
 			goto nocompression;
 	}
 
-	e->length = min(len, cfg.c_max_decompressed_extent_bytes);
+	e->length = min(len, ictx->max_compressed_extent_size);
 	if (data_unaligned) {
 		ret = erofs_compress(h, ctx->queue + ctx->head, e->length,
 				     dst, ctx->pclustersize);
@@ -1847,9 +1848,45 @@ void *erofs_prepare_compressed_file(struct erofs_importer *im,
 		ictx->ccfg = &sbi->zmgr->ccfg[inode->z_algorithmtype[0]];
 	inode->z_algorithmtype[0] = ictx->ccfg->algorithmtype;
 	inode->z_algorithmtype[1] = 0;
-	ictx->data_unaligned = erofs_sb_has_48bit(sbi) &&
-		cfg.c_max_decompressed_extent_bytes <=
-			z_erofs_get_pclustersize(ictx);
+
+	if (params->max_compressed_extent_size ==
+	    EROFS_COMPRESSED_EXTENT_UNSPECIFIED) {
+		if (erofs_sb_has_48bit(sbi) && ictx->ccfg->handle.alg->c->compress) {
+			ictx->max_compressed_extent_size =
+				z_erofs_get_pclustersize(ictx);
+			ictx->data_unaligned = true;
+		} else {
+			ictx->max_compressed_extent_size = UINT32_MAX;
+			ictx->data_unaligned = false;
+		}
+	} else if (params->max_compressed_extent_size <=
+		   (s32)z_erofs_get_pclustersize(ictx)) {
+		if (params->max_compressed_extent_size < 0) {
+			ictx->max_compressed_extent_size =
+				-params->max_compressed_extent_size;
+			if (!erofs_sb_has_48bit(sbi)) {
+				erofs_err("Unaligned compressed extents must be used with the 48bit encoded extent layout",
+					  ictx->max_compressed_extent_size);
+				free(ictx);
+				return ERR_PTR(-EINVAL);
+			}
+			ictx->data_unaligned = true;
+		} else {
+			ictx->max_compressed_extent_size =
+				params->max_compressed_extent_size;
+			if (erofs_sb_has_48bit(sbi))
+				ictx->data_unaligned = true;
+		}
+		if (ictx->max_compressed_extent_size < erofs_blksiz(sbi)) {
+			erofs_err("Maximum compressed extent size (%u) must be at least the block size (%u)",
+				  ictx->max_compressed_extent_size, erofs_blksiz(sbi));
+			return ERR_PTR(-EINVAL);
+		}
+	} else {
+		ictx->max_compressed_extent_size =
+			params->max_compressed_extent_size;
+		ictx->data_unaligned = false;
+	}
 	if (params->fragments && params->dedupe == EROFS_DEDUPE_FORCE_OFF &&
 	    !ictx->data_unaligned)
 		inode->z_advise |= Z_EROFS_ADVISE_INTERLACED_PCLUSTER;
diff --git a/lib/config.c b/lib/config.c
index 3398ded56ac1..ab7eb01e1914 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -29,7 +29,6 @@ void erofs_init_configure(void)
 	cfg.c_dbg_lvl  = EROFS_WARN;
 	cfg.c_version  = PACKAGE_VERSION;
 	cfg.c_dry_run  = false;
-	cfg.c_max_decompressed_extent_bytes = -1;
 	erofs_stdout_tty = isatty(STDOUT_FILENO);
 }
 
diff --git a/lib/importer.c b/lib/importer.c
index d686c519676b..26c86a0b0098 100644
--- a/lib/importer.c
+++ b/lib/importer.c
@@ -24,6 +24,8 @@ void erofs_importer_preset(struct erofs_importer_params *params)
 		.fixed_gid = -1,
 		.fsalignblks = 1,
 		.build_time = -1,
+		.max_compressed_extent_size =
+			EROFS_COMPRESSED_EXTENT_UNSPECIFIED,
 	};
 }
 
diff --git a/mkfs/main.c b/mkfs/main.c
index ee23944f3ebd..fb51cf87ef48 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1179,13 +1179,13 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 			break;
 #endif
 		case 9:
-			cfg.c_max_decompressed_extent_bytes =
-				strtoul(optarg, &endptr, 0);
-			if (*endptr != '\0') {
-				erofs_err("invalid maximum uncompressed extent size %s",
+			i = strtol(optarg, &endptr, 0);
+			if (*endptr != '\0' || i > INT32_MAX || i < INT32_MIN) {
+				erofs_err("invalid maximum compressed extent size %s",
 					  optarg);
 				return -EINVAL;
 			}
+			params->max_compressed_extent_size = i;
 			break;
 		case 10:
 			cfg.c_compress_hints_file = optarg;
-- 
2.43.5



More information about the Linux-erofs mailing list