diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index e7098e910a73..4ab59880781a 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -98,7 +98,7 @@ static int bch2_gc_check_topology(struct bch_fs *c, buf1.buf, buf2.buf) && !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) { 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; } else { set_bit(BCH_FS_INITIAL_GC_UNFIXED, &c->flags); @@ -126,7 +126,7 @@ static int bch2_gc_check_topology(struct bch_fs *c, buf1.buf, buf2.buf) && !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags)) { 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; } else { set_bit(BCH_FS_INITIAL_GC_UNFIXED, &c->flags); @@ -537,7 +537,7 @@ static int bch2_repair_topology(struct bch_fs *c) if (ret == DROP_THIS_NODE) { 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 (printbuf_reset(&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)) { - ret = FSCK_ERR_START_TOPOLOGY_REPAIR; + ret = -BCH_ERR_need_topology_repair; bch_info(c, "Halting mark and sweep to start topology repair pass"); goto fsck_err; } else { @@ -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, "btree root with incorrect min_key: %s", buf.buf)) { bch_err(c, "repair unimplemented"); - ret = FSCK_ERR_EXIT; + ret = -BCH_ERR_fsck_repair_unimplemented; goto fsck_err; } @@ -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, "btree root with incorrect max_key: %s", buf.buf)) { bch_err(c, "repair unimplemented"); - ret = FSCK_ERR_EXIT; + ret = -BCH_ERR_fsck_repair_unimplemented; goto fsck_err; } @@ -1777,7 +1777,7 @@ int bch2_gc(struct bch_fs *c, bool initial, bool 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_INITIAL_GC_DONE, &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) ret = 0; } - if (ret == FSCK_ERR_START_TOPOLOGY_REPAIR) - ret = FSCK_ERR_EXIT; + if (ret == -BCH_ERR_need_topology_repair) + ret = -BCH_ERR_fsck_errors_not_fixed; if (ret) goto out; diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index b7441677dc33..4254f7c7d85e 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -537,7 +537,7 @@ enum btree_validate_ret { struct printbuf out = PRINTBUF; \ \ 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 && \ write == READ && \ @@ -552,7 +552,7 @@ enum btree_validate_ret { \ switch (type) { \ case BTREE_ERR_FIXABLE: \ - ret = BCH_FSCK_ERRORS_NOT_FIXED; \ + ret = -BCH_ERR_fsck_errors_not_fixed; \ goto fsck_err; \ case BTREE_ERR_WANT_RETRY: \ if (have_retry) { \ @@ -564,7 +564,7 @@ enum btree_validate_ret { ret = BTREE_RETRY_READ; \ goto fsck_err; \ case BTREE_ERR_FATAL: \ - ret = BCH_FSCK_ERRORS_NOT_FIXED; \ + ret = -BCH_ERR_fsck_errors_not_fixed; \ goto fsck_err; \ } \ break; \ @@ -572,7 +572,7 @@ enum btree_validate_ret { bch_err(c, "corrupt metadata before write: %s", out.buf);\ \ if (bch2_fs_inconsistent(c)) { \ - ret = BCH_FSCK_ERRORS_NOT_FIXED; \ + ret = -BCH_ERR_fsck_errors_not_fixed; \ goto fsck_err; \ } \ break; \ diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h index 7972b018d2d0..95925c8434b3 100644 --- a/fs/bcachefs/errcode.h +++ b/fs/bcachefs/errcode.h @@ -7,7 +7,6 @@ x(0, freelist_empty) \ x(freelist_empty, no_buckets_found) \ x(0, insufficient_devices) \ - x(0, need_snapshot_cleanup) \ x(0, transaction_restart) \ x(transaction_restart, transaction_restart_fault_inject) \ x(transaction_restart, transaction_restart_relock) \ @@ -30,7 +29,15 @@ x(transaction_restart, transaction_restart_nested) \ x(0, lock_fail_node_reused) \ 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 { BCH_ERR_START = 2048, diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index 8279a9ba76a5..f6a895b2ceb7 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -68,8 +68,7 @@ void bch2_io_error(struct bch_dev *ca) #include "tools-util.h" #endif -enum fsck_err_ret bch2_fsck_err(struct bch_fs *c, unsigned flags, - const char *fmt, ...) +int bch2_fsck_err(struct bch_fs *c, unsigned flags, const char *fmt, ...) { struct fsck_err_state *s = NULL; va_list args; @@ -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) { bch_err(c, "fixing"); - return FSCK_ERR_FIX; + return -BCH_ERR_fsck_fix; } else { 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, if (fix) { set_bit(BCH_FS_ERRORS_FIXED, &c->flags); - return FSCK_ERR_FIX; + return -BCH_ERR_fsck_fix; } else { set_bit(BCH_FS_ERRORS_NOT_FIXED, &c->flags); set_bit(BCH_FS_ERROR, &c->flags); return c->opts.fix_errors == FSCK_OPT_EXIT || !(flags & FSCK_CAN_IGNORE) - ? FSCK_ERR_EXIT - : FSCK_ERR_IGNORE; + ? -BCH_ERR_fsck_errors_not_fixed + : -BCH_ERR_fsck_ignore; } } diff --git a/fs/bcachefs/error.h b/fs/bcachefs/error.h index 6e63c38186f3..b603d738c549 100644 --- a/fs/bcachefs/error.h +++ b/fs/bcachefs/error.h @@ -91,14 +91,6 @@ do { \ * 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 { FSCK_OPT_EXIT, FSCK_OPT_YES, @@ -106,13 +98,6 @@ enum fsck_err_opts { 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 list_head list; const char *fmt; @@ -127,21 +112,21 @@ struct fsck_err_state { #define FSCK_NO_RATELIMIT (1 << 3) __printf(3, 4) __cold -enum fsck_err_ret bch2_fsck_err(struct bch_fs *, - unsigned, const char *, ...); +int bch2_fsck_err(struct bch_fs *, unsigned, const char *, ...); void bch2_flush_fsck_errs(struct bch_fs *); #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"); \ - ret = BCH_FSCK_ERRORS_NOT_FIXED; \ + ret = _ret; \ goto fsck_err; \ } \ \ - _fix; \ + _ret == -BCH_ERR_fsck_fix; \ }) /* These macros return true if error should be fixed: */ diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 29d731a12436..306983811c1b 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -838,15 +838,14 @@ static int hash_check_key(struct btree_trans *trans, "hashed to %llu\n%s", bch2_btree_ids[desc.btree_id], hash_k.k->p.inode, hash_k.k->p.offset, hash, (printbuf_reset(&buf), - bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf)) == FSCK_ERR_IGNORE) - return 0; - - ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k); - if (ret) { - bch_err(c, "hash_redo_key err %s", bch2_err_str(ret)); - return ret; + bch2_bkey_val_to_text(&buf, c, hash_k), buf.buf))) { + ret = hash_redo_key(trans, desc, hash_info, k_iter, hash_k); + if (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: goto out; } @@ -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, "inode %llu:%u has incorrect i_sectors: got %llu, should be %llu", w->cur_inum, i->snapshot, - i->inode.bi_sectors, i->count) == FSCK_ERR_IGNORE) - continue; - - i->inode.bi_sectors = i->count; - ret = write_inode(trans, &i->inode, i->snapshot); - if (ret) - break; - ret2 = -BCH_ERR_transaction_restart_nested; + i->inode.bi_sectors, i->count)) { + i->inode.bi_sectors = i->count; + ret = write_inode(trans, &i->inode, i->snapshot); + if (ret) + break; + ret2 = -BCH_ERR_transaction_restart_nested; + } } fsck_err: if (ret) diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index 4b4a1d000219..acb2005c3b72 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -196,7 +196,7 @@ static void journal_entry_null_range(void *start, void *end) bch_err(c, "corrupt metadata before write:\n" \ msg, ##__VA_ARGS__); \ if (bch2_fs_inconsistent(c)) { \ - ret = BCH_FSCK_ERRORS_NOT_FIXED; \ + ret = -BCH_ERR_fsck_errors_not_fixed; \ goto fsck_err; \ } \ break; \ @@ -857,7 +857,7 @@ static int journal_read_bucket(struct bch_dev *ca, end - offset, sectors_read, READ); switch (ret) { - case BCH_FSCK_OK: + case 0: sectors = vstruct_sectors(j, c->block_bits); break; case JOURNAL_ENTRY_REREAD: diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index bb04b6f053cc..2cf347530b65 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1158,7 +1158,7 @@ int bch2_fs_recovery(struct bch_fs *c) use_clean: if (!clean) { bch_err(c, "no superblock clean section found"); - ret = BCH_FSCK_REPAIR_IMPOSSIBLE; + ret = -BCH_ERR_fsck_repair_impossible; goto err; } diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 87742962d6c2..fe7938e7e07b 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -927,31 +927,10 @@ int bch2_fs_start(struct bch_fs *c) up_write(&c->state_lock); return ret; err: - switch (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; - } + bch_err(c, "error starting filesystem: %s", bch2_err_str(ret)); - if (ret >= 0) - ret = -EIO; + if (ret < -BCH_ERR_START) + ret = -EINVAL; goto out; }