bcachefs: Kill more -EIO error codes

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>
This commit is contained in:
Kent Overstreet 2024-02-06 17:24:18 -05:00
parent da23795e4c
commit 52946d828a
11 changed files with 27 additions and 20 deletions

View File

@ -131,8 +131,7 @@ static noinline int backpointer_mod_err(struct btree_trans *trans,
printbuf_exit(&buf); printbuf_exit(&buf);
if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers) { if (c->curr_recovery_pass > BCH_RECOVERY_PASS_check_extents_to_backpointers) {
bch2_inconsistent_error(c); return bch2_inconsistent_error(c) ? BCH_ERR_erofs_unfixed_errors : 0;
return -EIO;
} else { } else {
return 0; return 0;
} }

View File

@ -905,7 +905,7 @@ retry:
if (unlikely(btree_node_read_error(b))) { if (unlikely(btree_node_read_error(b))) {
six_unlock_type(&b->c.lock, lock_type); 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); 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))) { if (unlikely(btree_node_read_error(b))) {
six_unlock_type(&b->c.lock, lock_type); 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); EBUG_ON(b->c.btree_id != path->btree_id);
@ -1079,7 +1079,7 @@ lock_node:
if (unlikely(btree_node_read_error(b))) { if (unlikely(btree_node_read_error(b))) {
six_unlock_read(&b->c.lock); six_unlock_read(&b->c.lock);
b = ERR_PTR(-EIO); b = ERR_PTR(-BCH_ERR_btree_node_read_error);
goto out; goto out;
} }

View File

@ -407,7 +407,7 @@ again:
printbuf_reset(&buf); printbuf_reset(&buf);
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k)); 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, btree_node_unreadable,
"Topology repair: unreadable btree node at btree %s level %u:\n" "Topology repair: unreadable btree node at btree %s level %u:\n"
" %s", " %s",
@ -979,7 +979,7 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b
false); false);
ret = PTR_ERR_OR_ZERO(child); ret = PTR_ERR_OR_ZERO(child);
if (ret == -EIO) { if (bch2_err_matches(ret, EIO)) {
bch2_topology_error(c); bch2_topology_error(c);
if (__fsck_err(c, if (__fsck_err(c,

View File

@ -581,8 +581,7 @@ static int __btree_err(int ret,
break; break;
case -BCH_ERR_btree_node_read_err_bad_node: case -BCH_ERR_btree_node_read_err_bad_node:
bch2_print_string_as_lines(KERN_ERR, out.buf); bch2_print_string_as_lines(KERN_ERR, out.buf);
bch2_topology_error(c); ret = bch2_topology_error(c);
ret = bch2_run_explicit_recovery_pass(c, BCH_RECOVERY_PASS_check_topology) ?: -EIO;
break; break;
case -BCH_ERR_btree_node_read_err_incompatible: case -BCH_ERR_btree_node_read_err_incompatible:
bch2_print_string_as_lines(KERN_ERR, out.buf); 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); list_move(&b->list, &c->btree_cache.freeable);
mutex_unlock(&c->btree_cache.lock); mutex_unlock(&c->btree_cache.lock);
ret = -EIO; ret = -BCH_ERR_btree_node_read_error;
goto err; 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)); bch2_dev_list_has_dev(wbio->wbio.failed, ptr->dev));
if (!bch2_bkey_nr_ptrs(bkey_i_to_s_c(&wbio->key))) { 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; goto err;
} }

View File

@ -2307,7 +2307,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
btree_iter_path(trans, iter)->level); btree_iter_path(trans, iter)->level);
if (iter->flags & BTREE_ITER_WITH_JOURNAL) 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(iter);
bch2_btree_iter_verify_entry_exit(iter); bch2_btree_iter_verify_entry_exit(iter);

View File

@ -727,7 +727,7 @@ struct btree_root {
__BKEY_PADDED(key, BKEY_BTREE_PTR_VAL_U64s_MAX); __BKEY_PADDED(key, BKEY_BTREE_PTR_VAL_U64s_MAX);
u8 level; u8 level;
u8 alive; u8 alive;
s8 error; s16 error;
}; };
enum btree_gc_coalesce_fail_reason { enum btree_gc_coalesce_fail_reason {

View File

@ -1894,8 +1894,7 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
__func__, buf1.buf, buf2.buf); __func__, buf1.buf, buf2.buf);
printbuf_exit(&buf1); printbuf_exit(&buf1);
printbuf_exit(&buf2); printbuf_exit(&buf2);
bch2_topology_error(c); ret = bch2_topology_error(c);
ret = -EIO;
goto err; goto err;
} }

View File

@ -178,6 +178,7 @@
x(EINVAL, opt_parse_error) \ x(EINVAL, opt_parse_error) \
x(EINVAL, remove_with_metadata_missing_unimplemented)\ x(EINVAL, remove_with_metadata_missing_unimplemented)\
x(EINVAL, remove_would_lose_data) \ x(EINVAL, remove_would_lose_data) \
x(EINVAL, btree_iter_with_journal_not_supported) \
x(EROFS, erofs_trans_commit) \ x(EROFS, erofs_trans_commit) \
x(EROFS, erofs_no_writes) \ x(EROFS, erofs_no_writes) \
x(EROFS, erofs_journal_err) \ x(EROFS, erofs_journal_err) \
@ -227,7 +228,10 @@
x(BCH_ERR_operation_blocked, nocow_lock_blocked) \ x(BCH_ERR_operation_blocked, nocow_lock_blocked) \
x(EIO, btree_node_read_err) \ x(EIO, btree_node_read_err) \
x(EIO, sb_not_downgraded) \ 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_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_want_retry) \
x(BCH_ERR_btree_node_read_err, btree_node_read_err_must_retry) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_must_retry) \

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include "bcachefs.h" #include "bcachefs.h"
#include "error.h" #include "error.h"
#include "recovery.h"
#include "super.h" #include "super.h"
#include "thread_with_file.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); 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); 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) void bch2_fatal_error(struct bch_fs *c)

View File

@ -30,7 +30,7 @@ struct work_struct;
bool bch2_inconsistent_error(struct bch_fs *); 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, ...) \ #define bch2_fs_inconsistent(c, ...) \
({ \ ({ \

View File

@ -275,7 +275,7 @@ static int journal_replay_entry_early(struct bch_fs *c,
bkey_copy(&r->key, (struct bkey_i *) entry->start); bkey_copy(&r->key, (struct bkey_i *) entry->start);
r->error = 0; r->error = 0;
} else { } else {
r->error = -EIO; r->error = -BCH_ERR_btree_node_read_error;
} }
r->alive = true; r->alive = true;
break; break;