[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251127073122.2542542-2-hsiangkao@linux.alibaba.com>
Date: Thu, 27 Nov 2025 15:31:20 +0800
From: Gao Xiang <hsiangkao@...ux.alibaba.com>
To: linux-erofs@...ts.ozlabs.org
Cc: LKML <linux-kernel@...r.kernel.org>,
Gao Xiang <hsiangkao@...ux.alibaba.com>
Subject: [PATCH 2/4] erofs: improve Zstd, LZMA and DEFLATE error strings
Enable better, more detailed, and unique error reporting.
Signed-off-by: Gao Xiang <hsiangkao@...ux.alibaba.com>
---
fs/erofs/decompressor_deflate.c | 16 ++++++++++------
fs/erofs/decompressor_lzma.c | 7 +++++--
fs/erofs/decompressor_zstd.c | 8 +++++---
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c
index e9c4b740ef89..46cc1fd19bce 100644
--- a/fs/erofs/decompressor_deflate.c
+++ b/fs/erofs/decompressor_deflate.c
@@ -97,12 +97,13 @@ static int z_erofs_load_deflate_config(struct super_block *sb,
return -ENOMEM;
}
-static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
- struct page **pgpl)
+static const char *__z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
+ struct page **pgpl)
{
struct super_block *sb = rq->sb;
struct z_erofs_stream_dctx dctx = { .rq = rq, .no = -1, .ni = 0 };
struct z_erofs_deflate *strm;
+ const char *reason = NULL;
int zerr, err;
/* 1. get the exact DEFLATE compressed size */
@@ -111,7 +112,7 @@ static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
if (err) {
kunmap_local(dctx.kin);
- return err;
+ return ERR_PTR(err);
}
/* 2. get an available DEFLATE context */
@@ -129,7 +130,7 @@ static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
/* 3. multi-call decompress */
zerr = zlib_inflateInit2(&strm->z, -MAX_WBITS);
if (zerr != Z_OK) {
- err = -EIO;
+ err = -EINVAL;
goto failed_zinit;
}
@@ -157,6 +158,9 @@ static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
break;
if (zerr == Z_STREAM_END && !rq->outputsize)
break;
+ reason = (zerr == Z_DATA_ERROR ?
+ "corrupted compressed data" :
+ "unexpected end of stream");
err = -EFSCORRUPTED;
break;
}
@@ -173,7 +177,7 @@ static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
z_erofs_deflate_head = strm;
spin_unlock(&z_erofs_deflate_lock);
wake_up(&z_erofs_deflate_wq);
- return err;
+ return reason ?: ERR_PTR(err);
}
static const char *z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
@@ -189,7 +193,7 @@ static const char *z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
}
#endif
- return ERR_PTR(__z_erofs_deflate_decompress(rq, pgpl));
+ return __z_erofs_deflate_decompress(rq, pgpl);
}
const struct z_erofs_decompressor z_erofs_deflate_decomp = {
diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c
index 7784ced90145..98a8c22cdbde 100644
--- a/fs/erofs/decompressor_lzma.c
+++ b/fs/erofs/decompressor_lzma.c
@@ -154,6 +154,7 @@ static const char *z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
struct xz_buf buf = {};
struct z_erofs_lzma *strm;
enum xz_ret xz_err;
+ const char *reason = NULL;
int err;
/* 1. get the exact LZMA compressed size */
@@ -207,7 +208,9 @@ static const char *z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
if (xz_err != XZ_OK) {
if (xz_err == XZ_STREAM_END && !rq->outputsize)
break;
- err = -EFSCORRUPTED;
+ reason = (xz_err == XZ_DATA_ERROR ?
+ "corrupted compressed data" :
+ "unexpected end of stream");
break;
}
} while (1);
@@ -221,7 +224,7 @@ static const char *z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
z_erofs_lzma_head = strm;
spin_unlock(&z_erofs_lzma_lock);
wake_up(&z_erofs_lzma_wq);
- return ERR_PTR(err);
+ return reason ?: ERR_PTR(err);
}
const struct z_erofs_decompressor z_erofs_lzma_decomp = {
diff --git a/fs/erofs/decompressor_zstd.c b/fs/erofs/decompressor_zstd.c
index 50fadff89cbc..aff6825cacde 100644
--- a/fs/erofs/decompressor_zstd.c
+++ b/fs/erofs/decompressor_zstd.c
@@ -143,6 +143,7 @@ static const char *z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
zstd_in_buffer in_buf = { NULL, 0, 0 };
zstd_out_buffer out_buf = { NULL, 0, 0 };
struct z_erofs_zstd *strm;
+ const char *reason = NULL;
zstd_dstream *stream;
int zerr, err;
@@ -161,7 +162,7 @@ static const char *z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
/* 3. multi-call decompress */
stream = zstd_init_dstream(z_erofs_zstd_max_dictsize, strm->wksp, strm->wkspsz);
if (!stream) {
- err = -EIO;
+ err = -ENOMEM;
goto failed_zinit;
}
@@ -191,7 +192,8 @@ static const char *z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
if (zstd_is_error(zerr) ||
((rq->outputsize + dctx.avail_out) && (!zerr || (zerr > 0 &&
!(rq->inputsize + in_buf.size - in_buf.pos))))) {
- err = -EFSCORRUPTED;
+ reason = zstd_is_error(zerr) ? zstd_get_error_name(zerr) :
+ "unexpected end of stream";
break;
}
} while (rq->outputsize + dctx.avail_out);
@@ -206,7 +208,7 @@ static const char *z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
z_erofs_zstd_head = strm;
spin_unlock(&z_erofs_zstd_lock);
wake_up(&z_erofs_zstd_wq);
- return ERR_PTR(err);
+ return reason ?: ERR_PTR(err);
}
const struct z_erofs_decompressor z_erofs_zstd_decomp = {
--
2.43.5
Powered by blists - more mailing lists