Commit 86b74451 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

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: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent ae33e7a2
...@@ -3417,19 +3417,19 @@ void bch2_trans_exit(struct btree_trans *trans) ...@@ -3417,19 +3417,19 @@ void bch2_trans_exit(struct btree_trans *trans)
static void __maybe_unused static void __maybe_unused
bch2_btree_path_node_to_text(struct printbuf *out, bch2_btree_path_node_to_text(struct printbuf *out,
struct btree_bkey_cached_common *_b, struct btree_bkey_cached_common *b,
bool cached) bool cached)
{ {
prt_printf(out, " l=%u %s:", prt_printf(out, " l=%u %s:",
_b->level, bch2_btree_ids[_b->btree_id]); b->level, bch2_btree_ids[b->btree_id]);
bch2_bpos_to_text(out, btree_node_pos(_b, cached)); bch2_bpos_to_text(out, btree_node_pos(b, cached));
} }
#ifdef CONFIG_BCACHEFS_DEBUG_TRANSACTIONS #ifdef CONFIG_BCACHEFS_DEBUG_TRANSACTIONS
void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans) void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
{ {
struct btree_path *path; struct btree_path *path;
struct btree *b; struct btree_bkey_cached_common *b;
static char lock_types[] = { 'r', 'i', 'w' }; static char lock_types[] = { 'r', 'i', 'w' };
unsigned l; unsigned l;
...@@ -3448,12 +3448,11 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans) ...@@ -3448,12 +3448,11 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans)
prt_printf(out, "\n"); prt_printf(out, "\n");
for (l = 0; l < BTREE_MAX_DEPTH; l++) { 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 ", prt_printf(out, " %s l=%u ",
btree_node_intent_locked(path, l) ? "i" : "r", l); btree_node_intent_locked(path, l) ? "i" : "r", l);
bch2_btree_path_node_to_text(out, bch2_btree_path_node_to_text(out, b, path->cached);
(void *) path->l[l].b,
path->cached);
prt_printf(out, "\n"); prt_printf(out, "\n");
} }
} }
...@@ -3471,8 +3470,7 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct btree_trans *trans) ...@@ -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); bch2_bpos_to_text(out, trans->locking_pos);
prt_printf(out, " node "); prt_printf(out, " node ");
bch2_btree_path_node_to_text(out, bch2_btree_path_node_to_text(out, b, path->cached);
(void *) b, path->cached);
prt_printf(out, "\n"); prt_printf(out, "\n");
} }
} }
......
...@@ -173,7 +173,7 @@ static inline int btree_node_lock_type(struct btree_trans *trans, ...@@ -173,7 +173,7 @@ static inline int btree_node_lock_type(struct btree_trans *trans,
trans->locking_btree_id = path->btree_id; trans->locking_btree_id = path->btree_id;
trans->locking_level = level; trans->locking_level = level;
trans->locking_lock_type = type; trans->locking_lock_type = type;
trans->locking = b; trans->locking = &b->c;
ret = six_lock_type(&b->c.lock, type, should_sleep_fn, p); ret = six_lock_type(&b->c.lock, type, should_sleep_fn, p);
trans->locking = NULL; trans->locking = NULL;
......
...@@ -392,7 +392,7 @@ struct btree_trans { ...@@ -392,7 +392,7 @@ struct btree_trans {
const char *fn; const char *fn;
struct list_head list; struct list_head list;
u64 last_begin_time; u64 last_begin_time;
struct btree *locking; struct btree_bkey_cached_common *locking;
unsigned locking_path_idx; unsigned locking_path_idx;
struct bpos locking_pos; struct bpos locking_pos;
u8 locking_btree_id; u8 locking_btree_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment