bcachefs: Fix some shutdown path bugs
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 20 Dec 2021 23:18:35 +0000 (18:18 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:19 +0000 (17:09 -0400)
This fixes some bugs when we hit an error very early in the filesystem
startup path, before most things have been initialized.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_iter.c
fs/bcachefs/btree_key_cache.c

index dde919a95585931203edf624b0e6b79000915686..1ad5eafb2f7676b7e31e51f96bb5922ad2d63ca5 100644 (file)
@@ -705,6 +705,7 @@ struct bch_fs {
        struct btree_path_buf  __percpu *btree_paths_bufs;
 
        struct srcu_struct      btree_trans_barrier;
+       bool                    btree_trans_barrier_initialized;
 
        struct btree_key_cache  btree_key_cache;
 
index cc1dd788cdd5719de096b7d066fd70b41f574dc1..a9db8d05dc93184587988f09bebc40d7a56f3618 100644 (file)
@@ -2984,22 +2984,27 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
 
 void bch2_fs_btree_iter_exit(struct bch_fs *c)
 {
+       if (c->btree_trans_barrier_initialized)
+               cleanup_srcu_struct(&c->btree_trans_barrier);
        mempool_exit(&c->btree_trans_mem_pool);
        mempool_exit(&c->btree_paths_pool);
-       cleanup_srcu_struct(&c->btree_trans_barrier);
 }
 
 int bch2_fs_btree_iter_init(struct bch_fs *c)
 {
        unsigned nr = BTREE_ITER_MAX;
+       int ret;
 
        INIT_LIST_HEAD(&c->btree_trans_list);
        mutex_init(&c->btree_trans_lock);
 
-       return  init_srcu_struct(&c->btree_trans_barrier) ?:
-               mempool_init_kmalloc_pool(&c->btree_paths_pool, 1,
+       ret   = mempool_init_kmalloc_pool(&c->btree_paths_pool, 1,
                        sizeof(struct btree_path) * nr +
                        sizeof(struct btree_insert_entry) * nr) ?:
                mempool_init_kmalloc_pool(&c->btree_trans_mem_pool, 1,
-                                         BTREE_TRANS_MEM_MAX);
+                                         BTREE_TRANS_MEM_MAX) ?:
+               init_srcu_struct(&c->btree_trans_barrier);
+       if (!ret)
+               c->btree_trans_barrier_initialized = true;
+       return ret;
 }
index 50b44e55dfe77e34a1aa157299615e5e163bc935..d045b3a5deedc4c8d2bc2bf6bc825ed1f7bef7d4 100644 (file)
@@ -663,11 +663,12 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
 
        rcu_read_lock();
        tbl = rht_dereference_rcu(bc->table.tbl, &bc->table);
-       for (i = 0; i < tbl->size; i++)
-               rht_for_each_entry_rcu(ck, pos, tbl, i, hash) {
-                       bkey_cached_evict(bc, ck);
-                       list_add(&ck->list, &bc->freed);
-               }
+       if (tbl)
+               for (i = 0; i < tbl->size; i++)
+                       rht_for_each_entry_rcu(ck, pos, tbl, i, hash) {
+                               bkey_cached_evict(bc, ck);
+                               list_add(&ck->list, &bc->freed);
+                       }
        rcu_read_unlock();
 
        list_for_each_entry_safe(ck, n, &bc->freed, list) {