]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
erofs: improve Zstd, LZMA and DEFLATE error strings
authorGao Xiang <hsiangkao@linux.alibaba.com>
Thu, 27 Nov 2025 07:31:20 +0000 (15:31 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 28 Nov 2025 14:00:08 +0000 (22:00 +0800)
Enable better, more detailed, and unique error reporting.

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
fs/erofs/decompressor_deflate.c
fs/erofs/decompressor_lzma.c
fs/erofs/decompressor_zstd.c

index e9c4b740ef89262274f0b4831656e8a1c2cc4eef..46cc1fd19bcebd69dfc1a703c8ba2739a1c2a51c 100644 (file)
@@ -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 = {
index 7784ced901456d86ca303769a8257a1051e92e00..98a8c22cdbdef560f3689bdde4287e68ef860895 100644 (file)
@@ -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 = {
index 50fadff89cbc109813e98b5b743f569ceb76bdcf..aff6825cacde55b3be731474497f3f2b5368547f 100644 (file)
@@ -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 = {