Skip to content

Commit 831faab

Browse files
committed
erofs: improve decompression error reporting
Change the return type of decompress() from `int` to `const char *` to provide more informative error diagnostics: - A NULL return indicates successful decompression; - If IS_ERR(ptr) is true, the return value encodes a standard negative errno (e.g., -ENOMEM, -EOPNOTSUPP) identifying the specific error; - Otherwise, a non-NULL return points to a human-readable error string, and the corresponding error code should be treated as -EFSCORRUPTED. Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
1 parent 9ae7719 commit 831faab

6 files changed

Lines changed: 40 additions & 37 deletions

File tree

fs/erofs/compress.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ struct z_erofs_decompress_req {
2323
struct z_erofs_decompressor {
2424
int (*config)(struct super_block *sb, struct erofs_super_block *dsb,
2525
void *data, int size);
26-
int (*decompress)(struct z_erofs_decompress_req *rq,
27-
struct page **pagepool);
26+
const char *(*decompress)(struct z_erofs_decompress_req *rq,
27+
struct page **pagepool);
2828
int (*init)(void);
2929
void (*exit)(void);
3030
char *name;

fs/erofs/decompressor.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,6 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_decompress_req *rq, u8 *dst
235235
rq->inputsize, rq->outputsize);
236236

237237
if (ret != rq->outputsize) {
238-
erofs_err(rq->sb, "failed to decompress %d in[%u, %u] out[%u]",
239-
ret, rq->inputsize, inputmargin, rq->outputsize);
240238
if (ret >= 0)
241239
memset(out + ret, 0, rq->outputsize - ret);
242240
ret = -EFSCORRUPTED;
@@ -257,8 +255,8 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_decompress_req *rq, u8 *dst
257255
return ret;
258256
}
259257

260-
static int z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq,
261-
struct page **pagepool)
258+
static const char *z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq,
259+
struct page **pagepool)
262260
{
263261
unsigned int dst_maptype;
264262
void *dst;
@@ -273,14 +271,14 @@ static int z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq,
273271
/* general decoding path which can be used for all cases */
274272
ret = z_erofs_lz4_prepare_dstpages(rq, pagepool);
275273
if (ret < 0)
276-
return ret;
274+
return ERR_PTR(ret);
277275
if (ret > 0) {
278276
dst = page_address(*rq->out);
279277
dst_maptype = 1;
280278
} else {
281279
dst = erofs_vm_map_ram(rq->out, rq->outpages);
282280
if (!dst)
283-
return -ENOMEM;
281+
return ERR_PTR(-ENOMEM);
284282
dst_maptype = 2;
285283
}
286284
}
@@ -289,19 +287,19 @@ static int z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq,
289287
kunmap_local(dst);
290288
else if (dst_maptype == 2)
291289
vm_unmap_ram(dst, rq->outpages);
292-
return ret;
290+
return ERR_PTR(ret);
293291
}
294292

295-
static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
296-
struct page **pagepool)
293+
static const char *z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
294+
struct page **pagepool)
297295
{
298296
const unsigned int nrpages_in = rq->inpages, nrpages_out = rq->outpages;
299297
const unsigned int bs = rq->sb->s_blocksize;
300298
unsigned int cur = 0, ni = 0, no, pi, po, insz, cnt;
301299
u8 *kin;
302300

303301
if (rq->outputsize > rq->inputsize)
304-
return -EOPNOTSUPP;
302+
return ERR_PTR(-EOPNOTSUPP);
305303
if (rq->alg == Z_EROFS_COMPRESSION_INTERLACED) {
306304
cur = bs - (rq->pageofs_out & (bs - 1));
307305
pi = (rq->pageofs_in + rq->inputsize - cur) & ~PAGE_MASK;
@@ -341,7 +339,7 @@ static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
341339
kunmap_local(kin);
342340
}
343341
DBG_BUGON(ni > nrpages_in);
344-
return 0;
342+
return NULL;
345343
}
346344

347345
int z_erofs_stream_switch_bufs(struct z_erofs_stream_dctx *dctx, void **dst,

fs/erofs/decompressor_deflate.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
157157
break;
158158
if (zerr == Z_STREAM_END && !rq->outputsize)
159159
break;
160-
erofs_err(sb, "failed to decompress %d in[%u] out[%u]",
161-
zerr, rq->inputsize, rq->outputsize);
162160
err = -EFSCORRUPTED;
163161
break;
164162
}
@@ -178,20 +176,20 @@ static int __z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
178176
return err;
179177
}
180178

181-
static int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
182-
struct page **pgpl)
179+
static const char *z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
180+
struct page **pgpl)
183181
{
184182
#ifdef CONFIG_EROFS_FS_ZIP_ACCEL
185183
int err;
186184

187185
if (!rq->partial_decoding) {
188186
err = z_erofs_crypto_decompress(rq, pgpl);
189187
if (err != -EOPNOTSUPP)
190-
return err;
188+
return ERR_PTR(err);
191189

192190
}
193191
#endif
194-
return __z_erofs_deflate_decompress(rq, pgpl);
192+
return ERR_PTR(__z_erofs_deflate_decompress(rq, pgpl));
195193
}
196194

197195
const struct z_erofs_decompressor z_erofs_deflate_decomp = {

fs/erofs/decompressor_lzma.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ static int z_erofs_load_lzma_config(struct super_block *sb,
146146
return err;
147147
}
148148

149-
static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
150-
struct page **pgpl)
149+
static const char *z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
150+
struct page **pgpl)
151151
{
152152
struct super_block *sb = rq->sb;
153153
struct z_erofs_stream_dctx dctx = { .rq = rq, .no = -1, .ni = 0 };
@@ -162,7 +162,7 @@ static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
162162
min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
163163
if (err) {
164164
kunmap_local(dctx.kin);
165-
return err;
165+
return ERR_PTR(err);
166166
}
167167

168168
/* 2. get an available lzma context */
@@ -207,8 +207,6 @@ static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
207207
if (xz_err != XZ_OK) {
208208
if (xz_err == XZ_STREAM_END && !rq->outputsize)
209209
break;
210-
erofs_err(sb, "failed to decompress %d in[%u] out[%u]",
211-
xz_err, rq->inputsize, rq->outputsize);
212210
err = -EFSCORRUPTED;
213211
break;
214212
}
@@ -223,7 +221,7 @@ static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
223221
z_erofs_lzma_head = strm;
224222
spin_unlock(&z_erofs_lzma_lock);
225223
wake_up(&z_erofs_lzma_wq);
226-
return err;
224+
return ERR_PTR(err);
227225
}
228226

229227
const struct z_erofs_decompressor z_erofs_lzma_decomp = {

fs/erofs/decompressor_zstd.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ static int z_erofs_load_zstd_config(struct super_block *sb,
135135
return strm ? -ENOMEM : 0;
136136
}
137137

138-
static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
139-
struct page **pgpl)
138+
static const char *z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
139+
struct page **pgpl)
140140
{
141141
struct super_block *sb = rq->sb;
142142
struct z_erofs_stream_dctx dctx = { .rq = rq, .no = -1, .ni = 0 };
@@ -152,7 +152,7 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
152152
min(rq->inputsize, sb->s_blocksize - rq->pageofs_in));
153153
if (err) {
154154
kunmap_local(dctx.kin);
155-
return err;
155+
return ERR_PTR(err);
156156
}
157157

158158
/* 2. get an available ZSTD context */
@@ -191,10 +191,6 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
191191
if (zstd_is_error(zerr) ||
192192
((rq->outputsize + dctx.avail_out) && (!zerr || (zerr > 0 &&
193193
!(rq->inputsize + in_buf.size - in_buf.pos))))) {
194-
erofs_err(sb, "failed to decompress in[%u] out[%u]: %s",
195-
rq->inputsize, rq->outputsize,
196-
zstd_is_error(zerr) ? zstd_get_error_name(zerr) :
197-
"unexpected end of stream");
198194
err = -EFSCORRUPTED;
199195
break;
200196
}
@@ -210,7 +206,7 @@ static int z_erofs_zstd_decompress(struct z_erofs_decompress_req *rq,
210206
z_erofs_zstd_head = strm;
211207
spin_unlock(&z_erofs_zstd_lock);
212208
wake_up(&z_erofs_zstd_wq);
213-
return err;
209+
return ERR_PTR(err);
214210
}
215211

216212
const struct z_erofs_decompressor z_erofs_zstd_decomp = {

fs/erofs/zdata.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,12 +1267,13 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, int err)
12671267
struct erofs_sb_info *const sbi = EROFS_SB(be->sb);
12681268
struct z_erofs_pcluster *pcl = be->pcl;
12691269
unsigned int pclusterpages = z_erofs_pclusterpages(pcl);
1270-
const struct z_erofs_decompressor *decomp =
1270+
const struct z_erofs_decompressor *alg =
12711271
z_erofs_decomp[pcl->algorithmformat];
1272+
bool try_free = true;
12721273
int i, j, jtop, err2;
12731274
struct page *page;
12741275
bool overlapped;
1275-
bool try_free = true;
1276+
const char *reason;
12761277

12771278
mutex_lock(&pcl->lock);
12781279
be->nr_pages = PAGE_ALIGN(pcl->length + pcl->pageofs_out) >> PAGE_SHIFT;
@@ -1304,8 +1305,8 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, int err)
13041305
err2 = z_erofs_parse_in_bvecs(be, &overlapped);
13051306
if (err2)
13061307
err = err2;
1307-
if (!err)
1308-
err = decomp->decompress(&(struct z_erofs_decompress_req) {
1308+
if (!err) {
1309+
reason = alg->decompress(&(struct z_erofs_decompress_req) {
13091310
.sb = be->sb,
13101311
.in = be->compressed_pages,
13111312
.out = be->decompressed_pages,
@@ -1322,6 +1323,18 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, int err)
13221323
.gfp = pcl->besteffort ? GFP_KERNEL :
13231324
GFP_NOWAIT | __GFP_NORETRY
13241325
}, be->pagepool);
1326+
if (IS_ERR(reason)) {
1327+
erofs_err(be->sb, "failed to decompress (%s) %ld @ pa %llu size %u => %u",
1328+
alg->name, PTR_ERR(reason), pcl->pos,
1329+
pcl->pclustersize, pcl->length);
1330+
err = PTR_ERR(reason);
1331+
} else if (unlikely(reason)) {
1332+
erofs_err(be->sb, "failed to decompress (%s) %s @ pa %llu size %u => %u",
1333+
alg->name, reason, pcl->pos,
1334+
pcl->pclustersize, pcl->length);
1335+
err = -EFSCORRUPTED;
1336+
}
1337+
}
13251338

13261339
/* must handle all compressed pages before actual file pages */
13271340
if (pcl->from_meta) {

0 commit comments

Comments
 (0)