linux-bcachefs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] bcachefs: btree_id_can_reconstruct(), btree_id_recovers_from_scan()
@ 2025-08-04 17:12 Kent Overstreet
  0 siblings, 0 replies; only message in thread
From: Kent Overstreet @ 2025-08-04 17:12 UTC (permalink / raw)
  To: linux-bcachefs; +Cc: Kent Overstreet

Add new helpers to clarify (and fix) repair strategies for different
btrees, and kill incorrect btree_id_is_alloc() use - it's not for
deciding how to repair.

btree node scan was incorrectly skipping BTREE_ID_alloc: while we can
reconstruct this one from scratch, it will fail by OOM on huge
filesystems, it's better to try btree node scan first

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
---
 fs/bcachefs/bcachefs_format.h | 32 ++++++++++++++++++++++++++++++--
 fs/bcachefs/btree_gc.c        | 23 +----------------------
 fs/bcachefs/btree_node_scan.c |  4 ++--
 fs/bcachefs/recovery.c        |  2 +-
 4 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
index a8f59522e258..19961b4f30b8 100644
--- a/fs/bcachefs/bcachefs_format.h
+++ b/fs/bcachefs/bcachefs_format.h
@@ -1438,9 +1438,9 @@ enum btree_id {
  */
 #define BTREE_ID_NR_MAX		63
 
-static inline bool btree_id_is_alloc(enum btree_id id)
+static inline bool btree_id_is_alloc(enum btree_id btree)
 {
-	switch (id) {
+	switch (btree) {
 	case BTREE_ID_alloc:
 	case BTREE_ID_backpointers:
 	case BTREE_ID_need_discard:
@@ -1454,6 +1454,34 @@ static inline bool btree_id_is_alloc(enum btree_id id)
 	}
 }
 
+/* We can reconstruct these btrees from information in other btrees */
+static inline bool btree_id_can_reconstruct(enum btree_id btree)
+{
+	if (btree_id_is_alloc(btree))
+		return true;
+
+	switch (btree) {
+	case BTREE_ID_snapshot_trees:
+	case BTREE_ID_deleted_inodes:
+	case BTREE_ID_logged_ops:
+	case BTREE_ID_rebalance_work:
+	case BTREE_ID_subvolume_children:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/*
+ * We can reconstruct BTREE_ID_alloc, but reconstucting it from scratch is not
+ * so cheap and OOMs on huge filesystems (until we have online
+ * check_allocations)
+ */
+static inline bool btree_id_recovers_from_scan(enum btree_id btree)
+{
+	return btree == BTREE_ID_alloc || !btree_id_can_reconstruct(btree);
+}
+
 #define BTREE_MAX_DEPTH		4U
 
 /* Btree nodes */
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
index 6b91649688da..cbf567679a85 100644
--- a/fs/bcachefs/btree_gc.c
+++ b/fs/bcachefs/btree_gc.c
@@ -44,27 +44,6 @@
 #include <linux/rcupdate.h>
 #include <linux/sched/task.h>
 
-/*
- * Returns true if it's a btree we can easily reconstruct, or otherwise won't
- * cause data loss if it's missing:
- */
-static bool btree_id_important(enum btree_id btree)
-{
-	if (btree_id_is_alloc(btree))
-		return false;
-
-	switch (btree) {
-	case BTREE_ID_quotas:
-	case BTREE_ID_snapshot_trees:
-	case BTREE_ID_logged_ops:
-	case BTREE_ID_rebalance_work:
-	case BTREE_ID_subvolume_children:
-		return false;
-	default:
-		return true;
-	}
-}
-
 static const char * const bch2_gc_phase_strs[] = {
 #define x(n)	#n,
 	GC_PHASES()
@@ -576,7 +555,7 @@ static int bch2_check_root(struct btree_trans *trans, enum btree_id btree,
 
 		if (!ret) {
 			__fsck_err(trans,
-				   FSCK_CAN_FIX|(!btree_id_important(btree) ? FSCK_AUTOFIX : 0),
+				   FSCK_CAN_FIX|(btree_id_can_reconstruct(btree) ? FSCK_AUTOFIX : 0),
 				   btree_root_unreadable_and_scan_found_nothing,
 				   "no nodes found for btree %s, continue?", buf.buf);
 
diff --git a/fs/bcachefs/btree_node_scan.c b/fs/bcachefs/btree_node_scan.c
index 4b7b5ca74ba1..6b747c053e91 100644
--- a/fs/bcachefs/btree_node_scan.c
+++ b/fs/bcachefs/btree_node_scan.c
@@ -149,7 +149,7 @@ static void try_read_btree_node(struct find_btree_nodes *f, struct bch_dev *ca,
 		bch2_encrypt(c, BSET_CSUM_TYPE(&bn->keys), nonce, &bn->flags, bytes);
 	}
 
-	if (btree_id_is_alloc(BTREE_NODE_ID(bn)))
+	if (btree_id_can_reconstruct(BTREE_NODE_ID(bn)))
 		return;
 
 	if (BTREE_NODE_LEVEL(bn) >= BTREE_MAX_DEPTH)
@@ -534,7 +534,7 @@ int bch2_btree_has_scanned_nodes(struct bch_fs *c, enum btree_id btree)
 int bch2_get_scanned_nodes(struct bch_fs *c, enum btree_id btree,
 			   unsigned level, struct bpos node_min, struct bpos node_max)
 {
-	if (btree_id_is_alloc(btree))
+	if (btree_id_recovers_from_scan(btree))
 		return 0;
 
 	struct find_btree_nodes *f = &c->found_btree_nodes;
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 21aa2edb13ac..29e81f96db0f 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -607,7 +607,7 @@ static int read_btree_roots(struct bch_fs *c)
 					c, btree_root_read_error,
 					"error reading btree root %s: %s",
 					buf.buf, bch2_err_str(ret))) {
-			if (btree_id_is_alloc(i))
+			if (btree_id_can_reconstruct(i))
 				r->error = 0;
 			ret = 0;
 		}
-- 
2.50.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2025-08-04 17:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-04 17:12 [PATCH] bcachefs: btree_id_can_reconstruct(), btree_id_recovers_from_scan() Kent Overstreet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).