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


Reply via email to