bcachefs: Include device in btree IO error messages
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 2 Feb 2021 22:08:54 +0000 (17:08 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:52 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_io.c
fs/bcachefs/btree_io.h
fs/bcachefs/debug.c

index 8ac50c9..6e656ed 100644 (file)
@@ -608,11 +608,16 @@ static void btree_pos_to_text(struct printbuf *out, struct bch_fs *c,
 }
 
 static void btree_err_msg(struct printbuf *out, struct bch_fs *c,
+                         struct bch_dev *ca,
                          struct btree *b, struct bset *i,
                          unsigned offset, int write)
 {
-       pr_buf(out, "error validating btree node %sat btree ",
-              write ? "before write " : "");
+       pr_buf(out, "error validating btree node ");
+       if (write)
+               pr_buf(out, "before write ");
+       if (ca)
+               pr_buf(out, "on %s ", ca->name);
+       pr_buf(out, "at btree ");
        btree_pos_to_text(out, c, b);
 
        pr_buf(out, "\n  node offset %u", b->written);
@@ -631,7 +636,7 @@ enum btree_validate_ret {
        BTREE_RETRY_READ = 64,
 };
 
-#define btree_err(type, c, b, i, msg, ...)                             \
+#define btree_err(type, c, ca, b, i, msg, ...)                         \
 ({                                                                     \
        __label__ out;                                                  \
        char _buf[300];                                                 \
@@ -642,7 +647,7 @@ enum btree_validate_ret {
        if (buf2)                                                       \
                out = _PBUF(buf2, 4986);                                \
                                                                        \
-       btree_err_msg(&out, c, b, i, b->written, write);                \
+       btree_err_msg(&out, c, ca, b, i, b->written, write);            \
        pr_buf(&out, ": " msg, ##__VA_ARGS__);                          \
                                                                        \
        if (type == BTREE_ERR_FIXABLE &&                                \
@@ -691,9 +696,9 @@ out:                                                                        \
 
 #define btree_err_on(cond, ...)        ((cond) ? btree_err(__VA_ARGS__) : false)
 
-static int validate_bset(struct bch_fs *c, struct btree *b,
-                        struct bset *i, unsigned sectors,
-                        int write, bool have_retry)
+static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
+                        struct btree *b, struct bset *i,
+                        unsigned sectors, int write, bool have_retry)
 {
        unsigned version = le16_to_cpu(i->version);
        const char *err;
@@ -702,18 +707,18 @@ static int validate_bset(struct bch_fs *c, struct btree *b,
        btree_err_on((version != BCH_BSET_VERSION_OLD &&
                      version < bcachefs_metadata_version_min) ||
                     version >= bcachefs_metadata_version_max,
-                    BTREE_ERR_FATAL, c, b, i,
+                    BTREE_ERR_FATAL, c, ca, b, i,
                     "unsupported bset version");
 
        if (btree_err_on(b->written + sectors > c->opts.btree_node_size,
-                        BTREE_ERR_FIXABLE, c, b, i,
+                        BTREE_ERR_FIXABLE, c, ca, b, i,
                         "bset past end of btree node")) {
                i->u64s = 0;
                return 0;
        }
 
        btree_err_on(b->written && !i->u64s,
-                    BTREE_ERR_FIXABLE, c, b, i,
+                    BTREE_ERR_FIXABLE, c, ca, b, i,
                     "empty bset");
 
        if (!b->written) {
@@ -727,16 +732,16 @@ static int validate_bset(struct bch_fs *c, struct btree *b,
 
                        /* XXX endianness */
                        btree_err_on(bp->seq != bn->keys.seq,
-                                    BTREE_ERR_MUST_RETRY, c, b, NULL,
+                                    BTREE_ERR_MUST_RETRY, c, ca, b, NULL,
                                     "incorrect sequence number (wrong btree node)");
                }
 
                btree_err_on(BTREE_NODE_ID(bn) != b->c.btree_id,
-                            BTREE_ERR_MUST_RETRY, c, b, i,
+                            BTREE_ERR_MUST_RETRY, c, ca, b, i,
                             "incorrect btree id");
 
                btree_err_on(BTREE_NODE_LEVEL(bn) != b->c.level,
-                            BTREE_ERR_MUST_RETRY, c, b, i,
+                            BTREE_ERR_MUST_RETRY, c, ca, b, i,
                             "incorrect level");
 
                if (BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN) {
@@ -759,7 +764,7 @@ static int validate_bset(struct bch_fs *c, struct btree *b,
                        }
 
                        btree_err_on(bkey_cmp(b->data->min_key, bp->min_key),
-                                    BTREE_ERR_MUST_RETRY, c, b, NULL,
+                                    BTREE_ERR_MUST_RETRY, c, ca, b, NULL,
                                     "incorrect min_key: got %llu:%llu should be %llu:%llu",
                                     b->data->min_key.inode,
                                     b->data->min_key.offset,
@@ -768,7 +773,7 @@ static int validate_bset(struct bch_fs *c, struct btree *b,
                }
 
                btree_err_on(bkey_cmp(bn->max_key, b->key.k.p),
-                            BTREE_ERR_MUST_RETRY, c, b, i,
+                            BTREE_ERR_MUST_RETRY, c, ca, b, i,
                             "incorrect max key %llu:%llu",
                             bn->max_key.inode,
                             bn->max_key.offset);
@@ -793,7 +798,7 @@ static int validate_bset(struct bch_fs *c, struct btree *b,
 #endif
                err = bch2_bkey_format_validate(&bn->format);
                btree_err_on(err,
-                            BTREE_ERR_FATAL, c, b, i,
+                            BTREE_ERR_FATAL, c, ca, b, i,
                             "invalid bkey format: %s", err);
 
                compat_bformat(b->c.level, b->c.btree_id, version,
@@ -825,14 +830,14 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
                const char *invalid;
 
                if (btree_err_on(bkey_next(k) > vstruct_last(i),
-                                BTREE_ERR_FIXABLE, c, b, i,
+                                BTREE_ERR_FIXABLE, c, NULL, b, i,
                                 "key extends past end of bset")) {
                        i->u64s = cpu_to_le16((u64 *) k - i->_data);
                        break;
                }
 
                if (btree_err_on(k->format > KEY_FORMAT_CURRENT,
-                                BTREE_ERR_FIXABLE, c, b, i,
+                                BTREE_ERR_FIXABLE, c, NULL, b, i,
                                 "invalid bkey format %u", k->format)) {
                        i->u64s = cpu_to_le16(le16_to_cpu(i->u64s) - k->u64s);
                        memmove_u64s_down(k, bkey_next(k),
@@ -855,7 +860,7 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
                        char buf[160];
 
                        bch2_bkey_val_to_text(&PBUF(buf), c, u.s_c);
-                       btree_err(BTREE_ERR_FIXABLE, c, b, i,
+                       btree_err(BTREE_ERR_FIXABLE, c, NULL, b, i,
                                  "invalid bkey: %s\n%s", invalid, buf);
 
                        i->u64s = cpu_to_le16(le16_to_cpu(i->u64s) - k->u64s);
@@ -889,7 +894,7 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
                        bch2_bkey_to_text(&PBUF(buf2), u.k);
 
                        bch2_dump_bset(c, b, i, 0);
-                       btree_err(BTREE_ERR_FATAL, c, b, i,
+                       btree_err(BTREE_ERR_FATAL, c, NULL, b, i,
                                  "keys out of order: %s > %s",
                                  buf1, buf2);
                        /* XXX: repair this */
@@ -902,7 +907,8 @@ fsck_err:
        return ret;
 }
 
-int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry)
+int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
+                             struct btree *b, bool have_retry)
 {
        struct btree_node_entry *bne;
        struct sort_iter *iter;
@@ -919,15 +925,15 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
        iter->size = (btree_blocks(c) + 1) * 2;
 
        if (bch2_meta_read_fault("btree"))
-               btree_err(BTREE_ERR_MUST_RETRY, c, b, NULL,
+               btree_err(BTREE_ERR_MUST_RETRY, c, ca, b, NULL,
                          "dynamic fault");
 
        btree_err_on(le64_to_cpu(b->data->magic) != bset_magic(c),
-                    BTREE_ERR_MUST_RETRY, c, b, NULL,
+                    BTREE_ERR_MUST_RETRY, c, ca, b, NULL,
                     "bad magic");
 
        btree_err_on(!b->data->keys.seq,
-                    BTREE_ERR_MUST_RETRY, c, b, NULL,
+                    BTREE_ERR_MUST_RETRY, c, ca, b, NULL,
                     "bad btree header");
 
        if (b->key.k.type == KEY_TYPE_btree_ptr_v2) {
@@ -935,7 +941,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                        &bkey_i_to_btree_ptr_v2(&b->key)->v;
 
                btree_err_on(b->data->keys.seq != bp->seq,
-                            BTREE_ERR_MUST_RETRY, c, b, NULL,
+                            BTREE_ERR_MUST_RETRY, c, ca, b, NULL,
                             "got wrong btree node (seq %llx want %llx)",
                             b->data->keys.seq, bp->seq);
        }
@@ -950,7 +956,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                        i = &b->data->keys;
 
                        btree_err_on(!bch2_checksum_type_valid(c, BSET_CSUM_TYPE(i)),
-                                    BTREE_ERR_WANT_RETRY, c, b, i,
+                                    BTREE_ERR_WANT_RETRY, c, ca, b, i,
                                     "unknown checksum type %llu",
                                     BSET_CSUM_TYPE(i));
 
@@ -958,7 +964,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                        csum = csum_vstruct(c, BSET_CSUM_TYPE(i), nonce, b->data);
 
                        btree_err_on(bch2_crc_cmp(csum, b->data->csum),
-                                    BTREE_ERR_WANT_RETRY, c, b, i,
+                                    BTREE_ERR_WANT_RETRY, c, ca, b, i,
                                     "invalid checksum");
 
                        bset_encrypt(c, i, b->written << 9);
@@ -978,7 +984,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                                break;
 
                        btree_err_on(!bch2_checksum_type_valid(c, BSET_CSUM_TYPE(i)),
-                                    BTREE_ERR_WANT_RETRY, c, b, i,
+                                    BTREE_ERR_WANT_RETRY, c, ca, b, i,
                                     "unknown checksum type %llu",
                                     BSET_CSUM_TYPE(i));
 
@@ -986,7 +992,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                        csum = csum_vstruct(c, BSET_CSUM_TYPE(i), nonce, bne);
 
                        btree_err_on(bch2_crc_cmp(csum, bne->csum),
-                                    BTREE_ERR_WANT_RETRY, c, b, i,
+                                    BTREE_ERR_WANT_RETRY, c, ca, b, i,
                                     "invalid checksum");
 
                        bset_encrypt(c, i, b->written << 9);
@@ -994,7 +1000,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                        sectors = vstruct_sectors(bne, c->block_bits);
                }
 
-               ret = validate_bset(c, b, i, sectors,
+               ret = validate_bset(c, ca, b, i, sectors,
                                    READ, have_retry);
                if (ret)
                        goto fsck_err;
@@ -1016,7 +1022,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                                        true);
 
                btree_err_on(blacklisted && first,
-                            BTREE_ERR_FIXABLE, c, b, i,
+                            BTREE_ERR_FIXABLE, c, ca, b, i,
                             "first btree node bset has blacklisted journal seq");
                if (blacklisted && !first)
                        continue;
@@ -1033,7 +1039,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
             bset_byte_offset(b, bne) < btree_bytes(c);
             bne = (void *) bne + block_bytes(c))
                btree_err_on(bne->keys.seq == b->data->keys.seq,
-                            BTREE_ERR_WANT_RETRY, c, b, NULL,
+                            BTREE_ERR_WANT_RETRY, c, ca, b, NULL,
                             "found bset signature after last bset");
 
        sorted = btree_bounce_alloc(c, btree_bytes(c), &used_mempool);
@@ -1068,7 +1074,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
                        char buf[160];
 
                        bch2_bkey_val_to_text(&PBUF(buf), c, u.s_c);
-                       btree_err(BTREE_ERR_FIXABLE, c, b, i,
+                       btree_err(BTREE_ERR_FIXABLE, c, NULL, b, i,
                                  "invalid bkey %s: %s", buf, invalid);
 
                        btree_keys_account_key_drop(&b->nr, 0, k);
@@ -1158,7 +1164,7 @@ start:
                                &failed, &rb->pick) > 0;
 
                if (!bio->bi_status &&
-                   !bch2_btree_node_read_done(c, b, can_retry))
+                   !bch2_btree_node_read_done(c, ca, b, can_retry))
                        break;
 
                if (!can_retry) {
@@ -1465,7 +1471,7 @@ static int validate_bset_for_write(struct bch_fs *c, struct btree *b,
        if (bch2_bkey_invalid(c, bkey_i_to_s_c(&b->key), BKEY_TYPE_BTREE))
                return -1;
 
-       ret = validate_bset(c, b, i, sectors, WRITE, false) ?:
+       ret = validate_bset(c, NULL, b, i, sectors, WRITE, false) ?:
                validate_bset_keys(c, b, i, &whiteout_u64s, WRITE, false);
        if (ret) {
                bch2_inconsistent_error(c);
index 3b61555..89685bd 100644 (file)
@@ -134,7 +134,8 @@ void bch2_btree_build_aux_trees(struct btree *);
 void bch2_btree_init_next(struct bch_fs *, struct btree *,
                         struct btree_iter *);
 
-int bch2_btree_node_read_done(struct bch_fs *, struct btree *, bool);
+int bch2_btree_node_read_done(struct bch_fs *, struct bch_dev *,
+                             struct btree *, bool);
 void bch2_btree_node_read(struct bch_fs *, struct btree *, bool);
 int bch2_btree_root_read(struct bch_fs *, enum btree_id,
                         const struct bkey_i *, unsigned);
index 0d5ec39..3ac700d 100644 (file)
@@ -79,7 +79,7 @@ void __bch2_btree_verify(struct bch_fs *c, struct btree *b)
 
        memcpy(n_ondisk, n_sorted, btree_bytes(c));
 
-       if (bch2_btree_node_read_done(c, v, false))
+       if (bch2_btree_node_read_done(c, ca, v, false))
                goto out;
 
        n_sorted = c->verify_data->data;