erofs-utils: lib: `fragment_size` should be 64 bits
authorGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 15 Nov 2023 02:49:52 +0000 (10:49 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 15 Nov 2023 09:57:53 +0000 (17:57 +0800)
`-Eall-fragments` will be broken if i_size is more than 32 bits.

Fixes: fcaa988a6ef6 ("erofs-utils: add `-Eall-fragments` option")
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Yue Hu <huyue2@coolpad.com>
Link: https://lore.kernel.org/r/20231115024952.1256243-1-hsiangkao@linux.alibaba.com
include/erofs/internal.h
lib/compress.c

index 78b9f3229073bd4b47546862ac7bb799ba607e84..82797e1af545925fb5d31142edbcdece2b6d235b 100644 (file)
@@ -233,16 +233,20 @@ struct erofs_inode {
                        uint8_t  z_algorithmtype[2];
                        uint8_t  z_logical_clusterbits;
                        uint8_t  z_physical_clusterblks;
-                       uint64_t z_tailextent_headlcn;
-                       unsigned int    z_idataoff;
+                       union {
+                               uint64_t z_tailextent_headlcn;
+                               erofs_off_t fragment_size;
+                       };
+                       union {
+                               unsigned int z_idataoff;
+                               erofs_off_t fragmentoff;
+                       };
 #define z_idata_size   idata_size
                };
        };
 #ifdef WITH_ANDROID
        uint64_t capabilities;
 #endif
-       erofs_off_t fragmentoff;
-       unsigned int fragment_size;
 };
 
 static inline erofs_off_t erofs_iloc(struct erofs_inode *inode)
index 4eac3634455f87b881e95d81388fb70611e91a37..47f1c1d2c1f0c87b5421de740a7fbee4d7138c51 100644 (file)
@@ -373,9 +373,9 @@ static bool z_erofs_fixup_deduped_fragment(struct z_erofs_vle_compress_ctx *ctx,
 
        /* try to fix again if it gets larger (should be rare) */
        if (inode->fragment_size < newsize) {
-               ctx->pclustersize = min(z_erofs_get_max_pclustersize(inode),
-                                       roundup(newsize - inode->fragment_size,
-                                               erofs_blksiz(sbi)));
+               ctx->pclustersize = min_t(erofs_off_t, z_erofs_get_max_pclustersize(inode),
+                                         roundup(newsize - inode->fragment_size,
+                                                 erofs_blksiz(sbi)));
                return false;
        }
 
@@ -1005,7 +1005,8 @@ int erofs_write_compressed_file(struct erofs_inode *inode, int fd)
                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) {
+       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);