Skip to content

Commit be9438f

Browse files
committed
btrfs: enhance compression error messages
Add more verbose and specific messages to all main error points in compression code for all algorithms. Currently there's no way to know which inode is affected or where in the data errors happened. The messages follow a common format: - what happened - error code if relevant - root and inode - additional data like offsets or lengths There's no helper for the messages as they differ in some details and that would be cumbersome to generalize to a single function. As all the errors are "almost never happens" there are the unlikely annotations done as compression is hot path. Signed-off-by: David Sterba <[email protected]>
1 parent ca84529 commit be9438f

File tree

3 files changed

+125
-44
lines changed

3 files changed

+125
-44
lines changed

fs/btrfs/lzo.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ int lzo_compress_folios(struct list_head *ws, struct address_space *mapping,
258258
workspace->cbuf, &out_len,
259259
workspace->mem);
260260
kunmap_local(data_in);
261-
if (ret < 0) {
262-
pr_debug("BTRFS: lzo in loop returned %d\n", ret);
261+
if (unlikely(ret < 0)) {
262+
/* lzo1x_1_compress never fails. */
263263
ret = -EIO;
264264
goto out;
265265
}
@@ -354,11 +354,14 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
354354
* and all sectors should be used.
355355
* If this happens, it means the compressed extent is corrupted.
356356
*/
357-
if (len_in > min_t(size_t, BTRFS_MAX_COMPRESSED, cb->compressed_len) ||
358-
round_up(len_in, sectorsize) < cb->compressed_len) {
357+
if (unlikely(len_in > min_t(size_t, BTRFS_MAX_COMPRESSED, cb->compressed_len) ||
358+
round_up(len_in, sectorsize) < cb->compressed_len)) {
359+
struct btrfs_inode *inode = cb->bbio.inode;
360+
359361
btrfs_err(fs_info,
360-
"invalid lzo header, lzo len %u compressed len %u",
361-
len_in, cb->compressed_len);
362+
"lzo header invalid, root %llu inode %llu offset %llu lzo len %u compressed len %u",
363+
btrfs_root_id(inode->root), btrfs_ino(inode),
364+
cb->start, len_in, cb->compressed_len);
362365
return -EUCLEAN;
363366
}
364367

@@ -383,13 +386,17 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
383386
kunmap_local(kaddr);
384387
cur_in += LZO_LEN;
385388

386-
if (seg_len > WORKSPACE_CBUF_LENGTH) {
389+
if (unlikely(seg_len > WORKSPACE_CBUF_LENGTH)) {
390+
struct btrfs_inode *inode = cb->bbio.inode;
391+
387392
/*
388393
* seg_len shouldn't be larger than we have allocated
389394
* for workspace->cbuf
390395
*/
391-
btrfs_err(fs_info, "unexpectedly large lzo segment len %u",
392-
seg_len);
396+
btrfs_err(fs_info,
397+
"lzo segment too big, root %llu inode %llu offset %llu len %u",
398+
btrfs_root_id(inode->root), btrfs_ino(inode),
399+
cb->start, seg_len);
393400
return -EIO;
394401
}
395402

@@ -399,8 +406,13 @@ int lzo_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
399406
/* Decompress the data */
400407
ret = lzo1x_decompress_safe(workspace->cbuf, seg_len,
401408
workspace->buf, &out_len);
402-
if (ret != LZO_E_OK) {
403-
btrfs_err(fs_info, "failed to decompress");
409+
if (unlikely(ret != LZO_E_OK)) {
410+
struct btrfs_inode *inode = cb->bbio.inode;
411+
412+
btrfs_err(fs_info,
413+
"lzo decompression failed, error %d root %llu inode %llu offset %llu",
414+
ret, btrfs_root_id(inode->root), btrfs_ino(inode),
415+
cb->start);
404416
return -EIO;
405417
}
406418

@@ -454,8 +466,13 @@ int lzo_decompress(struct list_head *ws, const u8 *data_in,
454466

455467
out_len = sectorsize;
456468
ret = lzo1x_decompress_safe(data_in, in_len, workspace->buf, &out_len);
457-
if (ret != LZO_E_OK) {
458-
pr_warn("BTRFS: decompress failed!\n");
469+
if (unlikely(ret != LZO_E_OK)) {
470+
struct btrfs_inode *inode = BTRFS_I(dest_page->mapping->host);
471+
472+
btrfs_err(fs_info,
473+
"lzo decompression failed, error %d root %llu inode %llu offset %llu",
474+
ret, btrfs_root_id(inode->root), btrfs_ino(inode),
475+
page_offset(dest_page));
459476
ret = -EIO;
460477
goto out;
461478
}

fs/btrfs/zlib.c

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/pagemap.h>
1919
#include <linux/bio.h>
2020
#include <linux/refcount.h>
21+
#include "btrfs_inode.h"
2122
#include "compression.h"
2223

2324
/* workspace buffer size for s390 zlib hardware support */
@@ -112,8 +113,13 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
112113
*total_out = 0;
113114
*total_in = 0;
114115

115-
if (Z_OK != zlib_deflateInit(&workspace->strm, workspace->level)) {
116-
pr_warn("BTRFS: deflateInit failed\n");
116+
ret = zlib_deflateInit(&workspace->strm, workspace->level);
117+
if (unlikely(ret != Z_OK)) {
118+
struct btrfs_inode *inode = BTRFS_I(mapping->host);
119+
120+
btrfs_err(inode->root->fs_info,
121+
"zlib compression init failed, error %d root %llu inode %llu offset %llu",
122+
ret, btrfs_root_id(inode->root), btrfs_ino(inode), start);
117123
ret = -EIO;
118124
goto out;
119125
}
@@ -182,9 +188,13 @@ int zlib_compress_folios(struct list_head *ws, struct address_space *mapping,
182188
}
183189

184190
ret = zlib_deflate(&workspace->strm, Z_SYNC_FLUSH);
185-
if (ret != Z_OK) {
186-
pr_debug("BTRFS: deflate in loop returned %d\n",
187-
ret);
191+
if (unlikely(ret != Z_OK)) {
192+
struct btrfs_inode *inode = BTRFS_I(mapping->host);
193+
194+
btrfs_warn(inode->root->fs_info,
195+
"zlib compression failed, error %d root %llu inode %llu offset %llu",
196+
ret, btrfs_root_id(inode->root), btrfs_ino(inode),
197+
start);
188198
zlib_deflateEnd(&workspace->strm);
189199
ret = -EIO;
190200
goto out;
@@ -307,9 +317,14 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
307317
workspace->strm.avail_in -= 2;
308318
}
309319

310-
if (Z_OK != zlib_inflateInit2(&workspace->strm, wbits)) {
311-
pr_warn("BTRFS: inflateInit failed\n");
320+
ret = zlib_inflateInit2(&workspace->strm, wbits);
321+
if (unlikely(ret != Z_OK)) {
322+
struct btrfs_inode *inode = cb->bbio.inode;
323+
312324
kunmap_local(data_in);
325+
btrfs_err(inode->root->fs_info,
326+
"zlib decompression init failed, error %d root %llu inode %llu offset %llu",
327+
ret, btrfs_root_id(inode->root), btrfs_ino(inode), cb->start);
313328
return -EIO;
314329
}
315330
while (workspace->strm.total_in < srclen) {
@@ -348,10 +363,15 @@ int zlib_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
348363
workspace->strm.avail_in = min(tmp, PAGE_SIZE);
349364
}
350365
}
351-
if (ret != Z_STREAM_END)
366+
if (unlikely(ret != Z_STREAM_END)) {
367+
btrfs_err(cb->bbio.inode->root->fs_info,
368+
"zlib decompression failed, error %d root %llu inode %llu offset %llu",
369+
ret, btrfs_root_id(cb->bbio.inode->root),
370+
btrfs_ino(cb->bbio.inode), cb->start);
352371
ret = -EIO;
353-
else
372+
} else {
354373
ret = 0;
374+
}
355375
done:
356376
zlib_inflateEnd(&workspace->strm);
357377
if (data_in)
@@ -386,8 +406,14 @@ int zlib_decompress(struct list_head *ws, const u8 *data_in,
386406
workspace->strm.avail_in -= 2;
387407
}
388408

389-
if (Z_OK != zlib_inflateInit2(&workspace->strm, wbits)) {
390-
pr_warn("BTRFS: inflateInit failed\n");
409+
ret = zlib_inflateInit2(&workspace->strm, wbits);
410+
if (unlikely(ret != Z_OK)) {
411+
struct btrfs_inode *inode = BTRFS_I(dest_page->mapping->host);
412+
413+
btrfs_err(inode->root->fs_info,
414+
"zlib decompression init failed, error %d root %llu inode %llu offset %llu",
415+
ret, btrfs_root_id(inode->root), btrfs_ino(inode),
416+
page_offset(dest_page));
391417
return -EIO;
392418
}
393419

@@ -404,8 +430,12 @@ int zlib_decompress(struct list_head *ws, const u8 *data_in,
404430

405431
out:
406432
if (unlikely(to_copy != destlen)) {
407-
pr_warn_ratelimited("BTRFS: inflate failed, decompressed=%lu expected=%zu\n",
408-
to_copy, destlen);
433+
struct btrfs_inode *inode = BTRFS_I(dest_page->mapping->host);
434+
435+
btrfs_err(inode->root->fs_info,
436+
"zlib decompression failed, error %d root %llu inode %llu offset %llu decompressed %lu expected %zu",
437+
ret, btrfs_root_id(inode->root), btrfs_ino(inode),
438+
page_offset(dest_page), to_copy, destlen);
409439
ret = -EIO;
410440
} else {
411441
ret = 0;

fs/btrfs/zstd.c

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/zstd.h>
2020
#include "misc.h"
2121
#include "fs.h"
22+
#include "btrfs_inode.h"
2223
#include "compression.h"
2324
#include "super.h"
2425

@@ -399,8 +400,13 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
399400
/* Initialize the stream */
400401
stream = zstd_init_cstream(&params, len, workspace->mem,
401402
workspace->size);
402-
if (!stream) {
403-
pr_warn("BTRFS: zstd_init_cstream failed\n");
403+
if (unlikely(!stream)) {
404+
struct btrfs_inode *inode = BTRFS_I(mapping->host);
405+
406+
btrfs_err(inode->root->fs_info,
407+
"zstd compression init level %d failed, root %llu inode %llu offset %llu",
408+
workspace->req_level, btrfs_root_id(inode->root),
409+
btrfs_ino(inode), start);
404410
ret = -EIO;
405411
goto out;
406412
}
@@ -429,9 +435,14 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
429435

430436
ret2 = zstd_compress_stream(stream, &workspace->out_buf,
431437
&workspace->in_buf);
432-
if (zstd_is_error(ret2)) {
433-
pr_debug("BTRFS: zstd_compress_stream returned %d\n",
434-
zstd_get_error_code(ret2));
438+
if (unlikely(zstd_is_error(ret2))) {
439+
struct btrfs_inode *inode = BTRFS_I(mapping->host);
440+
441+
btrfs_warn(inode->root->fs_info,
442+
"zstd compression level %d failed, error %d root %llu inode %llu offset %llu",
443+
workspace->req_level, zstd_get_error_code(ret2),
444+
btrfs_root_id(inode->root), btrfs_ino(inode),
445+
start);
435446
ret = -EIO;
436447
goto out;
437448
}
@@ -497,9 +508,14 @@ int zstd_compress_folios(struct list_head *ws, struct address_space *mapping,
497508
size_t ret2;
498509

499510
ret2 = zstd_end_stream(stream, &workspace->out_buf);
500-
if (zstd_is_error(ret2)) {
501-
pr_debug("BTRFS: zstd_end_stream returned %d\n",
502-
zstd_get_error_code(ret2));
511+
if (unlikely(zstd_is_error(ret2))) {
512+
struct btrfs_inode *inode = BTRFS_I(mapping->host);
513+
514+
btrfs_err(inode->root->fs_info,
515+
"zstd compression end level %d failed, error %d root %llu inode %llu offset %llu",
516+
workspace->req_level, zstd_get_error_code(ret2),
517+
btrfs_root_id(inode->root), btrfs_ino(inode),
518+
start);
503519
ret = -EIO;
504520
goto out;
505521
}
@@ -561,8 +577,12 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
561577

562578
stream = zstd_init_dstream(
563579
ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size);
564-
if (!stream) {
565-
pr_debug("BTRFS: zstd_init_dstream failed\n");
580+
if (unlikely(!stream)) {
581+
struct btrfs_inode *inode = cb->bbio.inode;
582+
583+
btrfs_err(inode->root->fs_info,
584+
"zstd decompression init failed, root %llu inode %llu offset %llu",
585+
btrfs_root_id(inode->root), btrfs_ino(inode), cb->start);
566586
ret = -EIO;
567587
goto done;
568588
}
@@ -580,9 +600,13 @@ int zstd_decompress_bio(struct list_head *ws, struct compressed_bio *cb)
580600

581601
ret2 = zstd_decompress_stream(stream, &workspace->out_buf,
582602
&workspace->in_buf);
583-
if (zstd_is_error(ret2)) {
584-
pr_debug("BTRFS: zstd_decompress_stream returned %d\n",
585-
zstd_get_error_code(ret2));
603+
if (unlikely(zstd_is_error(ret2))) {
604+
struct btrfs_inode *inode = cb->bbio.inode;
605+
606+
btrfs_err(inode->root->fs_info,
607+
"zstd decompression failed, error %d root %llu inode %llu offset %llu",
608+
zstd_get_error_code(ret2), btrfs_root_id(inode->root),
609+
btrfs_ino(inode), cb->start);
586610
ret = -EIO;
587611
goto done;
588612
}
@@ -637,8 +661,14 @@ int zstd_decompress(struct list_head *ws, const u8 *data_in,
637661

638662
stream = zstd_init_dstream(
639663
ZSTD_BTRFS_MAX_INPUT, workspace->mem, workspace->size);
640-
if (!stream) {
641-
pr_warn("BTRFS: zstd_init_dstream failed\n");
664+
if (unlikely(!stream)) {
665+
struct btrfs_inode *inode = BTRFS_I(dest_page->mapping->host);
666+
667+
btrfs_err(inode->root->fs_info,
668+
"zstd decompression init failed, root %llu inode %llu offset %llu",
669+
btrfs_root_id(inode->root), btrfs_ino(inode),
670+
page_offset(dest_page));
671+
ret = -EIO;
642672
goto finish;
643673
}
644674

@@ -655,9 +685,13 @@ int zstd_decompress(struct list_head *ws, const u8 *data_in,
655685
* one call should end the decompression.
656686
*/
657687
ret = zstd_decompress_stream(stream, &workspace->out_buf, &workspace->in_buf);
658-
if (zstd_is_error(ret)) {
659-
pr_warn_ratelimited("BTRFS: zstd_decompress_stream return %d\n",
660-
zstd_get_error_code(ret));
688+
if (unlikely(zstd_is_error(ret))) {
689+
struct btrfs_inode *inode = BTRFS_I(dest_page->mapping->host);
690+
691+
btrfs_err(inode->root->fs_info,
692+
"zstd decompression failed, error %d root %llu inode %llu offset %llu",
693+
zstd_get_error_code(ret), btrfs_root_id(inode->root),
694+
btrfs_ino(inode), page_offset(dest_page));
661695
goto finish;
662696
}
663697
to_copy = workspace->out_buf.pos;

0 commit comments

Comments
 (0)