[PATCH] erofs-utils: lib: fix missing CBLKCNT for big pcluster dedupe
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Nov 22 17:45:27 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>
---
lib/compress.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/lib/compress.c b/lib/compress.c
index 17b3213..50fea0c 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -186,11 +186,6 @@ static int z_erofs_compress_dedupe(struct erofs_inode *inode,
if (z_erofs_dedupe_match(&dctx))
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);
@@ -199,10 +194,24 @@ static int z_erofs_compress_dedupe(struct erofs_inode *inode,
ctx->e.length -= delta;
}
+ /*
+ * 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.
+ */
+ z_erofs_write_indexes(ctx);
+ if (dctx.e.compressedblks > 1 &&
+ ctx->clusterofs + dctx.e.length < 2*EROFS_BLKSIZ)
+ return ret;
+
+ /* 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();
+
erofs_dbg("Dedupe %u %scompressed data (delta %d) to %u of %u blocks",
dctx.e.length, dctx.e.raw ? "un" : "",
delta, dctx.e.blkaddr, dctx.e.compressedblks);
- z_erofs_write_indexes(ctx);
ctx->e = dctx.e;
ctx->head += dctx.e.length - delta;
DBG_BUGON(*len < dctx.e.length - delta);
--
2.30.2
More information about the Linux-erofs
mailing list