summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-04-19 01:01:49 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:08:54 +0300
commit2ee47eec44f0613d6c51d88f8c820a5e8ed624a3 (patch)
tree32089e6eb74857812f93cff20124bf68983a82db
parentbae895a5a3300c2da605dd0c841e175c4c9e5872 (diff)
downloadlinux-2ee47eec44f0613d6c51d88f8c820a5e8ed624a3.tar.xz
bcachefs: Fix for copygc getting stuck waiting for reserve to be filled
This fixes a regression from the patch bcachefs: Fix copygc dying on startup In general only the allocator thread itself should be updating ca->allocator_state, the thread waking up the allocator setting it is an ugly hack only needed to avoid racing with the copygc threads when we're first starting up. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/alloc_background.h4
-rw-r--r--fs/bcachefs/super.c9
2 files changed, 9 insertions, 4 deletions
diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h
index 73e1c27c96e3..ad15a80602c0 100644
--- a/fs/bcachefs/alloc_background.h
+++ b/fs/bcachefs/alloc_background.h
@@ -100,10 +100,8 @@ static inline void bch2_wake_allocator(struct bch_dev *ca)
rcu_read_lock();
p = rcu_dereference(ca->alloc_thread);
- if (p) {
+ if (p)
wake_up_process(p);
- ca->allocator_state = ALLOCATOR_running;
- }
rcu_read_unlock();
}
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 650a559737fd..0ff80816a54f 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -908,9 +908,16 @@ int bch2_fs_start(struct bch_fs *c)
/*
* Allocator threads don't start filling copygc reserve until after we
* set BCH_FS_STARTED - wake them now:
+ *
+ * XXX ugly hack:
+ * Need to set ca->allocator_state here instead of relying on the
+ * allocator threads to do it to avoid racing with the copygc threads
+ * checking it and thinking they have no alloc reserve:
*/
- for_each_online_member(ca, c, i)
+ for_each_online_member(ca, c, i) {
+ ca->allocator_state = ALLOCATOR_running;
bch2_wake_allocator(ca);
+ }
if (c->opts.read_only || c->opts.nochanges) {
bch2_fs_read_only(c);