From 1ed0a5d280ef7a1183b42b2fcc13d919925f1b6e Mon Sep 17 00:00:00 2001
From: Kent Overstreet <kent.overstreet@gmail.com>
Date: Tue, 19 Jul 2022 17:20:18 -0400
Subject: [PATCH] bcachefs: Convert fsck errors to errcode.h

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
---
 fs/bcachefs/btree_gc.c   | 18 +++++++++---------
 fs/bcachefs/btree_io.c   |  8 ++++----
 fs/bcachefs/errcode.h    | 11 +++++++++--
 fs/bcachefs/error.c      | 13 ++++++-------
 fs/bcachefs/error.h      | 27 ++++++---------------------
 fs/bcachefs/fsck.c       | 30 ++++++++++++++----------------
 fs/bcachefs/journal_io.c |  4 ++--
 fs/bcachefs/recovery.c   |  2 +-
 fs/bcachefs/super.c      | 27 +++------------------------
 9 files changed, 54 insertions(+), 86 deletions(-)

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;
 }
 
-- 
2.30.9