diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-07-17 21:33:00 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:36 -0400 |
commit | f501ad2b8108a7910adf494fcc5c59bbbfa886e8 (patch) | |
tree | 317f88e49c2158fc3613c303f8a18246598bf530 /fs/bcachefs/buckets.c | |
parent | c807ca95a6e20bedbbb84287bc7087c2b2b775de (diff) | |
download | lwn-f501ad2b8108a7910adf494fcc5c59bbbfa886e8.tar.gz lwn-f501ad2b8108a7910adf494fcc5c59bbbfa886e8.zip |
bcachefs: bch2_mark_alloc(): Do wakeups after updating usage
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>
Diffstat (limited to 'fs/bcachefs/buckets.c')
-rw-r--r-- | fs/bcachefs/buckets.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 99c9d5b14d48..71618f5bfcd5 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -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; } |