bcachefs: Fix bch2_btree_trans_to_text()

bch2_btree_trans_to_text() is used to print btree_transactions owned by
other threads; thus, it needs to be particularly careful. This fixes a
null ptr deref caused by racing with the owning thread changing
path->l[].b.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
Kent Overstreet 2022-08-05 11:36:13 -04:00 committed by Kent Overstreet
parent ae33e7a274
commit 86b7445193
3 changed files with 10 additions and 12 deletions

View File

@ -3417,19 +3417,19 @@ void bch2_trans_exit(struct btree_trans *trans)
static void __maybe_unused
bch2_btree_path_node_to_text(struct printbuf *out,
struct btree_bkey_cached_common *_b,
struct btree_bkey_cached_common *b,
bool cached)
{
prt_printf(out, " l=%u %s:",
_b->level, bch2_btree_ids[_b->btree_id]);
bch2_bpos_to_text(out, btree_node_pos(_b, cached));
b->level, bch2_btree_ids[b->btree_id]);
bch2_bpos_to_text(out, btree_node_pos(b, cached));
}
#ifdef CONFIG_BCACHEFS_DEBUG_TRANSACTIONS
void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
{
struct btree_path *path;
struct btree *b;
struct btree_bkey_cached_common *b;
static char lock_types[] = { 'r', 'i', 'w' };
unsigned l;
@ -3448,12 +3448,11 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
prt_printf(out, "\n");
for (l = 0; l < BTREE_MAX_DEPTH; l++) {
if (btree_node_locked(path, l)) {
if (btree_node_locked(path, l) &&
(unsigned long) (b = (void *) READ_ONCE(path->l[l].b)) >= 128) {
prt_printf(out, " %s l=%u ",
btree_node_intent_locked(path, l) ? "i" : "r", l);
bch2_btree_path_node_to_text(out,
(void *) path->l[l].b,
path->cached);
bch2_btree_path_node_to_text(out, b, path->cached);
prt_printf(out, "\n");
}
}
@ -3471,8 +3470,7 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
bch2_bpos_to_text(out, trans->locking_pos);
prt_printf(out, " node ");
bch2_btree_path_node_to_text(out,
(void *) b, path->cached);
bch2_btree_path_node_to_text(out, b, path->cached);
prt_printf(out, "\n");
}
}

View File

@ -173,7 +173,7 @@ static inline int btree_node_lock_type(struct btree_trans *trans,
trans->locking_btree_id = path->btree_id;
trans->locking_level = level;
trans->locking_lock_type = type;
trans->locking = b;
trans->locking = &b->c;
ret = six_lock_type(&b->c.lock, type, should_sleep_fn, p);
trans->locking = NULL;

View File

@ -392,7 +392,7 @@ struct btree_trans {
const char *fn;
struct list_head list;
u64 last_begin_time;
struct btree *locking;
struct btree_bkey_cached_common *locking;
unsigned locking_path_idx;
struct bpos locking_pos;
u8 locking_btree_id;