[PATCH v2] erofs-utils: lib: fix missing CBLKCNT for big pcluster dedupe

Gao Xiang hsiangkao at linux.alibaba.com
Wed Nov 23 13:30:34 AEDT 2022


CBLKCNT needs to be stored for big pcluster dedupe.  Otherwise,
the decompression could fail due to incomplete compressed data.

Reported-by: Yue Hu <huyue2 at coolpad.com>
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
changes since v1:
 - fix potential data corruption of v1

 lib/compress.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/compress.c b/lib/compress.c
index 17b3213..8f4c63a 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -186,12 +186,22 @@ static int z_erofs_compress_dedupe(struct erofs_inode *inode,
 		if (z_erofs_dedupe_match(&dctx))
 			break;
 
+		delta = ctx->queue + ctx->head - dctx.cur;
+		/*
+		 * For big pcluster dedupe, leave two indices at least to store
+		 * CBLKCNT as the first step.  Even laterly, an one-block
+		 * decompresssion could be done as another try in practice.
+		 */
+		if (dctx.e.compressedblks > 1 &&
+		    (ctx->clusterofs + ctx->e.length - delta) % EROFS_BLKSIZ +
+			dctx.e.length < 2 * EROFS_BLKSIZ)
+			break;
+
 		/* fall back to noncompact indexes for deduplication */
 		inode->z_advise &= ~Z_EROFS_ADVISE_COMPACTED_2B;
 		inode->datalayout = EROFS_INODE_FLAT_COMPRESSION_LEGACY;
 		erofs_sb_set_dedupe();
 
-		delta = ctx->queue + ctx->head - dctx.cur;
 		if (delta) {
 			DBG_BUGON(delta < 0);
 			DBG_BUGON(!ctx->e.length);
-- 
2.24.4



More information about the Linux-erofs mailing list