mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 23:13:00 +00:00
bcachefs: bch2_trans_verify_not_unlocked()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
e590e4e222
commit
fd104e2967
|
@ -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,
|
||||||
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)
|
||||||
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
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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 *,
|
||||||
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)
|
||||||
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 @@ out:
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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,
|
||||||
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));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user