]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: bch2_mark_alloc(): Do wakeups after updating usage
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 18 Jul 2022 01:33:00 +0000 (21:33 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:36 +0000 (17:09 -0400)
We have an obvious wake up race if we do the wakeup _before_ updating
the counters the thing doing the waiting is reading.

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

index 99c9d5b14d4874775e4a48f530f211f7c13fdab2..71618f5bfcd5b0c3e984e25d10cb059566dd6dfc 100644 (file)
@@ -547,22 +547,6 @@ int bch2_mark_alloc(struct btree_trans *trans,
                }
        }
 
-       if (new_a.data_type == BCH_DATA_free &&
-           (!new_a.journal_seq || new_a.journal_seq < c->journal.flushed_seq_ondisk))
-               closure_wake_up(&c->freelist_wait);
-
-       if (new_a.data_type == BCH_DATA_need_discard &&
-           (!new_a.journal_seq || new_a.journal_seq < c->journal.flushed_seq_ondisk))
-               bch2_do_discards(c);
-
-       if (old_a.data_type != BCH_DATA_cached &&
-           new_a.data_type == BCH_DATA_cached &&
-           should_invalidate_buckets(ca, bch2_dev_usage_read(ca)))
-               bch2_do_invalidates(c);
-
-       if (new_a.data_type == BCH_DATA_need_gc_gens)
-               bch2_do_gc_gens(c);
-
        percpu_down_read(&c->mark_lock);
        if (!gc && new_a.gen != old_a.gen)
                *bucket_gen(ca, new.k->p.offset) = new_a.gen;
@@ -602,6 +586,22 @@ int bch2_mark_alloc(struct btree_trans *trans,
                }
        }
 
+       if (new_a.data_type == BCH_DATA_free &&
+           (!new_a.journal_seq || new_a.journal_seq < c->journal.flushed_seq_ondisk))
+               closure_wake_up(&c->freelist_wait);
+
+       if (new_a.data_type == BCH_DATA_need_discard &&
+           (!new_a.journal_seq || new_a.journal_seq < c->journal.flushed_seq_ondisk))
+               bch2_do_discards(c);
+
+       if (old_a.data_type != BCH_DATA_cached &&
+           new_a.data_type == BCH_DATA_cached &&
+           should_invalidate_buckets(ca, bch2_dev_usage_read(ca)))
+               bch2_do_invalidates(c);
+
+       if (new_a.data_type == BCH_DATA_need_gc_gens)
+               bch2_do_gc_gens(c);
+
        return 0;
 }