From: Gao Xiang Date: Thu, 27 Nov 2025 07:31:20 +0000 (+0800) Subject: erofs: improve Zstd, LZMA and DEFLATE error strings X-Git-Tag: v6.19-rc1~165^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83564b06b275be083b1a7f707e1951dd506d7627;p=thirdparty%2Fkernel%2Flinux.git erofs: improve Zstd, LZMA and DEFLATE error strings Enable better, more detailed, and unique error reporting. Signed-off-by: Gao Xiang --- diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c index e9c4b740ef892..46cc1fd19bceb 100644 --- a/fs/erofs/decompressor_deflate.c +++ b/fs/erofs/decompressor_deflate.c @@ -97,12 +97,13 @@ failed: 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 @@ again: /* 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 @@ again: 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 @@ failed_zinit: 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 7784ced901456..98a8c22cdbdef 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 @@ again: 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 @@ again: 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 50fadff89cbc1..aff6825cacde5 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 @@ failed_zinit: 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 = {