]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: c->ro_ref
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 6 Dec 2023 21:26:18 +0000 (16:26 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 1 Jan 2024 16:47:40 +0000 (11:47 -0500)
Add a new refcount for async ops that don't necessarily need the fs to
be RW, with similar lifetime/rules otherwise as c->writes.

To be used by online fsck.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/super.c

index 06b5cea9980e417b3f8e66faad793fa98502f461..ca7c9dea83dd576568e237c18c46b05dc851108b 100644 (file)
@@ -710,6 +710,13 @@ struct bch_fs {
 #else
        struct percpu_ref       writes;
 #endif
+       /*
+        * Analagous to c->writes, for asynchronous ops that don't necessarily
+        * need fs to be read-write
+        */
+       refcount_t              ro_ref;
+       wait_queue_head_t       ro_ref_wait;
+
        struct work_struct      read_only_work;
 
        struct bch_dev __rcu    *devs[BCH_SB_MEMBERS_MAX];
@@ -1105,6 +1112,20 @@ static inline void bch2_write_ref_put(struct bch_fs *c, enum bch_write_ref ref)
 #endif
 }
 
+static inline bool bch2_ro_ref_tryget(struct bch_fs *c)
+{
+       if (test_bit(BCH_FS_stopping, &c->flags))
+               return false;
+
+       return refcount_inc_not_zero(&c->ro_ref);
+}
+
+static inline void bch2_ro_ref_put(struct bch_fs *c)
+{
+       if (refcount_dec_and_test(&c->ro_ref))
+               wake_up(&c->ro_ref_wait);
+}
+
 static inline void bch2_set_ra_pages(struct bch_fs *c, unsigned ra_pages)
 {
 #ifndef NO_BCACHEFS_FS
index 8e566c3afcfd1063246befa202ece883a0ce0936..1ec66bb8a63f0367a14aa0837ffe8761737b4e12 100644 (file)
@@ -599,6 +599,9 @@ void __bch2_fs_stop(struct bch_fs *c)
        bch2_fs_debug_exit(c);
        bch2_fs_chardev_exit(c);
 
+       bch2_ro_ref_put(c);
+       wait_event(c->ro_ref_wait, !refcount_read(&c->ro_ref));
+
        kobject_put(&c->counters_kobj);
        kobject_put(&c->time_stats);
        kobject_put(&c->opts_dir);
@@ -729,6 +732,9 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
        mutex_init(&c->btree_root_lock);
        INIT_WORK(&c->read_only_work, bch2_fs_read_only_work);
 
+       refcount_set(&c->ro_ref, 1);
+       init_waitqueue_head(&c->ro_ref_wait);
+
        init_rwsem(&c->gc_lock);
        mutex_init(&c->gc_gens_lock);
        atomic_set(&c->journal_keys.ref, 1);