]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_key_cache.c
Disable pristine-tar option in gbp.conf, since there is no pristine-tar branch.
[bcachefs-tools-debian] / libbcachefs / btree_key_cache.c
index 8e80a5b687fe04e685f61b022333befa218c0c9c..74e52fd28abe584617d2d7ccd2c09b8a46db1603 100644 (file)
@@ -13,7 +13,6 @@
 #include "trace.h"
 
 #include <linux/sched/mm.h>
-#include <linux/seq_buf.h>
 
 static inline bool btree_uses_pcpu_readers(enum btree_id id)
 {
@@ -631,7 +630,7 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
        if (ret)
                goto out;
 
-       ck = (void *) c_iter.path->l[0].b;
+       ck = (void *) btree_iter_path(trans, &c_iter)->l[0].b;
        if (!ck)
                goto out;
 
@@ -646,11 +645,21 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
        if (journal_seq && ck->journal.seq != journal_seq)
                goto out;
 
+       trans->journal_res.seq = ck->journal.seq;
+
        /*
-        * Since journal reclaim depends on us making progress here, and the
-        * allocator/copygc depend on journal reclaim making progress, we need
-        * to be using alloc reserves:
+        * If we're at the end of the journal, we really want to free up space
+        * in the journal right away - we don't want to pin that old journal
+        * sequence number with a new btree node write, we want to re-journal
+        * the update
         */
+       if (ck->journal.seq == journal_last_seq(j))
+               commit_flags |= BCH_WATERMARK_reclaim;
+
+       if (ck->journal.seq != journal_last_seq(j) ||
+           j->watermark == BCH_WATERMARK_stripe)
+               commit_flags |= BCH_TRANS_COMMIT_no_journal_res;
+
        ret   = bch2_btree_iter_traverse(&b_iter) ?:
                bch2_trans_update(trans, &b_iter, ck->k,
                                  BTREE_UPDATE_KEY_CACHE_RECLAIM|
@@ -659,9 +668,6 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
                bch2_trans_commit(trans, NULL, NULL,
                                  BCH_TRANS_COMMIT_no_check_rw|
                                  BCH_TRANS_COMMIT_no_enospc|
-                                 (ck->journal.seq == journal_last_seq(j)
-                                  ? BCH_WATERMARK_reclaim
-                                  : 0)|
                                  commit_flags);
 
        bch2_fs_fatal_err_on(ret &&
@@ -674,7 +680,8 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
 
        bch2_journal_pin_drop(j, &ck->journal);
 
-       BUG_ON(!btree_node_locked(c_iter.path, 0));
+       struct btree_path *path = btree_iter_path(trans, &c_iter);
+       BUG_ON(!btree_node_locked(path, 0));
 
        if (!evict) {
                if (test_bit(BKEY_CACHED_DIRTY, &ck->flags)) {
@@ -683,19 +690,20 @@ static int btree_key_cache_flush_pos(struct btree_trans *trans,
                }
        } else {
                struct btree_path *path2;
+               unsigned i;
 evict:
-               trans_for_each_path(trans, path2)
-                       if (path2 != c_iter.path)
+               trans_for_each_path(trans, path2, i)
+                       if (path2 != path)
                                __bch2_btree_path_unlock(trans, path2);
 
-               bch2_btree_node_lock_write_nofail(trans, c_iter.path, &ck->c);
+               bch2_btree_node_lock_write_nofail(trans, path, &ck->c);
 
                if (test_bit(BKEY_CACHED_DIRTY, &ck->flags)) {
                        clear_bit(BKEY_CACHED_DIRTY, &ck->flags);
                        atomic_long_dec(&c->btree_key_cache.nr_dirty);
                }
 
-               mark_btree_node_locked_noreset(c_iter.path, 0, BTREE_NODE_UNLOCKED);
+               mark_btree_node_locked_noreset(path, 0, BTREE_NODE_UNLOCKED);
                bkey_cached_evict(&c->btree_key_cache, ck);
                bkey_cached_free_fast(&c->btree_key_cache, ck);
        }
@@ -733,7 +741,7 @@ int bch2_btree_key_cache_journal_flush(struct journal *j,
        }
        six_unlock_read(&ck->c.lock);
 
-       ret = commit_do(trans, NULL, NULL, 0,
+       ret = lockrestart_do(trans,
                btree_key_cache_flush_pos(trans, key, seq,
                                BCH_TRANS_COMMIT_journal_reclaim, false));
 unlock:
@@ -743,28 +751,12 @@ unlock:
        return ret;
 }
 
-/*
- * Flush and evict a key from the key cache:
- */
-int bch2_btree_key_cache_flush(struct btree_trans *trans,
-                              enum btree_id id, struct bpos pos)
-{
-       struct bch_fs *c = trans->c;
-       struct bkey_cached_key key = { id, pos };
-
-       /* Fastpath - assume it won't be found: */
-       if (!bch2_btree_key_cache_find(c, id, pos))
-               return 0;
-
-       return btree_key_cache_flush_pos(trans, key, 0, 0, true);
-}
-
 bool bch2_btree_insert_key_cached(struct btree_trans *trans,
                                  unsigned flags,
                                  struct btree_insert_entry *insert_entry)
 {
        struct bch_fs *c = trans->c;
-       struct bkey_cached *ck = (void *) insert_entry->path->l[0].b;
+       struct bkey_cached *ck = (void *) (trans->paths + insert_entry->path)->l[0].b;
        struct bkey_i *insert = insert_entry->k;
        bool kick_reclaim = false;
 
@@ -774,7 +766,7 @@ bool bch2_btree_insert_key_cached(struct btree_trans *trans,
        ck->valid = true;
 
        if (!test_bit(BKEY_CACHED_DIRTY, &ck->flags)) {
-               EBUG_ON(test_bit(BCH_FS_CLEAN_SHUTDOWN, &c->flags));
+               EBUG_ON(test_bit(BCH_FS_clean_shutdown, &c->flags));
                set_bit(BKEY_CACHED_DIRTY, &ck->flags);
                atomic_long_inc(&c->btree_key_cache.nr_dirty);
 
@@ -830,8 +822,7 @@ void bch2_btree_key_cache_drop(struct btree_trans *trans,
 static unsigned long bch2_btree_key_cache_scan(struct shrinker *shrink,
                                           struct shrink_control *sc)
 {
-       struct bch_fs *c = container_of(shrink, struct bch_fs,
-                                       btree_key_cache.shrink);
+       struct bch_fs *c = shrink->private_data;
        struct btree_key_cache *bc = &c->btree_key_cache;
        struct bucket_table *tbl;
        struct bkey_cached *ck, *t;
@@ -932,8 +923,7 @@ out:
 static unsigned long bch2_btree_key_cache_count(struct shrinker *shrink,
                                            struct shrink_control *sc)
 {
-       struct bch_fs *c = container_of(shrink, struct bch_fs,
-                                       btree_key_cache.shrink);
+       struct bch_fs *c = shrink->private_data;
        struct btree_key_cache *bc = &c->btree_key_cache;
        long nr = atomic_long_read(&bc->nr_keys) -
                atomic_long_read(&bc->nr_dirty);
@@ -953,7 +943,7 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
        int cpu;
 #endif
 
-       unregister_shrinker(&bc->shrink);
+       shrinker_free(bc->shrink);
 
        mutex_lock(&bc->lock);
 
@@ -995,8 +985,6 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
        list_for_each_entry_safe(ck, n, &items, list) {
                cond_resched();
 
-               bch2_journal_pin_drop(&c->journal, &ck->journal);
-
                list_del(&ck->list);
                kfree(ck->k);
                six_lock_exit(&ck->c.lock);
@@ -1005,7 +993,7 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
 
        if (atomic_long_read(&bc->nr_dirty) &&
            !bch2_journal_error(&c->journal) &&
-           test_bit(BCH_FS_WAS_RW, &c->flags))
+           test_bit(BCH_FS_was_rw, &c->flags))
                panic("btree key cache shutdown error: nr_dirty nonzero (%li)\n",
                      atomic_long_read(&bc->nr_dirty));
 
@@ -1026,21 +1014,10 @@ void bch2_fs_btree_key_cache_init_early(struct btree_key_cache *c)
        INIT_LIST_HEAD(&c->freed_nonpcpu);
 }
 
-static void bch2_btree_key_cache_shrinker_to_text(struct seq_buf *s, struct shrinker *shrink)
-{
-       struct btree_key_cache *bc =
-               container_of(shrink, struct btree_key_cache, shrink);
-       char *cbuf;
-       size_t buflen = seq_buf_get_buf(s, &cbuf);
-       struct printbuf out = PRINTBUF_EXTERN(cbuf, buflen);
-
-       bch2_btree_key_cache_to_text(&out, bc);
-       seq_buf_commit(s, out.pos);
-}
-
 int bch2_fs_btree_key_cache_init(struct btree_key_cache *bc)
 {
        struct bch_fs *c = container_of(bc, struct bch_fs, btree_key_cache);
+       struct shrinker *shrink;
 
 #ifdef __KERNEL__
        bc->pcpu_freed = alloc_percpu(struct btree_key_cache_freelist);
@@ -1053,12 +1030,15 @@ int bch2_fs_btree_key_cache_init(struct btree_key_cache *bc)
 
        bc->table_init_done = true;
 
-       bc->shrink.seeks                = 0;
-       bc->shrink.count_objects        = bch2_btree_key_cache_count;
-       bc->shrink.scan_objects         = bch2_btree_key_cache_scan;
-       bc->shrink.to_text              = bch2_btree_key_cache_shrinker_to_text;
-       if (register_shrinker(&bc->shrink, "%s-btree_key_cache", c->name))
+       shrink = shrinker_alloc(0, "%s-btree_key_cache", c->name);
+       if (!shrink)
                return -BCH_ERR_ENOMEM_fs_btree_cache_init;
+       bc->shrink = shrink;
+       shrink->seeks           = 0;
+       shrink->count_objects   = bch2_btree_key_cache_count;
+       shrink->scan_objects    = bch2_btree_key_cache_scan;
+       shrink->private_data    = c;
+       shrinker_register(shrink);
        return 0;
 }