bcachefs: Take a SRCU lock in btree transactions
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 15 Nov 2020 21:30:22 +0000 (16:30 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:47 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/Kconfig
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_types.h

index eccf643e9081c8cf34fe7e68b4267d0d24179454..151c4b10d54351ee2d0f141f7d88a04efa3b2c43 100644 (file)
@@ -19,6 +19,7 @@ config BCACHEFS_FS
        select KEYS
        select RAID6_PQ
        select XOR_BLOCKS
+       select SRCU
        help
        The bcachefs filesystem - a modern, copy on write filesystem, with
        support for multiple devices, compression, checksumming, etc.
index 8ac96384fddf15ba526d81d32a07affc8ce1b9d6..d77d1fc1cfedf6f6005dc56d9682c84c49850e1e 100644 (file)
 #include <linux/rwsem.h>
 #include <linux/seqlock.h>
 #include <linux/shrinker.h>
+#include <linux/srcu.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 #include <linux/zstd.h>
@@ -642,6 +643,8 @@ struct bch_fs {
        mempool_t               btree_iters_pool;
        struct btree_iter_buf  __percpu *btree_iters_bufs;
 
+       struct srcu_struct      btree_trans_barrier;
+
        struct btree_key_cache  btree_key_cache;
 
        struct workqueue_struct *wq;
index f1d6553890f4eefd081bb78bf814913b82ab20bb..007d696566608f8f510c6499d1ec09307c2184e6 100644 (file)
@@ -2373,6 +2373,8 @@ void bch2_trans_init(struct btree_trans *trans, struct bch_fs *c,
        if (expected_mem_bytes)
                bch2_trans_preload_mem(trans, expected_mem_bytes);
 
+       trans->srcu_idx = srcu_read_lock(&c->btree_trans_barrier);
+
 #ifdef CONFIG_BCACHEFS_DEBUG
        trans->pid = current->pid;
        mutex_lock(&c->btree_trans_lock);
@@ -2393,6 +2395,8 @@ int bch2_trans_exit(struct btree_trans *trans)
        mutex_unlock(&trans->c->btree_trans_lock);
 #endif
 
+       srcu_read_unlock(&c->btree_trans_barrier, trans->srcu_idx);
+
        bch2_journal_preres_put(&trans->c->journal, &trans->journal_preres);
 
        kfree(trans->fs_usage_deltas);
@@ -2475,6 +2479,7 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
 void bch2_fs_btree_iter_exit(struct bch_fs *c)
 {
        mempool_exit(&c->btree_iters_pool);
+       cleanup_srcu_struct(&c->btree_trans_barrier);
 }
 
 int bch2_fs_btree_iter_init(struct bch_fs *c)
@@ -2484,7 +2489,8 @@ int bch2_fs_btree_iter_init(struct bch_fs *c)
        INIT_LIST_HEAD(&c->btree_trans_list);
        mutex_init(&c->btree_trans_lock);
 
-       return mempool_init_kmalloc_pool(&c->btree_iters_pool, 1,
+       return  init_srcu_struct(&c->btree_trans_barrier) ?:
+               mempool_init_kmalloc_pool(&c->btree_iters_pool, 1,
                        sizeof(struct btree_iter) * nr +
                        sizeof(struct btree_insert_entry) * nr +
                        sizeof(struct btree_insert_entry) * nr);
index de287f91ac28aebe01bdcf76ba52e8fe3149ae2d..47564995a0a319b6fc2452dde383085fba325ca0 100644 (file)
@@ -350,6 +350,7 @@ struct btree_trans {
        pid_t                   pid;
 #endif
        unsigned long           ip;
+       int                     srcu_idx;
 
        u64                     iters_linked;
        u64                     iters_live;