]> www.infradead.org Git - linux.git/commitdiff
bcachefs: Improve decompression error messages
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 24 Jan 2025 14:23:02 +0000 (09:23 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 25 Jan 2025 19:43:13 +0000 (14:43 -0500)
Ratelimit them, and use the new bch2_write_op_error() helper that prints
path and file offset.

Reported-by: https://github.com/koverstreet/bcachefs/issues/819
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/compress.c
fs/bcachefs/compress.h
fs/bcachefs/io_write.c
fs/bcachefs/io_write.h

index f99ff18195979eeed794a1e87b88896491af3256..114bf2f3879f677a1d2952dd571ab60d214ddc77 100644 (file)
@@ -4,6 +4,7 @@
 #include "compress.h"
 #include "error.h"
 #include "extents.h"
+#include "io_write.h"
 #include "opts.h"
 #include "super-io.h"
 
@@ -254,11 +255,14 @@ err:
        goto out;
 }
 
-int bch2_bio_uncompress_inplace(struct bch_fs *c, struct bio *bio,
-                               struct bch_extent_crc_unpacked *crc)
+int bch2_bio_uncompress_inplace(struct bch_write_op *op,
+                               struct bio *bio)
 {
+       struct bch_fs *c = op->c;
+       struct bch_extent_crc_unpacked *crc = &op->crc;
        struct bbuf data = { NULL };
        size_t dst_len = crc->uncompressed_size << 9;
+       int ret = 0;
 
        /* bio must own its pages: */
        BUG_ON(!bio->bi_vcnt);
@@ -266,17 +270,26 @@ int bch2_bio_uncompress_inplace(struct bch_fs *c, struct bio *bio,
 
        if (crc->uncompressed_size << 9 > c->opts.encoded_extent_max ||
            crc->compressed_size << 9   > c->opts.encoded_extent_max) {
-               bch_err(c, "error rewriting existing data: extent too big");
+               struct printbuf buf = PRINTBUF;
+               bch2_write_op_error(&buf, op);
+               prt_printf(&buf, "error rewriting existing data: extent too big");
+               bch_err_ratelimited(c, "%s", buf.buf);
+               printbuf_exit(&buf);
                return -EIO;
        }
 
        data = __bounce_alloc(c, dst_len, WRITE);
 
        if (__bio_uncompress(c, bio, data.b, *crc)) {
-               if (!c->opts.no_data_io)
-                       bch_err(c, "error rewriting existing data: decompression error");
-               bio_unmap_or_unbounce(c, data);
-               return -EIO;
+               if (!c->opts.no_data_io) {
+                       struct printbuf buf = PRINTBUF;
+                       bch2_write_op_error(&buf, op);
+                       prt_printf(&buf, "error rewriting existing data: decompression error");
+                       bch_err_ratelimited(c, "%s", buf.buf);
+                       printbuf_exit(&buf);
+               }
+               ret = -EIO;
+               goto err;
        }
 
        /*
@@ -293,9 +306,9 @@ int bch2_bio_uncompress_inplace(struct bch_fs *c, struct bio *bio,
        crc->uncompressed_size  = crc->live_size;
        crc->offset             = 0;
        crc->csum               = (struct bch_csum) { 0, 0 };
-
+err:
        bio_unmap_or_unbounce(c, data);
-       return 0;
+       return ret;
 }
 
 int bch2_bio_uncompress(struct bch_fs *c, struct bio *src,
index 607fd5e232c902dbb39f3dac84ea2e214e6b106c..bec2f05bfd52ac63c72bc77e41d26a142809b289 100644 (file)
@@ -47,8 +47,8 @@ static inline enum bch_compression_type bch2_compression_opt_to_type(unsigned v)
        return __bch2_compression_opt_to_type[bch2_compression_decode(v).type];
 }
 
-int bch2_bio_uncompress_inplace(struct bch_fs *, struct bio *,
-                               struct bch_extent_crc_unpacked *);
+struct bch_write_op;
+int bch2_bio_uncompress_inplace(struct bch_write_op *, struct bio *);
 int bch2_bio_uncompress(struct bch_fs *, struct bio *, struct bio *,
                       struct bvec_iter, struct bch_extent_crc_unpacked);
 unsigned bch2_bio_compress(struct bch_fs *, struct bio *, size_t *,
index 3e71860f66b9e877b825e61daad8af97797e81df..dd508d93e9fc8d7b00fd9114d747eab7ddc28780 100644 (file)
@@ -406,7 +406,7 @@ static void __bch2_write_op_error(struct printbuf *out, struct bch_write_op *op,
                   op->flags & BCH_WRITE_MOVE ? "(internal move)" : "");
 }
 
-static void bch2_write_op_error(struct printbuf *out, struct bch_write_op *op)
+void bch2_write_op_error(struct printbuf *out, struct bch_write_op *op)
 {
        __bch2_write_op_error(out, op, op->pos.offset);
 }
@@ -873,7 +873,7 @@ static enum prep_encoded_ret {
                if (bch2_crc_cmp(op->crc.csum, csum) && !c->opts.no_data_io)
                        return PREP_ENCODED_CHECKSUM_ERR;
 
-               if (bch2_bio_uncompress_inplace(c, bio, &op->crc))
+               if (bch2_bio_uncompress_inplace(op, bio))
                        return PREP_ENCODED_ERR;
        }
 
index 5400ce94ee57db8fd54e89827d7a9b9b173c1e39..b4626013abc84a0633f816955c86f17a01df3e4c 100644 (file)
@@ -20,6 +20,8 @@ static inline void bch2_latency_acct(struct bch_dev *ca, u64 submit_time, int rw
 void bch2_submit_wbio_replicas(struct bch_write_bio *, struct bch_fs *,
                               enum bch_data_type, const struct bkey_i *, bool);
 
+void bch2_write_op_error(struct printbuf *out, struct bch_write_op *op);
+
 #define BCH_WRITE_FLAGS()              \
        x(ALLOC_NOWAIT)                 \
        x(CACHED)                       \