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 <[email protected]>
---
 fs/bcachefs/compress.c | 31 ++++++++++++++++++++++---------
 fs/bcachefs/compress.h |  4 ++--
 fs/bcachefs/io_write.c |  4 ++--
 fs/bcachefs/io_write.h |  2 ++
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/fs/bcachefs/compress.c b/fs/bcachefs/compress.c
index f99ff1819597..114bf2f3879f 100644
--- a/fs/bcachefs/compress.c
+++ b/fs/bcachefs/compress.c
@@ -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 @@ static int __bio_uncompress(struct bch_fs *c, struct bio 
*src,
        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,
diff --git a/fs/bcachefs/compress.h b/fs/bcachefs/compress.h
index 607fd5e232c9..bec2f05bfd52 100644
--- a/fs/bcachefs/compress.h
+++ b/fs/bcachefs/compress.h
@@ -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 *,
diff --git a/fs/bcachefs/io_write.c b/fs/bcachefs/io_write.c
index 3e71860f66b9..dd508d93e9fc 100644
--- a/fs/bcachefs/io_write.c
+++ b/fs/bcachefs/io_write.c
@@ -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;
        }
 
diff --git a/fs/bcachefs/io_write.h b/fs/bcachefs/io_write.h
index 5400ce94ee57..b4626013abc8 100644
--- a/fs/bcachefs/io_write.h
+++ b/fs/bcachefs/io_write.h
@@ -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)                       \
-- 
2.45.2


Reply via email to