Commit abf23afa authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Fix btree node scan when unknown btree IDs are present



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: default avatar <syzbot+1f202d4da221ec6ebf8e@syzkaller.appspotmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 427db7ff
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -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));
}

+7 −2
Original line number Diff line number Diff line
@@ -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 */