bcachefs: Don't start allocator threads too early
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 31 Dec 2021 00:30:42 +0000 (19:30 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:19 +0000 (17:09 -0400)
If the allocator threads start before journal replay has finished
replaying alloc keys, journal replay might overwrite the allocator's
btree updates.

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

index e81e056..fe7bc3c 100644 (file)
@@ -900,7 +900,8 @@ static void discard_one_bucket(struct bch_fs *c, struct bch_dev *ca, u64 b)
 static bool allocator_thread_running(struct bch_dev *ca)
 {
        unsigned state = ca->mi.state == BCH_MEMBER_STATE_rw &&
-               test_bit(BCH_FS_ALLOCATOR_RUNNING, &ca->fs->flags)
+               test_bit(BCH_FS_ALLOCATOR_RUNNING, &ca->fs->flags) &&
+               test_bit(BCH_FS_ALLOC_REPLAY_DONE, &ca->fs->flags)
                ? ALLOCATOR_running
                : ALLOCATOR_stopped;
        alloc_thread_set_state(ca, state);
index c8c7f6b..5f18531 100644 (file)
@@ -509,6 +509,7 @@ enum {
        BCH_FS_INITIAL_GC_DONE,
        BCH_FS_INITIAL_GC_UNFIXED,
        BCH_FS_TOPOLOGY_REPAIR_DONE,
+       BCH_FS_ALLOC_REPLAY_DONE,
        BCH_FS_BTREE_INTERIOR_REPLAY_DONE,
        BCH_FS_FSCK_DONE,
        BCH_FS_STARTED,
index 9916fad..d0ceac0 100644 (file)
@@ -567,9 +567,10 @@ static int bch2_journal_replay(struct bch_fs *c,
                               struct journal_keys keys)
 {
        struct journal *j = &c->journal;
+       struct bch_dev *ca;
        struct journal_key *i;
        u64 seq;
-       int ret;
+       int ret, idx;
 
        sort(keys.d, keys.nr, sizeof(keys.d[0]), journal_sort_seq_cmp, NULL);
 
@@ -593,6 +594,11 @@ static int bch2_journal_replay(struct bch_fs *c,
                }
        }
 
+       /* Now we can start the allocator threads: */
+       set_bit(BCH_FS_ALLOC_REPLAY_DONE, &c->flags);
+       for_each_member_device(ca, c, idx)
+               bch2_wake_allocator(ca);
+
        /*
         * Next replay updates to interior btree nodes:
         */
@@ -1391,6 +1397,7 @@ int bch2_fs_initialize(struct bch_fs *c)
        for (i = 0; i < BTREE_ID_NR; i++)
                bch2_btree_root_alloc(c, i);
 
+       set_bit(BCH_FS_ALLOC_REPLAY_DONE, &c->flags);
        set_bit(BCH_FS_BTREE_INTERIOR_REPLAY_DONE, &c->flags);
        set_bit(JOURNAL_RECLAIM_STARTED, &c->journal.flags);