kthread creation checks for pending signals, which is _very_ annoying if
we have to do a long recovery and don't go rw until we've done
significant work.

Check if we'll be going rw and pre-allocate kthreads/workqueues.

Signed-off-by: Kent Overstreet <kent.overstr...@linux.dev>
---
 fs/bcachefs/recovery.c        | 10 ++++++++++
 fs/bcachefs/recovery_passes.c |  6 +-----
 fs/bcachefs/recovery_passes.h |  9 +++++++++
 fs/bcachefs/super.c           | 13 +++++++++++--
 fs/bcachefs/super.h           |  1 +
 5 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 37f2cc1ec2f8..fa5d1ef5bea6 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -762,6 +762,16 @@ int bch2_fs_recovery(struct bch_fs *c)
                c->opts.fsck = true;
        }
 
+       if (go_rw_in_recovery(c)) {
+               /*
+                * start workqueues/kworkers early - kthread creation checks for
+                * pending signals, which is _very_ annoying
+                */
+               ret = bch2_fs_init_rw(c);
+               if (ret)
+                       goto err;
+       }
+
        mutex_lock(&c->sb_lock);
        struct bch_sb_field_ext *ext = bch2_sb_field_get(c->disk_sb.sb, ext);
        bool write_sb = false;
diff --git a/fs/bcachefs/recovery_passes.c b/fs/bcachefs/recovery_passes.c
index 35ac0d64d73a..c2c18c0a5429 100644
--- a/fs/bcachefs/recovery_passes.c
+++ b/fs/bcachefs/recovery_passes.c
@@ -217,11 +217,7 @@ static int bch2_set_may_go_rw(struct bch_fs *c)
 
        set_bit(BCH_FS_may_go_rw, &c->flags);
 
-       if (keys->nr ||
-           !c->opts.read_only ||
-           !c->sb.clean ||
-           c->opts.recovery_passes ||
-           (c->opts.fsck && !(c->sb.features & 
BIT_ULL(BCH_FEATURE_no_alloc_info)))) {
+       if (go_rw_in_recovery(c)) {
                if (c->sb.features & BIT_ULL(BCH_FEATURE_no_alloc_info)) {
                        bch_info(c, "mounting a filesystem with no alloc info 
read-write; will recreate");
                        bch2_reconstruct_alloc(c);
diff --git a/fs/bcachefs/recovery_passes.h b/fs/bcachefs/recovery_passes.h
index 260571c7105e..2117f0ce1922 100644
--- a/fs/bcachefs/recovery_passes.h
+++ b/fs/bcachefs/recovery_passes.h
@@ -17,6 +17,15 @@ enum bch_run_recovery_pass_flags {
        RUN_RECOVERY_PASS_ratelimit     = BIT(1),
 };
 
+static inline bool go_rw_in_recovery(struct bch_fs *c)
+{
+       return (c->journal_keys.nr ||
+               !c->opts.read_only ||
+               !c->sb.clean ||
+               c->opts.recovery_passes ||
+               (c->opts.fsck && !(c->sb.features & 
BIT_ULL(BCH_FEATURE_no_alloc_info))));
+}
+
 int bch2_run_print_explicit_recovery_pass(struct bch_fs *, enum 
bch_recovery_pass);
 
 int __bch2_run_explicit_recovery_pass(struct bch_fs *, struct printbuf *,
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index a5b97c9c5163..69c097ff54e7 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -210,7 +210,6 @@ static int bch2_dev_alloc(struct bch_fs *, unsigned);
 static int bch2_dev_sysfs_online(struct bch_fs *, struct bch_dev *);
 static void bch2_dev_io_ref_stop(struct bch_dev *, int);
 static void __bch2_dev_read_only(struct bch_fs *, struct bch_dev *);
-static int bch2_fs_init_rw(struct bch_fs *);
 
 struct bch_fs *bch2_dev_to_fs(dev_t dev)
 {
@@ -794,7 +793,7 @@ static int bch2_fs_online(struct bch_fs *c)
        return ret;
 }
 
-static int bch2_fs_init_rw(struct bch_fs *c)
+int bch2_fs_init_rw(struct bch_fs *c)
 {
        if (test_bit(BCH_FS_rw_init_done, &c->flags))
                return 0;
@@ -1015,6 +1014,16 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, 
struct bch_opts *opts,
        if (ret)
                goto err;
 
+       if (go_rw_in_recovery(c)) {
+               /*
+                * start workqueues/kworkers early - kthread creation checks for
+                * pending signals, which is _very_ annoying
+                */
+               ret = bch2_fs_init_rw(c);
+               if (ret)
+                       goto err;
+       }
+
 #ifdef CONFIG_UNICODE
        /* Default encoding until we can potentially have more as an option. */
        c->cf_encoding = utf8_load(BCH_FS_DEFAULT_UTF8_ENCODING);
diff --git a/fs/bcachefs/super.h b/fs/bcachefs/super.h
index dc52f06cb2b9..e90bab9afe78 100644
--- a/fs/bcachefs/super.h
+++ b/fs/bcachefs/super.h
@@ -46,6 +46,7 @@ void __bch2_fs_stop(struct bch_fs *);
 void bch2_fs_free(struct bch_fs *);
 void bch2_fs_stop(struct bch_fs *);
 
+int bch2_fs_init_rw(struct bch_fs *);
 int bch2_fs_start(struct bch_fs *);
 struct bch_fs *bch2_fs_open(darray_const_str *, struct bch_opts *);
 
-- 
2.50.0


Reply via email to