Signed-off-by: Gao Xiang <[email protected]>
---
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