[PATCH] erofs-utils: lib: `fragment_size` should be 64 bits

Gao Xiang hsiangkao at linux.alibaba.com
Wed Nov 15 13:49:52 AEDT 2023


`-Eall-fragments` is broken if i_size is more than 32 bits.

Fixes: fcaa988a6ef6 ("erofs-utils: add `-Eall-fragments` option")
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/internal.h | 12 ++++++++----
 lib/compress.c           |  9 +++++----
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 78b9f32..82797e1 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -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)
diff --git a/lib/compress.c b/lib/compress.c
index 4eac363..47f1c1d 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -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);
-- 
2.39.3



More information about the Linux-erofs mailing list