74 lines
2.5 KiB
Diff
74 lines
2.5 KiB
Diff
From 3307caf863385f8b670a6b496083571a88d3c0bc Mon Sep 17 00:00:00 2001
|
|
From: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Date: Sun, 24 Nov 2024 22:57:01 -0500
|
|
Subject: [PATCH 121/233] bcachefs: Fix btree node scan when unknown btree IDs
|
|
are present
|
|
Content-Type: text/plain; charset="utf-8"
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
btree_root entries for unknown btree IDs are created during recovery,
|
|
before reading those btree roots.
|
|
|
|
But btree_node_scan may find btree nodes with unknown btree IDs when we
|
|
haven't seen roots for those btrees.
|
|
|
|
Reported-by: syzbot+1f202d4da221ec6ebf8e@syzkaller.appspotmail.com
|
|
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
|
|
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
|
|
---
|
|
fs/bcachefs/btree_cache.c | 11 ++++++++---
|
|
fs/bcachefs/btree_cache.h | 9 +++++++--
|
|
2 files changed, 15 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c
|
|
index 36dfa6a48aa6..1f06e24e53fc 100644
|
|
--- a/fs/bcachefs/btree_cache.c
|
|
+++ b/fs/bcachefs/btree_cache.c
|
|
@@ -1406,9 +1406,14 @@ void bch2_btree_id_level_to_text(struct printbuf *out, enum btree_id btree, unsi
|
|
void bch2_btree_pos_to_text(struct printbuf *out, struct bch_fs *c, const struct btree *b)
|
|
{
|
|
bch2_btree_id_to_text(out, b->c.btree_id);
|
|
- prt_printf(out, " level %u/%u\n ",
|
|
- b->c.level,
|
|
- bch2_btree_id_root(c, b->c.btree_id)->level);
|
|
+ prt_printf(out, " level %u/", b->c.level);
|
|
+ struct btree_root *r = bch2_btree_id_root(c, b->c.btree_id);
|
|
+ if (r)
|
|
+ prt_printf(out, "%u", r->level);
|
|
+ else
|
|
+ prt_printf(out, "(unknown)");
|
|
+ prt_printf(out, "\n ");
|
|
+
|
|
bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(&b->key));
|
|
}
|
|
|
|
diff --git a/fs/bcachefs/btree_cache.h b/fs/bcachefs/btree_cache.h
|
|
index 6cfacacb6769..dcc34fe4996d 100644
|
|
--- a/fs/bcachefs/btree_cache.h
|
|
+++ b/fs/bcachefs/btree_cache.h
|
|
@@ -128,14 +128,19 @@ static inline struct btree_root *bch2_btree_id_root(struct bch_fs *c, unsigned i
|
|
} else {
|
|
unsigned idx = id - BTREE_ID_NR;
|
|
|
|
- EBUG_ON(idx >= c->btree_roots_extra.nr);
|
|
+ /* This can happen when we're called from btree_node_scan */
|
|
+ if (idx >= c->btree_roots_extra.nr)
|
|
+ return NULL;
|
|
+
|
|
return &c->btree_roots_extra.data[idx];
|
|
}
|
|
}
|
|
|
|
static inline struct btree *btree_node_root(struct bch_fs *c, struct btree *b)
|
|
{
|
|
- return bch2_btree_id_root(c, b->c.btree_id)->b;
|
|
+ struct btree_root *r = bch2_btree_id_root(c, b->c.btree_id);
|
|
+
|
|
+ return r ? r->b : NULL;
|
|
}
|
|
|
|
const char *bch2_btree_id_str(enum btree_id); /* avoid */
|
|
--
|
|
2.45.2
|
|
|