Commit fd104e29 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bch2_trans_verify_not_unlocked()

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent e590e4e2
...@@ -1421,6 +1421,12 @@ void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans) ...@@ -1421,6 +1421,12 @@ void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans)
(void *) trans->last_restarted_ip); (void *) trans->last_restarted_ip);
} }
void __noreturn bch2_trans_unlocked_error(struct btree_trans *trans)
{
panic("trans should be locked, unlocked by %pS\n",
(void *) trans->last_unlock_ip);
}
noinline __cold noinline __cold
void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans) void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans)
{ {
...@@ -1690,6 +1696,7 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans, ...@@ -1690,6 +1696,7 @@ btree_path_idx_t bch2_path_get(struct btree_trans *trans,
struct trans_for_each_path_inorder_iter iter; struct trans_for_each_path_inorder_iter iter;
btree_path_idx_t path_pos = 0, path_idx; btree_path_idx_t path_pos = 0, path_idx;
bch2_trans_verify_not_unlocked(trans);
bch2_trans_verify_not_in_restart(trans); bch2_trans_verify_not_in_restart(trans);
bch2_trans_verify_locks(trans); bch2_trans_verify_locks(trans);
...@@ -1826,6 +1833,8 @@ bch2_btree_iter_traverse(struct btree_iter *iter) ...@@ -1826,6 +1833,8 @@ bch2_btree_iter_traverse(struct btree_iter *iter)
struct btree_trans *trans = iter->trans; struct btree_trans *trans = iter->trans;
int ret; int ret;
bch2_trans_verify_not_unlocked(trans);
iter->path = bch2_btree_path_set_pos(trans, iter->path, iter->path = bch2_btree_path_set_pos(trans, iter->path,
btree_iter_search_key(iter), btree_iter_search_key(iter),
iter->flags & BTREE_ITER_intent, iter->flags & BTREE_ITER_intent,
...@@ -2102,6 +2111,9 @@ struct bkey_s_c btree_trans_peek_key_cache(struct btree_iter *iter, struct bpos ...@@ -2102,6 +2111,9 @@ struct bkey_s_c btree_trans_peek_key_cache(struct btree_iter *iter, struct bpos
struct bkey_s_c k; struct bkey_s_c k;
int ret; int ret;
bch2_trans_verify_not_in_restart(trans);
bch2_trans_verify_not_unlocked(trans);
if ((iter->flags & BTREE_ITER_key_cache_fill) && if ((iter->flags & BTREE_ITER_key_cache_fill) &&
bpos_eq(iter->pos, pos)) bpos_eq(iter->pos, pos))
return bkey_s_c_null; return bkey_s_c_null;
...@@ -2240,6 +2252,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e ...@@ -2240,6 +2252,7 @@ struct bkey_s_c bch2_btree_iter_peek_upto(struct btree_iter *iter, struct bpos e
struct bpos iter_pos; struct bpos iter_pos;
int ret; int ret;
bch2_trans_verify_not_unlocked(trans);
EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bkey_eq(end, POS_MAX)); EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bkey_eq(end, POS_MAX));
if (iter->update_path) { if (iter->update_path) {
...@@ -2412,6 +2425,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter) ...@@ -2412,6 +2425,7 @@ struct bkey_s_c bch2_btree_iter_peek_prev(struct btree_iter *iter)
btree_path_idx_t saved_path = 0; btree_path_idx_t saved_path = 0;
int ret; int ret;
bch2_trans_verify_not_unlocked(trans);
EBUG_ON(btree_iter_path(trans, iter)->cached || EBUG_ON(btree_iter_path(trans, iter)->cached ||
btree_iter_path(trans, iter)->level); btree_iter_path(trans, iter)->level);
...@@ -2548,6 +2562,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter) ...@@ -2548,6 +2562,7 @@ struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)
struct bkey_s_c k; struct bkey_s_c k;
int ret; int ret;
bch2_trans_verify_not_unlocked(trans);
bch2_btree_iter_verify(iter); bch2_btree_iter_verify(iter);
bch2_btree_iter_verify_entry_exit(iter); bch2_btree_iter_verify_entry_exit(iter);
EBUG_ON(btree_iter_path(trans, iter)->level && (iter->flags & BTREE_ITER_with_key_cache)); EBUG_ON(btree_iter_path(trans, iter)->level && (iter->flags & BTREE_ITER_with_key_cache));
...@@ -3067,6 +3082,7 @@ u32 bch2_trans_begin(struct btree_trans *trans) ...@@ -3067,6 +3082,7 @@ u32 bch2_trans_begin(struct btree_trans *trans)
trans->notrace_relock_fail = false; trans->notrace_relock_fail = false;
} }
bch2_trans_verify_not_unlocked(trans);
return trans->restart_count; return trans->restart_count;
} }
......
...@@ -216,9 +216,13 @@ int __must_check bch2_btree_path_traverse_one(struct btree_trans *, ...@@ -216,9 +216,13 @@ int __must_check bch2_btree_path_traverse_one(struct btree_trans *,
btree_path_idx_t, btree_path_idx_t,
unsigned, unsigned long); unsigned, unsigned long);
static inline void bch2_trans_verify_not_unlocked(struct btree_trans *);
static inline int __must_check bch2_btree_path_traverse(struct btree_trans *trans, static inline int __must_check bch2_btree_path_traverse(struct btree_trans *trans,
btree_path_idx_t path, unsigned flags) btree_path_idx_t path, unsigned flags)
{ {
bch2_trans_verify_not_unlocked(trans);
if (trans->paths[path].uptodate < BTREE_ITER_NEED_RELOCK) if (trans->paths[path].uptodate < BTREE_ITER_NEED_RELOCK)
return 0; return 0;
...@@ -311,6 +315,14 @@ static inline void bch2_trans_verify_not_in_restart(struct btree_trans *trans) ...@@ -311,6 +315,14 @@ static inline void bch2_trans_verify_not_in_restart(struct btree_trans *trans)
bch2_trans_in_restart_error(trans); bch2_trans_in_restart_error(trans);
} }
void __noreturn bch2_trans_unlocked_error(struct btree_trans *);
static inline void bch2_trans_verify_not_unlocked(struct btree_trans *trans)
{
if (!trans->locked)
bch2_trans_unlocked_error(trans);
}
__always_inline __always_inline
static int btree_trans_restart_nounlock(struct btree_trans *trans, int err) static int btree_trans_restart_nounlock(struct btree_trans *trans, int err)
{ {
......
...@@ -773,14 +773,16 @@ static noinline __cold int bch2_trans_relock_fail(struct btree_trans *trans, str ...@@ -773,14 +773,16 @@ static noinline __cold int bch2_trans_relock_fail(struct btree_trans *trans, str
static inline int __bch2_trans_relock(struct btree_trans *trans, bool trace) static inline int __bch2_trans_relock(struct btree_trans *trans, bool trace)
{ {
struct btree_path *path; bch2_trans_verify_locks(trans);
unsigned i;
if (unlikely(trans->restarted)) if (unlikely(trans->restarted))
return -((int) trans->restarted); return -((int) trans->restarted);
if (unlikely(trans->locked)) if (unlikely(trans->locked))
goto out; goto out;
struct btree_path *path;
unsigned i;
trans_for_each_path(trans, path, i) { trans_for_each_path(trans, path, i) {
struct get_locks_fail f; struct get_locks_fail f;
...@@ -881,6 +883,11 @@ static bool bch2_trans_locked(struct btree_trans *trans) ...@@ -881,6 +883,11 @@ static bool bch2_trans_locked(struct btree_trans *trans)
void bch2_trans_verify_locks(struct btree_trans *trans) void bch2_trans_verify_locks(struct btree_trans *trans)
{ {
if (!trans->locked) {
BUG_ON(bch2_trans_locked(trans));
return;
}
struct btree_path *path; struct btree_path *path;
unsigned i; unsigned i;
......
...@@ -630,6 +630,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags, ...@@ -630,6 +630,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
unsigned u64s = 0; unsigned u64s = 0;
int ret; int ret;
bch2_trans_verify_not_unlocked(trans);
bch2_trans_verify_not_in_restart(trans);
if (race_fault()) { if (race_fault()) {
trace_and_count(c, trans_restart_fault_inject, trans, trace_ip); trace_and_count(c, trans_restart_fault_inject, trans, trace_ip);
return btree_trans_restart_nounlock(trans, BCH_ERR_transaction_restart_fault_inject); return btree_trans_restart_nounlock(trans, BCH_ERR_transaction_restart_fault_inject);
...@@ -1007,6 +1010,9 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags) ...@@ -1007,6 +1010,9 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
struct bch_fs *c = trans->c; struct bch_fs *c = trans->c;
int ret = 0; int ret = 0;
bch2_trans_verify_not_unlocked(trans);
bch2_trans_verify_not_in_restart(trans);
if (!trans->nr_updates && if (!trans->nr_updates &&
!trans->journal_entries_u64s) !trans->journal_entries_u64s)
goto out_reset; goto out_reset;
...@@ -1105,6 +1111,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags) ...@@ -1105,6 +1111,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
} }
retry: retry:
errored_at = NULL; errored_at = NULL;
bch2_trans_verify_not_unlocked(trans);
bch2_trans_verify_not_in_restart(trans); bch2_trans_verify_not_in_restart(trans);
if (likely(!(flags & BCH_TRANS_COMMIT_no_journal_res))) if (likely(!(flags & BCH_TRANS_COMMIT_no_journal_res)))
memset(&trans->journal_res, 0, sizeof(trans->journal_res)); memset(&trans->journal_res, 0, sizeof(trans->journal_res));
......
...@@ -1949,6 +1949,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans, ...@@ -1949,6 +1949,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
u64 start_time = local_clock(); u64 start_time = local_clock();
int ret = 0; int ret = 0;
bch2_trans_verify_not_in_restart(trans);
bch2_trans_verify_not_unlocked(trans);
BUG_ON(!trans->paths[path].should_be_locked); BUG_ON(!trans->paths[path].should_be_locked);
BUG_ON(!btree_node_locked(&trans->paths[path], level)); BUG_ON(!btree_node_locked(&trans->paths[path], level));
......
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