mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
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:
parent
ae33e7a274
commit
86b7445193
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user