]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_key_cache.c
Update bcachefs sources to b964c6cba8 bcachefs: Change lockrestart_do() to always...
[bcachefs-tools-debian] / libbcachefs / btree_key_cache.c
index 7f47ef3345aae4ea02ff92bd84c268d5433aeaf0..e327ef39d4329512f3e576b6f2bed239ea1c0272 100644 (file)
@@ -214,7 +214,7 @@ static int btree_key_cache_fill(struct btree_trans *trans,
 
        if (!bch2_btree_node_relock(ck_iter, 0)) {
                trace_transaction_restart_ip(trans->ip, _THIS_IP_);
-               ret = -EINTR;
+               ret = btree_trans_restart(trans);
                goto err;
        }
 
@@ -233,6 +233,10 @@ static int btree_key_cache_fill(struct btree_trans *trans,
                }
        }
 
+       /*
+        * XXX: not allowed to be holding read locks when we take a write lock,
+        * currently
+        */
        bch2_btree_node_lock_write(ck_iter->l[0].b, ck_iter);
        if (new_k) {
                kfree(ck->k);
@@ -299,10 +303,8 @@ retry:
 
                if (!btree_node_lock((void *) ck, iter->pos, 0, iter, lock_want,
                                     bkey_cached_check_fn, iter, _THIS_IP_)) {
-                       if (ck->key.btree_id != iter->btree_id ||
-                           bpos_cmp(ck->key.pos, iter->pos)) {
+                       if (!trans->restarted)
                                goto retry;
-                       }
 
                        trace_transaction_restart_ip(trans->ip, _THIS_IP_);
                        ret = -EINTR;
@@ -322,10 +324,10 @@ retry:
        iter->l[0].b            = (void *) ck;
 fill:
        if (!ck->valid && !(iter->flags & BTREE_ITER_CACHED_NOFILL)) {
-               if (!btree_node_intent_locked(iter, 0))
-                       bch2_btree_iter_upgrade(iter, 1);
-               if (!btree_node_intent_locked(iter, 0)) {
+               if (!iter->locks_want &&
+                   !!__bch2_btree_iter_upgrade(iter, 1)) {
                        trace_transaction_restart_ip(trans->ip, _THIS_IP_);
+                       BUG_ON(!trans->restarted);
                        ret = -EINTR;
                        goto err;
                }
@@ -340,13 +342,14 @@ fill:
 
        iter->uptodate = BTREE_ITER_NEED_PEEK;
 
-       if (!(iter->flags & BTREE_ITER_INTENT))
-               bch2_btree_iter_downgrade(iter);
-       else if (!iter->locks_want) {
-               if (!__bch2_btree_iter_upgrade(iter, 1))
-                       ret = -EINTR;
+       if ((iter->flags & BTREE_ITER_INTENT) &&
+           !bch2_btree_iter_upgrade(iter, 1)) {
+               BUG_ON(!trans->restarted);
+               ret = -EINTR;
        }
 
+       BUG_ON(!ret && !btree_node_locked(iter, 0));
+
        return ret;
 err:
        if (ret != -EINTR) {
@@ -377,10 +380,9 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
                                     BTREE_ITER_CACHED_NOFILL|
                                     BTREE_ITER_CACHED_NOCREATE|
                                     BTREE_ITER_INTENT);
-retry:
        ret = bch2_btree_iter_traverse(c_iter);
        if (ret)
-               goto err;
+               goto out;
 
        ck = (void *) c_iter->l[0].b;
        if (!ck ||
@@ -399,9 +401,10 @@ retry:
         * to be using alloc reserves:
         * */
        ret   = bch2_btree_iter_traverse(b_iter) ?:
-               bch2_trans_update(trans, b_iter, ck->k, BTREE_TRIGGER_NORUN) ?:
+               bch2_trans_update(trans, b_iter, ck->k,
+                                 BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|
+                                 BTREE_TRIGGER_NORUN) ?:
                bch2_trans_commit(trans, NULL, NULL,
-                                 BTREE_INSERT_NOUNLOCK|
                                  BTREE_INSERT_NOCHECK_RW|
                                  BTREE_INSERT_NOFAIL|
                                  BTREE_INSERT_USE_RESERVE|
@@ -409,15 +412,10 @@ retry:
                                   ? BTREE_INSERT_JOURNAL_RESERVED
                                   : 0)|
                                  commit_flags);
-err:
-       if (ret == -EINTR)
-               goto retry;
-
-       if (ret == -EAGAIN)
-               goto out;
-
        if (ret) {
-               bch2_fs_fatal_err_on(!bch2_journal_error(j), c,
+               bch2_fs_fatal_err_on(ret != -EINTR &&
+                                    ret != -EAGAIN &&
+                                    !bch2_journal_error(j), c,
                        "error flushing key cache: %i", ret);
                goto out;
        }
@@ -465,7 +463,6 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
        struct bkey_cached *ck =
                container_of(pin, struct bkey_cached, journal);
        struct bkey_cached_key key;
-       struct btree_trans trans;
        int ret = 0;
 
        int srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
@@ -480,10 +477,9 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
        }
        six_unlock_read(&ck->c.lock);
 
-       bch2_trans_init(&trans, c, 0, 0);
-       ret = btree_key_cache_flush_pos(&trans, key, seq,
-                                 BTREE_INSERT_JOURNAL_RECLAIM, false);
-       bch2_trans_exit(&trans);
+       ret = bch2_trans_do(c, NULL, NULL, 0,
+               btree_key_cache_flush_pos(&trans, key, seq,
+                               BTREE_INSERT_JOURNAL_RECLAIM, false));
 unlock:
        srcu_read_unlock(&c->btree_trans_barrier, srcu_idx);