Commit 1ed0a5d2 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Convert fsck errors to errcode.h

Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent a0cb8d78
...@@ -98,7 +98,7 @@ static int bch2_gc_check_topology(struct bch_fs *c, ...@@ -98,7 +98,7 @@ static int bch2_gc_check_topology(struct bch_fs *c,
buf1.buf, buf2.buf) && buf1.buf, buf2.buf) &&
!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) { !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) {
bch_info(c, "Halting mark and sweep to start topology repair pass"); bch_info(c, "Halting mark and sweep to start topology repair pass");
ret = FSCK_ERR_START_TOPOLOGY_REPAIR; ret = -BCH_ERR_need_topology_repair;
goto err; goto err;
} else { } else {
set_bit(BCH_FS_INITIAL_GC_UNFIXED, &c->flags); set_bit(BCH_FS_INITIAL_GC_UNFIXED, &c->flags);
...@@ -126,7 +126,7 @@ static int bch2_gc_check_topology(struct bch_fs *c, ...@@ -126,7 +126,7 @@ static int bch2_gc_check_topology(struct bch_fs *c,
buf1.buf, buf2.buf) && buf1.buf, buf2.buf) &&
!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) { !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) {
bch_info(c, "Halting mark and sweep to start topology repair pass"); bch_info(c, "Halting mark and sweep to start topology repair pass");
ret = FSCK_ERR_START_TOPOLOGY_REPAIR; ret = -BCH_ERR_need_topology_repair;
goto err; goto err;
} else { } else {
set_bit(BCH_FS_INITIAL_GC_UNFIXED, &c->flags); set_bit(BCH_FS_INITIAL_GC_UNFIXED, &c->flags);
...@@ -537,7 +537,7 @@ static int bch2_repair_topology(struct bch_fs *c) ...@@ -537,7 +537,7 @@ static int bch2_repair_topology(struct bch_fs *c)
if (ret == DROP_THIS_NODE) { if (ret == DROP_THIS_NODE) {
bch_err(c, "empty btree root - repair unimplemented"); bch_err(c, "empty btree root - repair unimplemented");
ret = FSCK_ERR_EXIT; ret = -BCH_ERR_fsck_repair_unimplemented;
} }
} }
...@@ -960,7 +960,7 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b ...@@ -960,7 +960,7 @@ static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b
(printbuf_reset(&buf), (printbuf_reset(&buf),
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur.k)), buf.buf)) && bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur.k)), buf.buf)) &&
!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) { !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) {
ret = FSCK_ERR_START_TOPOLOGY_REPAIR; ret = -BCH_ERR_need_topology_repair;
bch_info(c, "Halting mark and sweep to start topology repair pass"); bch_info(c, "Halting mark and sweep to start topology repair pass");
goto fsck_err; goto fsck_err;
} else { } else {
...@@ -1013,7 +1013,7 @@ static int bch2_gc_btree_init(struct btree_trans *trans, ...@@ -1013,7 +1013,7 @@ static int bch2_gc_btree_init(struct btree_trans *trans,
if (mustfix_fsck_err_on(bpos_cmp(b->data->min_key, POS_MIN), c, if (mustfix_fsck_err_on(bpos_cmp(b->data->min_key, POS_MIN), c,
"btree root with incorrect min_key: %s", buf.buf)) { "btree root with incorrect min_key: %s", buf.buf)) {
bch_err(c, "repair unimplemented"); bch_err(c, "repair unimplemented");
ret = FSCK_ERR_EXIT; ret = -BCH_ERR_fsck_repair_unimplemented;
goto fsck_err; goto fsck_err;
} }
...@@ -1022,7 +1022,7 @@ static int bch2_gc_btree_init(struct btree_trans *trans, ...@@ -1022,7 +1022,7 @@ static int bch2_gc_btree_init(struct btree_trans *trans,
if (mustfix_fsck_err_on(bpos_cmp(b->data->max_key, SPOS_MAX), c, if (mustfix_fsck_err_on(bpos_cmp(b->data->max_key, SPOS_MAX), c,
"btree root with incorrect max_key: %s", buf.buf)) { "btree root with incorrect max_key: %s", buf.buf)) {
bch_err(c, "repair unimplemented"); bch_err(c, "repair unimplemented");
ret = FSCK_ERR_EXIT; ret = -BCH_ERR_fsck_repair_unimplemented;
goto fsck_err; goto fsck_err;
} }
...@@ -1777,7 +1777,7 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only) ...@@ -1777,7 +1777,7 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only)
ret = bch2_gc_btrees(c, initial, metadata_only); ret = bch2_gc_btrees(c, initial, metadata_only);
if (ret == FSCK_ERR_START_TOPOLOGY_REPAIR && if (ret == -BCH_ERR_need_topology_repair &&
!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) && !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) &&
!test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) { !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) {
set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags); set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
...@@ -1785,8 +1785,8 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only) ...@@ -1785,8 +1785,8 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only)
ret = 0; ret = 0;
} }
if (ret == FSCK_ERR_START_TOPOLOGY_REPAIR) if (ret == -BCH_ERR_need_topology_repair)
ret = FSCK_ERR_EXIT; ret = -BCH_ERR_fsck_errors_not_fixed;
if (ret) if (ret)
goto out; goto out;
......
...@@ -537,7 +537,7 @@ enum btree_validate_ret { ...@@ -537,7 +537,7 @@ enum btree_validate_ret {
struct printbuf out = PRINTBUF; \ struct printbuf out = PRINTBUF; \
\ \
btree_err_msg(&out, c, ca, b, i, b->written, write); \ btree_err_msg(&out, c, ca, b, i, b->written, write); \
prt_printf(&out, ": " msg, ##__VA_ARGS__); \ prt_printf(&out, ": " msg, ##__VA_ARGS__); \
\ \
if (type == BTREE_ERR_FIXABLE && \ if (type == BTREE_ERR_FIXABLE && \
write == READ && \ write == READ && \
...@@ -552,7 +552,7 @@ enum btree_validate_ret { ...@@ -552,7 +552,7 @@ enum btree_validate_ret {
\ \
switch (type) { \ switch (type) { \
case BTREE_ERR_FIXABLE: \ case BTREE_ERR_FIXABLE: \
ret = BCH_FSCK_ERRORS_NOT_FIXED; \ ret = -BCH_ERR_fsck_errors_not_fixed; \
goto fsck_err; \ goto fsck_err; \
case BTREE_ERR_WANT_RETRY: \ case BTREE_ERR_WANT_RETRY: \
if (have_retry) { \ if (have_retry) { \
...@@ -564,7 +564,7 @@ enum btree_validate_ret { ...@@ -564,7 +564,7 @@ enum btree_validate_ret {
ret = BTREE_RETRY_READ; \ ret = BTREE_RETRY_READ; \
goto fsck_err; \ goto fsck_err; \
case BTREE_ERR_FATAL: \ case BTREE_ERR_FATAL: \
ret = BCH_FSCK_ERRORS_NOT_FIXED; \ ret = -BCH_ERR_fsck_errors_not_fixed; \
goto fsck_err; \ goto fsck_err; \
} \ } \
break; \ break; \
...@@ -572,7 +572,7 @@ enum btree_validate_ret { ...@@ -572,7 +572,7 @@ enum btree_validate_ret {
bch_err(c, "corrupt metadata before write: %s", out.buf);\ bch_err(c, "corrupt metadata before write: %s", out.buf);\
\ \
if (bch2_fs_inconsistent(c)) { \ if (bch2_fs_inconsistent(c)) { \
ret = BCH_FSCK_ERRORS_NOT_FIXED; \ ret = -BCH_ERR_fsck_errors_not_fixed; \
goto fsck_err; \ goto fsck_err; \
} \ } \
break; \ break; \
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
x(0, freelist_empty) \ x(0, freelist_empty) \
x(freelist_empty, no_buckets_found) \ x(freelist_empty, no_buckets_found) \
x(0, insufficient_devices) \ x(0, insufficient_devices) \
x(0, need_snapshot_cleanup) \
x(0, transaction_restart) \ x(0, transaction_restart) \
x(transaction_restart, transaction_restart_fault_inject) \ x(transaction_restart, transaction_restart_fault_inject) \
x(transaction_restart, transaction_restart_relock) \ x(transaction_restart, transaction_restart_relock) \
...@@ -30,7 +29,15 @@ ...@@ -30,7 +29,15 @@
x(transaction_restart, transaction_restart_nested) \ x(transaction_restart, transaction_restart_nested) \
x(0, lock_fail_node_reused) \ x(0, lock_fail_node_reused) \
x(0, lock_fail_root_changed) \ x(0, lock_fail_root_changed) \
x(0, journal_reclaim_would_deadlock) x(0, journal_reclaim_would_deadlock) \
x(0, fsck) \
x(fsck, fsck_fix) \
x(fsck, fsck_ignore) \
x(fsck, fsck_errors_not_fixed) \
x(fsck, fsck_repair_unimplemented) \
x(fsck, fsck_repair_impossible) \
x(0, need_snapshot_cleanup) \
x(0, need_topology_repair)
enum bch_errcode { enum bch_errcode {
BCH_ERR_START = 2048, BCH_ERR_START = 2048,
......
...@@ -68,8 +68,7 @@ void bch2_io_error(struct bch_dev *ca) ...@@ -68,8 +68,7 @@ void bch2_io_error(struct bch_dev *ca)
#include "tools-util.h" #include "tools-util.h"
#endif #endif
enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags, int bch2_fsck_err(struct bch_fs *c, unsigned flags, const char *fmt, ...)
const char *fmt, ...)
{ {
struct fsck_err_state *s = NULL; struct fsck_err_state *s = NULL;
va_list args; va_list args;
...@@ -83,10 +82,10 @@ enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags, ...@@ -83,10 +82,10 @@ enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags,
if (c->opts.errors == BCH_ON_ERROR_continue) { if (c->opts.errors == BCH_ON_ERROR_continue) {
bch_err(c, "fixing"); bch_err(c, "fixing");
return FSCK_ERR_FIX; return -BCH_ERR_fsck_fix;
} else { } else {
bch2_inconsistent_error(c); bch2_inconsistent_error(c);
return FSCK_ERR_EXIT; return -BCH_ERR_fsck_errors_not_fixed;
} }
} }
...@@ -156,14 +155,14 @@ enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags, ...@@ -156,14 +155,14 @@ enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags,
if (fix) { if (fix) {
set_bit(BCH_FS_ERRORS_FIXED, &c->flags); set_bit(BCH_FS_ERRORS_FIXED, &c->flags);
return FSCK_ERR_FIX; return -BCH_ERR_fsck_fix;
} else { } else {
set_bit(BCH_FS_ERRORS_NOT_FIXED, &c->flags); set_bit(BCH_FS_ERRORS_NOT_FIXED, &c->flags);
set_bit(BCH_FS_ERROR, &c->flags); set_bit(BCH_FS_ERROR, &c->flags);
return c->opts.fix_errors == FSCK_OPT_EXIT || return c->opts.fix_errors == FSCK_OPT_EXIT ||
!(flags & FSCK_CAN_IGNORE) !(flags & FSCK_CAN_IGNORE)
? FSCK_ERR_EXIT ? -BCH_ERR_fsck_errors_not_fixed
: FSCK_ERR_IGNORE; : -BCH_ERR_fsck_ignore;
} }
} }
......
...@@ -91,14 +91,6 @@ do { \ ...@@ -91,14 +91,6 @@ do { \
* be able to repair: * be able to repair:
*/ */
enum {
BCH_FSCK_OK = 0,
BCH_FSCK_ERRORS_NOT_FIXED = 1,
BCH_FSCK_REPAIR_UNIMPLEMENTED = 2,
BCH_FSCK_REPAIR_IMPOSSIBLE = 3,
BCH_FSCK_UNKNOWN_VERSION = 4,
};
enum fsck_err_opts { enum fsck_err_opts {
FSCK_OPT_EXIT, FSCK_OPT_EXIT,
FSCK_OPT_YES, FSCK_OPT_YES,
...@@ -106,13 +98,6 @@ enum fsck_err_opts { ...@@ -106,13 +98,6 @@ enum fsck_err_opts {
FSCK_OPT_ASK, FSCK_OPT_ASK,
}; };
enum fsck_err_ret {
FSCK_ERR_IGNORE = 0,
FSCK_ERR_FIX = 1,
FSCK_ERR_EXIT = 2,
FSCK_ERR_START_TOPOLOGY_REPAIR = 3,
};
struct fsck_err_state { struct fsck_err_state {
struct list_head list; struct list_head list;
const char *fmt; const char *fmt;
...@@ -127,21 +112,21 @@ struct fsck_err_state { ...@@ -127,21 +112,21 @@ struct fsck_err_state {
#define FSCK_NO_RATELIMIT (1 << 3) #define FSCK_NO_RATELIMIT (1 << 3)
__printf(3, 4) __cold __printf(3, 4) __cold
enum fsck_err_ret bch2_fsck_err(struct bch_fs *, int bch2_fsck_err(struct bch_fs *, unsigned, const char *, ...);
unsigned, const char *, ...);
void bch2_flush_fsck_errs(struct bch_fs *); void bch2_flush_fsck_errs(struct bch_fs *);
#define __fsck_err(c, _flags, msg, ...) \ #define __fsck_err(c, _flags, msg, ...) \
({ \ ({ \
int _fix = bch2_fsck_err(c, _flags, msg, ##__VA_ARGS__);\ int _ret = bch2_fsck_err(c, _flags, msg, ##__VA_ARGS__); \
\ \
if (_fix == FSCK_ERR_EXIT) { \ if (_ret != -BCH_ERR_fsck_fix && \
_ret != -BCH_ERR_fsck_ignore) { \
bch_err(c, "Unable to continue, halting"); \ bch_err(c, "Unable to continue, halting"); \
ret = BCH_FSCK_ERRORS_NOT_FIXED; \ ret = _ret; \
goto fsck_err; \ goto fsck_err; \
} \ } \
\ \
_fix; \ _ret == -BCH_ERR_fsck_fix; \
}) })
/* These macros return true if error should be fixed: */ /* These macros return true if error should be fixed: */
......
...@@ -838,15 +838,14 @@ static int hash_check_key(struct btree_trans *trans, ...@@ -838,15 +838,14 @@ static int hash_check_key(struct btree_trans *trans,
"hashed to %llu\n%s", "hashed to %llu\n%s",
bch2_btree_ids[desc.btree_id], hash_k.k->p.inode, hash_k.k->p.offset, hash, bch2_btree_ids[desc.btree_id], hash_k.k->p.inode, hash_k.k->p.offset, hash,
(printbuf_reset(&buf), (printbuf_reset(&buf),
bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf)) == FSCK_ERR_IGNORE) bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) {
return 0; ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k);
if (ret) {
ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k); bch_err(c, "hash_redo_key err %s", bch2_err_str(ret));
if (ret) { return ret;
bch_err(c, "hash_redo_key err %s", bch2_err_str(ret)); }
return ret; ret = -BCH_ERR_transaction_restart_nested;
} }
ret = -BCH_ERR_transaction_restart_nested;
fsck_err: fsck_err:
goto out; goto out;
} }
...@@ -1137,14 +1136,13 @@ static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w) ...@@ -1137,14 +1136,13 @@ static int check_i_sectors(struct btree_trans *trans, struct inode_walker *w)
if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY), c, if (fsck_err_on(!(i->inode.bi_flags & BCH_INODE_I_SECTORS_DIRTY), c,
"inode %llu:%u has incorrect i_sectors: got %llu, should be %llu", "inode %llu:%u has incorrect i_sectors: got %llu, should be %llu",
w->cur_inum, i->snapshot, w->cur_inum, i->snapshot,
i->inode.bi_sectors, i->count) == FSCK_ERR_IGNORE) i->inode.bi_sectors, i->count)) {
continue; i->inode.bi_sectors = i->count;
ret = write_inode(trans, &i->inode, i->snapshot);
i->inode.bi_sectors = i->count; if (ret)
ret = write_inode(trans, &i->inode, i->snapshot); break;
if (ret) ret2 = -BCH_ERR_transaction_restart_nested;
break; }
ret2 = -BCH_ERR_transaction_restart_nested;
} }
fsck_err: fsck_err:
if (ret) if (ret)
......
...@@ -196,7 +196,7 @@ static void journal_entry_null_range(void *start, void *end) ...@@ -196,7 +196,7 @@ static void journal_entry_null_range(void *start, void *end)
bch_err(c, "corrupt metadata before write:\n" \ bch_err(c, "corrupt metadata before write:\n" \
msg, ##__VA_ARGS__); \ msg, ##__VA_ARGS__); \
if (bch2_fs_inconsistent(c)) { \ if (bch2_fs_inconsistent(c)) { \
ret = BCH_FSCK_ERRORS_NOT_FIXED; \ ret = -BCH_ERR_fsck_errors_not_fixed; \
goto fsck_err; \ goto fsck_err; \
} \ } \
break; \ break; \
...@@ -857,7 +857,7 @@ static int journal_read_bucket(struct bch_dev *ca, ...@@ -857,7 +857,7 @@ static int journal_read_bucket(struct bch_dev *ca,
end - offset, sectors_read, end - offset, sectors_read,
READ); READ);
switch (ret) { switch (ret) {
case BCH_FSCK_OK: case 0:
sectors = vstruct_sectors(j, c->block_bits); sectors = vstruct_sectors(j, c->block_bits);
break; break;
case JOURNAL_ENTRY_REREAD: case JOURNAL_ENTRY_REREAD:
......
...@@ -1158,7 +1158,7 @@ int bch2_fs_recovery(struct bch_fs *c) ...@@ -1158,7 +1158,7 @@ int bch2_fs_recovery(struct bch_fs *c)
use_clean: use_clean:
if (!clean) { if (!clean) {
bch_err(c, "no superblock clean section found"); bch_err(c, "no superblock clean section found");
ret = BCH_FSCK_REPAIR_IMPOSSIBLE; ret = -BCH_ERR_fsck_repair_impossible;
goto err; goto err;
} }
......
...@@ -927,31 +927,10 @@ int bch2_fs_start(struct bch_fs *c) ...@@ -927,31 +927,10 @@ int bch2_fs_start(struct bch_fs *c)
up_write(&c->state_lock); up_write(&c->state_lock);
return ret; return ret;
err: err:
switch (ret) { bch_err(c, "error starting filesystem: %s", bch2_err_str(ret));
case BCH_FSCK_ERRORS_NOT_FIXED:
bch_err(c, "filesystem contains errors: please report this to the developers");
pr_cont("mount with -o fix_errors to repair\n");
break;
case BCH_FSCK_REPAIR_UNIMPLEMENTED:
bch_err(c, "filesystem contains errors: please report this to the developers");
pr_cont("repair unimplemented: inform the developers so that it can be added\n");
break;
case BCH_FSCK_REPAIR_IMPOSSIBLE:
bch_err(c, "filesystem contains errors, but repair impossible");
break;
case BCH_FSCK_UNKNOWN_VERSION:
bch_err(c, "unknown metadata version");
break;
case -ENOMEM:
bch_err(c, "cannot allocate memory");
break;
case -EIO:
bch_err(c, "IO error");
break;
}
if (ret >= 0) if (ret < -BCH_ERR_START)
ret = -EIO; ret = -EINVAL;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment