]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: bch2_dev_get_ioref2(); alloc_background.c
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 3 May 2024 16:43:31 +0000 (12:43 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 9 May 2024 20:23:35 +0000 (16:23 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/alloc_background.c
fs/bcachefs/sb-members.h

index 71b727f5d432c52bd4bb5094203319ea1f22c51c..b9ded84d2d94ec3a99036be9a0ffe0920d6e61b9 100644 (file)
@@ -1657,9 +1657,8 @@ static void discard_buckets_next_dev(struct bch_fs *c, struct discard_buckets_st
            bch2_dev_usage_read(s->ca).d[BCH_DATA_free].buckets)
                bch2_journal_flush_async(&c->journal, NULL);
 
-       bch2_dev_put(s->ca);
-       if (ca)
-               bch2_dev_get(ca);
+       if (s->ca)
+               percpu_ref_put(&s->ca->io_ref);
        s->ca = ca;
        s->need_journal_commit_this_dev = 0;
 }
@@ -1673,15 +1672,15 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
        struct bpos pos = need_discard_iter->pos;
        struct btree_iter iter = { NULL };
        struct bkey_s_c k;
-       struct bch_dev *ca;
        struct bkey_i_alloc_v4 *a;
        struct printbuf buf = PRINTBUF;
        bool discard_locked = false;
        int ret = 0;
 
-       ca = bch2_dev_bkey_exists(c, pos.inode);
-
-       if (!percpu_ref_tryget(&ca->io_ref)) {
+       struct bch_dev *ca = s->ca && s->ca->dev_idx == pos.inode
+               ? s->ca
+               : bch2_dev_get_ioref2(c, pos.inode, WRITE);
+       if (!ca) {
                bch2_btree_iter_set_pos(need_discard_iter, POS(pos.inode + 1, 0));
                return 0;
        }
@@ -1787,7 +1786,6 @@ out:
                discard_in_flight_remove(c, iter.pos);
        s->seen++;
        bch2_trans_iter_exit(trans, &iter);
-       percpu_ref_put(&ca->io_ref);
        printbuf_exit(&buf);
        return ret;
 }
@@ -1862,9 +1860,8 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
                        if (i->snapshot)
                                continue;
 
-                       ca = bch2_dev_bkey_exists(c, i->inode);
-
-                       if (!percpu_ref_tryget(&ca->io_ref)) {
+                       ca = bch2_dev_get_ioref2(c, i->inode, WRITE);
+                       if (!ca) {
                                darray_remove_item(&c->discard_buckets_in_flight, i);
                                continue;
                        }
index 7cecac44ab80ac9c5cdb59a68d2f545025d7ce94..f2a7794b0b500ee1f0bec27b2f176509d5a5a42d 100644 (file)
@@ -285,6 +285,24 @@ static inline struct bch_dev *bch2_dev_iterate(struct bch_fs *c, struct bch_dev
        return bch2_dev_tryget(c, dev_idx);
 }
 
+static inline struct bch_dev *bch2_dev_get_ioref2(struct bch_fs *c, unsigned dev, int rw)
+{
+       rcu_read_lock();
+       struct bch_dev *ca = bch2_dev_rcu(c, dev);
+       if (ca && !percpu_ref_tryget(&ca->io_ref))
+               ca = NULL;
+       rcu_read_unlock();
+
+       if (ca &&
+           (ca->mi.state == BCH_MEMBER_STATE_rw ||
+           (ca->mi.state == BCH_MEMBER_STATE_ro && rw == READ)))
+               return ca;
+
+       if (ca)
+               percpu_ref_put(&ca->io_ref);
+       return NULL;
+}
+
 /* XXX kill, move to struct bch_fs */
 static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
 {