bcachefs: Convert write path errors to inum_to_path()
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 14 Nov 2024 04:08:57 +0000 (23:08 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Dec 2024 06:36:21 +0000 (01:36 -0500)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/io_write.c

index f97ebb30f6c026d149b4eb51be31c2c5fa1d2b86..bae045e76055740f1345614ef1f52ee52964d8df 100644 (file)
@@ -396,6 +396,21 @@ static int bch2_write_index_default(struct bch_write_op *op)
 
 /* Writes */
 
+static void __bch2_write_op_error(struct printbuf *out, struct bch_write_op *op,
+                                 u64 offset)
+{
+       bch2_inum_offset_err_msg(op->c, out,
+                                (subvol_inum) { op->subvol, op->pos.inode, },
+                                offset << 9);
+       prt_printf(out, "write error%s: ",
+                  op->flags & BCH_WRITE_MOVE ? "(internal move)" : "");
+}
+
+static void bch2_write_op_error(struct printbuf *out, struct bch_write_op *op)
+{
+       __bch2_write_op_error(out, op, op->pos.offset);
+}
+
 void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c,
                               enum bch_data_type type,
                               const struct bkey_i *k,
@@ -532,14 +547,14 @@ static void __bch2_write_index(struct bch_write_op *op)
 
                op->written += sectors_start - keylist_sectors(keys);
 
-               if (ret && !bch2_err_matches(ret, EROFS)) {
+               if (unlikely(ret && !bch2_err_matches(ret, EROFS))) {
                        struct bkey_i *insert = bch2_keylist_front(&op->insert_keys);
 
-                       bch_err_inum_offset_ratelimited(c,
-                               insert->k.p.inode, insert->k.p.offset << 9,
-                               "%s write error while doing btree update: %s",
-                               op->flags & BCH_WRITE_MOVE ? "move" : "user",
-                               bch2_err_str(ret));
+                       struct printbuf buf = PRINTBUF;
+                       __bch2_write_op_error(&buf, op, bkey_start_offset(&insert->k));
+                       prt_printf(&buf, "btree update error: %s", bch2_err_str(ret));
+                       bch_err_ratelimited(c, "%s", buf.buf);
+                       printbuf_exit(&buf);
                }
 
                if (ret)
@@ -1081,11 +1096,14 @@ do_write:
        *_dst = dst;
        return more;
 csum_err:
-       bch_err_inum_offset_ratelimited(c,
-               op->pos.inode,
-               op->pos.offset << 9,
-               "%s write error: error verifying existing checksum while rewriting existing data (memory corruption?)",
-               op->flags & BCH_WRITE_MOVE ? "move" : "user");
+       {
+               struct printbuf buf = PRINTBUF;
+               bch2_write_op_error(&buf, op);
+               prt_printf(&buf, "error verifying existing checksum while rewriting existing data (memory corruption?)");
+               bch_err_ratelimited(c, "%s", buf.buf);
+               printbuf_exit(&buf);
+       }
+
        ret = -EIO;
 err:
        if (to_wbio(dst)->bounce)
@@ -1176,11 +1194,11 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
                if (ret && !bch2_err_matches(ret, EROFS)) {
                        struct bkey_i *insert = bch2_keylist_front(&op->insert_keys);
 
-                       bch_err_inum_offset_ratelimited(c,
-                               insert->k.p.inode, insert->k.p.offset << 9,
-                               "%s write error while doing btree update: %s",
-                               op->flags & BCH_WRITE_MOVE ? "move" : "user",
-                               bch2_err_str(ret));
+                       struct printbuf buf = PRINTBUF;
+                       __bch2_write_op_error(&buf, op, bkey_start_offset(&insert->k));
+                       prt_printf(&buf, "btree update error: %s", bch2_err_str(ret));
+                       bch_err_ratelimited(c, "%s", buf.buf);
+                       printbuf_exit(&buf);
                }
 
                if (ret) {
@@ -1340,17 +1358,19 @@ err:
        if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
                goto retry;
 
+       bch2_trans_put(trans);
+       darray_exit(&buckets);
+
        if (ret) {
-               bch_err_inum_offset_ratelimited(c,
-                       op->pos.inode, op->pos.offset << 9,
-                       "%s: btree lookup error %s", __func__, bch2_err_str(ret));
+               struct printbuf buf = PRINTBUF;
+               bch2_write_op_error(&buf, op);
+               prt_printf(&buf, "%s(): btree lookup error: %s", __func__, bch2_err_str(ret));
+               bch_err_ratelimited(c, "%s", buf.buf);
+               printbuf_exit(&buf);
                op->error = ret;
                op->flags |= BCH_WRITE_SUBMITTED;
        }
 
-       bch2_trans_put(trans);
-       darray_exit(&buckets);
-
        /* fallback to cow write path? */
        if (!(op->flags & BCH_WRITE_SUBMITTED)) {
                closure_sync(&op->cl);
@@ -1463,14 +1483,14 @@ err:
                if (ret <= 0) {
                        op->flags |= BCH_WRITE_SUBMITTED;
 
-                       if (ret < 0) {
-                               if (!(op->flags & BCH_WRITE_ALLOC_NOWAIT))
-                                       bch_err_inum_offset_ratelimited(c,
-                                               op->pos.inode,
-                                               op->pos.offset << 9,
-                                               "%s(): %s error: %s", __func__,
-                                               op->flags & BCH_WRITE_MOVE ? "move" : "user",
-                                               bch2_err_str(ret));
+                       if (unlikely(ret < 0)) {
+                               if (!(op->flags & BCH_WRITE_ALLOC_NOWAIT)) {
+                                       struct printbuf buf = PRINTBUF;
+                                       bch2_write_op_error(&buf, op);
+                                       prt_printf(&buf, "%s(): %s", __func__, bch2_err_str(ret));
+                                       bch_err_ratelimited(c, "%s", buf.buf);
+                                       printbuf_exit(&buf);
+                               }
                                op->error = ret;
                                break;
                        }
@@ -1596,12 +1616,11 @@ CLOSURE_CALLBACK(bch2_write)
        bch2_keylist_init(&op->insert_keys, op->inline_keys);
        wbio_init(bio)->put_bio = false;
 
-       if (bio->bi_iter.bi_size & (c->opts.block_size - 1)) {
-               bch_err_inum_offset_ratelimited(c,
-                       op->pos.inode,
-                       op->pos.offset << 9,
-                       "%s write error: misaligned write",
-                       op->flags & BCH_WRITE_MOVE ? "move" : "user");
+       if (unlikely(bio->bi_iter.bi_size & (c->opts.block_size - 1))) {
+               struct printbuf buf = PRINTBUF;
+               bch2_write_op_error(&buf, op);
+               prt_printf(&buf, "misaligned write");
+               printbuf_exit(&buf);
                op->error = -EIO;
                goto err;
        }