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:
parent
da23795e4c
commit
52946d828a
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) \
|
||||||
|
@ -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)
|
||||||
|
@ -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, ...) \
|
||||||
({ \
|
({ \
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user