bcachefs: bch2_trans_verify_not_unlocked()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 10 Apr 2024 00:14:21 +0000 (20:14 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:19 +0000 (17:29 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_locking.c
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_update_interior.c

index 7718630625ed78ebbb086a931006ce7d45328796..27f3935d67cb5fc3ed2f28d9b53151f53d20e16c 100644 (file)
@@ -1421,6 +1421,12 @@ void __noreturn bch2_trans_in_restart_error(struct btree_trans *trans)
              (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
 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;
        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_locks(trans);
 
@@ -1826,6 +1833,8 @@ bch2_btree_iter_traverse(struct btree_iter *iter)
        struct btree_trans *trans = iter->trans;
        int ret;
 
+       bch2_trans_verify_not_unlocked(trans);
+
        iter->path = bch2_btree_path_set_pos(trans, iter->path,
                                        btree_iter_search_key(iter),
                                        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;
        int ret;
 
+       bch2_trans_verify_not_in_restart(trans);
+       bch2_trans_verify_not_unlocked(trans);
+
        if ((iter->flags & BTREE_ITER_key_cache_fill) &&
            bpos_eq(iter->pos, pos))
                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;
        int ret;
 
+       bch2_trans_verify_not_unlocked(trans);
        EBUG_ON((iter->flags & BTREE_ITER_filter_snapshots) && bkey_eq(end, POS_MAX));
 
        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;
        int ret;
 
+       bch2_trans_verify_not_unlocked(trans);
        EBUG_ON(btree_iter_path(trans, iter)->cached ||
                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;
        int ret;
 
+       bch2_trans_verify_not_unlocked(trans);
        bch2_btree_iter_verify(iter);
        bch2_btree_iter_verify_entry_exit(iter);
        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;
        }
 
+       bch2_trans_verify_not_unlocked(trans);
        return trans->restart_count;
 }
 
index e4786610539029bb672939d50e7521bd242ca669..430b0d4848744b4a11426f79477a6ef4eff82052 100644 (file)
@@ -216,9 +216,13 @@ int __must_check bch2_btree_path_traverse_one(struct btree_trans *,
                                              btree_path_idx_t,
                                              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,
                                          btree_path_idx_t path, unsigned flags)
 {
+       bch2_trans_verify_not_unlocked(trans);
+
        if (trans->paths[path].uptodate < BTREE_ITER_NEED_RELOCK)
                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);
 }
 
+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
 static int btree_trans_restart_nounlock(struct btree_trans *trans, int err)
 {
index 7824a7a2e50f7059b5732153edfa96b9de03330f..c3e9b0cc7bbdc9ece6ee8da4966a43838f64df9e 100644 (file)
@@ -773,14 +773,16 @@ out:
 
 static inline int __bch2_trans_relock(struct btree_trans *trans, bool trace)
 {
-       struct btree_path *path;
-       unsigned i;
+       bch2_trans_verify_locks(trans);
 
        if (unlikely(trans->restarted))
                return -((int) trans->restarted);
        if (unlikely(trans->locked))
                goto out;
 
+       struct btree_path *path;
+       unsigned i;
+
        trans_for_each_path(trans, path, i) {
                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)
 {
+       if (!trans->locked) {
+               BUG_ON(bch2_trans_locked(trans));
+               return;
+       }
+
        struct btree_path *path;
        unsigned i;
 
index 04831c9e603cc7169f203738957fe92ac2d54f4e..0bf7c70da4175ab1a36a82dd3f08ca2723df79d6 100644 (file)
@@ -630,6 +630,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
        unsigned u64s = 0;
        int ret;
 
+       bch2_trans_verify_not_unlocked(trans);
+       bch2_trans_verify_not_in_restart(trans);
+
        if (race_fault()) {
                trace_and_count(c, trans_restart_fault_inject, trans, trace_ip);
                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;
        int ret = 0;
 
+       bch2_trans_verify_not_unlocked(trans);
+       bch2_trans_verify_not_in_restart(trans);
+
        if (!trans->nr_updates &&
            !trans->journal_entries_u64s)
                goto out_reset;
@@ -1105,6 +1111,7 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
        }
 retry:
        errored_at = NULL;
+       bch2_trans_verify_not_unlocked(trans);
        bch2_trans_verify_not_in_restart(trans);
        if (likely(!(flags & BCH_TRANS_COMMIT_no_journal_res)))
                memset(&trans->journal_res, 0, sizeof(trans->journal_res));
index a87608dd74c6d08756090664013ad6d8fcffa4f6..1febab152bfadff83d9980bd7a83f1d441c4cf74 100644 (file)
@@ -1949,6 +1949,8 @@ int __bch2_foreground_maybe_merge(struct btree_trans *trans,
        u64 start_time = local_clock();
        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(!btree_node_locked(&trans->paths[path], level));