bcachefs: Kill more -EIO error codes
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 6 Feb 2024 22:24:18 +0000 (17:24 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 14 Mar 2024 01:22:23 +0000 (21:22 -0400)
This converts -EIOs related to btree node errors to private error codes,
which will help with some ongoing debugging by giving us better error
messages.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/backpointers.c
fs/bcachefs/btree_cache.c
fs/bcachefs/btree_gc.c
fs/bcachefs/btree_io.c
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update_interior.c
fs/bcachefs/errcode.h
fs/bcachefs/error.c
fs/bcachefs/error.h
fs/bcachefs/recovery.c

index 569b97904da42eec8975e8662dd78895d41d62fe..f9ccefc74c49d1390f6becfa077346b72284a4e8 100644 (file)
@@ -131,8 +131,7 @@ static noinline int backpointer_mod_err(struct btree_trans *trans,
        printbuf_exit(&buf);
 
        if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers) {
-               bch2_inconsistent_error(c);
-               return -EIO;
+               return bch2_inconsistent_error(c) ? BCH_ERR_erofs_unfixed_errors : 0;
        } else {
                return 0;
        }
index 72d24933dc193d5a6f41a0d9adea73d82ae192fe..e8665258360e7c716452b9dba68cee129fd0fbc9 100644 (file)
@@ -905,7 +905,7 @@ retry:
 
        if (unlikely(btree_node_read_error(b))) {
                six_unlock_type(&b->c.lock, lock_type);
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-BCH_ERR_btree_node_read_error);
        }
 
        EBUG_ON(b->c.btree_id != path->btree_id);
@@ -996,7 +996,7 @@ struct btree *bch2_btree_node_get(struct btree_trans *trans, struct btree_path *
 
        if (unlikely(btree_node_read_error(b))) {
                six_unlock_type(&b->c.lock, lock_type);
-               return ERR_PTR(-EIO);
+               return ERR_PTR(-BCH_ERR_btree_node_read_error);
        }
 
        EBUG_ON(b->c.btree_id != path->btree_id);
@@ -1079,7 +1079,7 @@ lock_node:
 
        if (unlikely(btree_node_read_error(b))) {
                six_unlock_read(&b->c.lock);
-               b = ERR_PTR(-EIO);
+               b = ERR_PTR(-BCH_ERR_btree_node_read_error);
                goto out;
        }
 
index f4872f1d6fc614d8bc802cc79e51219d711d97b0..b7085e996c440c0212c5d767ac02d5229dca4b42 100644 (file)
@@ -407,7 +407,7 @@ again:
                printbuf_reset(&buf);
                bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k));
 
-               if (mustfix_fsck_err_on(ret == -EIO, c,
+               if (mustfix_fsck_err_on(bch2_err_matches(ret, EIO), c,
                                btree_node_unreadable,
                                "Topology repair: unreadable btree node at btree %s level %u:\n"
                                "  %s",
@@ -979,7 +979,7 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b
                                                false);
                        ret = PTR_ERR_OR_ZERO(child);
 
-                       if (ret == -EIO) {
+                       if (bch2_err_matches(ret, EIO)) {
                                bch2_topology_error(c);
 
                                if (__fsck_err(c,
index 767cdbe7f586198fb7050356174b4a327731f809..624c8287deb43191d39b130c842875f7aa1a9ff1 100644 (file)
@@ -581,8 +581,7 @@ static int __btree_err(int ret,
                break;
        case -BCH_ERR_btree_node_read_err_bad_node:
                bch2_print_string_as_lines(KERN_ERR, out.buf);
-               bch2_topology_error(c);
-               ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology) ?: -EIO;
+               ret = bch2_topology_error(c);
                break;
        case -BCH_ERR_btree_node_read_err_incompatible:
                bch2_print_string_as_lines(KERN_ERR, out.buf);
@@ -1746,7 +1745,7 @@ static int __bch2_btree_root_read(struct btree_trans *trans, enum btree_id id,
                list_move(&b->list, &c->btree_cache.freeable);
                mutex_unlock(&c->btree_cache.lock);
 
-               ret = -EIO;
+               ret = -BCH_ERR_btree_node_read_error;
                goto err;
        }
 
@@ -1850,7 +1849,7 @@ static void btree_node_write_work(struct work_struct *work)
                bch2_dev_list_has_dev(wbio->wbio.failed, ptr->dev));
 
        if (!bch2_bkey_nr_ptrs(bkey_i_to_s_c(&wbio->key))) {
-               ret = -BCH_ERR_btree_write_all_failed;
+               ret = -BCH_ERR_btree_node_write_all_failed;
                goto err;
        }
 
index 8f185a98f96f501a99fcc2123a0864d1d4a91e6f..4cb43c676ee13a9cff1576d078b35fa1da8aba59 100644 (file)
@@ -2307,7 +2307,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
                btree_iter_path(trans, iter)->level);
 
        if (iter->flags & BTREE_ITER_WITH_JOURNAL)
-               return bkey_s_c_err(-EIO);
+               return bkey_s_c_err(-BCH_ERR_btree_iter_with_journal_not_supported);
 
        bch2_btree_iter_verify(iter);
        bch2_btree_iter_verify_entry_exit(iter);
index 4a5a64499eb76698743ae7f20b4e47eaca09b868..94f996ef5d2b9ce1840d49dbf78ffd697a742345 100644 (file)
@@ -727,7 +727,7 @@ struct btree_root {
        __BKEY_PADDED(key, BKEY_BTREE_PTR_VAL_U64s_MAX);
        u8                      level;
        u8                      alive;
-       s                     error;
+       s16                     error;
 };
 
 enum btree_gc_coalesce_fail_reason {
index 8b0291cfa8727027f7c3effb144c4bbab68131d2..fd0bbce11765d7ab9c78aac5a3d14e8d5899bdc3 100644 (file)
@@ -1894,8 +1894,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
                        __func__, buf1.buf, buf2.buf);
                printbuf_exit(&buf1);
                printbuf_exit(&buf2);
-               bch2_topology_error(c);
-               ret = -EIO;
+               ret = bch2_topology_error(c);
                goto err;
        }
 
index 3fd33b307a77f943bea59882de951995d27987c5..a82a9d754fdab0d739dd518e70244f183f116694 100644 (file)
        x(EINVAL,                       opt_parse_error)                        \
        x(EINVAL,                       remove_with_metadata_missing_unimplemented)\
        x(EINVAL,                       remove_would_lose_data)                 \
+       x(EINVAL,                       btree_iter_with_journal_not_supported)  \
        x(EROFS,                        erofs_trans_commit)                     \
        x(EROFS,                        erofs_no_writes)                        \
        x(EROFS,                        erofs_journal_err)                      \
        x(BCH_ERR_operation_blocked,    nocow_lock_blocked)                     \
        x(EIO,                          btree_node_read_err)                    \
        x(EIO,                          sb_not_downgraded)                      \
-       x(EIO,                          btree_write_all_failed)                 \
+       x(EIO,                          btree_node_write_all_failed)            \
+       x(EIO,                          btree_node_read_error)                  \
+       x(EIO,                          btree_node_read_validate_error)         \
+       x(EIO,                          btree_need_topology_repair)             \
        x(BCH_ERR_btree_node_read_err,  btree_node_read_err_fixable)            \
        x(BCH_ERR_btree_node_read_err,  btree_node_read_err_want_retry)         \
        x(BCH_ERR_btree_node_read_err,  btree_node_read_err_must_retry)         \
index d32c8bebe46c32f7abc1a11ad49ee80752f2a623..043431206799d80a6e3eab43bd635947fa48db9f 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include "bcachefs.h"
 #include "error.h"
+#include "recovery.h"
 #include "super.h"
 #include "thread_with_file.h"
 
@@ -25,11 +26,16 @@ bool bch2_inconsistent_error(struct bch_fs *c)
        }
 }
 
-void bch2_topology_error(struct bch_fs *c)
+int bch2_topology_error(struct bch_fs *c)
 {
        set_bit(BCH_FS_topology_error, &c->flags);
-       if (!test_bit(BCH_FS_fsck_running, &c->flags))
+       if (!test_bit(BCH_FS_fsck_running, &c->flags)) {
                bch2_inconsistent_error(c);
+               return -BCH_ERR_btree_need_topology_repair;
+       } else {
+               return bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology) ?:
+                       -BCH_ERR_btree_node_read_validate_error;
+       }
 }
 
 void bch2_fatal_error(struct bch_fs *c)
index fec17d1353d18042ca77132106d2e2318de2be01..94491190e09e9d5085ca1ef87c5764c4192d6a24 100644 (file)
@@ -30,7 +30,7 @@ struct work_struct;
 
 bool bch2_inconsistent_error(struct bch_fs *);
 
-void bch2_topology_error(struct bch_fs *);
+int bch2_topology_error(struct bch_fs *);
 
 #define bch2_fs_inconsistent(c, ...)                                   \
 ({                                                                     \
index 39271d2d63d17e4fc16f7c06b294c1df42b05698..83f95d22fa81d5f1207397958b34e3b2842078a5 100644 (file)
@@ -275,7 +275,7 @@ static int journal_replay_entry_early(struct bch_fs *c,
                        bkey_copy(&r->key, (struct bkey_i *) entry->start);
                        r->error = 0;
                } else {
-                       r->error = -EIO;
+                       r->error = -BCH_ERR_btree_node_read_error;
                }
                r->alive = true;
                break;