bcachefs: bch2_dev_iterate()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 30 Apr 2024 19:37:25 +0000 (15:37 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:23 +0000 (17:29 -0400)
New helper for getting refs to devices as we iterate.

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

index 41f2e19aa8fe69e53fae667bb25ffa70adbd812d..69a77d268edf1b63f006923011928a01296b4457 100644 (file)
@@ -567,6 +567,7 @@ iter_err:
 int bch2_alloc_read(struct bch_fs *c)
 {
        struct btree_trans *trans = bch2_trans_get(c);
+       struct bch_dev *ca = NULL;
        int ret;
 
        down_read(&c->gc_lock);
@@ -580,16 +581,17 @@ int bch2_alloc_read(struct bch_fs *c)
                        if (k.k->type != KEY_TYPE_bucket_gens)
                                continue;
 
-                       const struct bch_bucket_gens *g = bkey_s_c_to_bucket_gens(k).v;
-
+                       ca = bch2_dev_iterate(c, ca, k.k->p.inode);
                        /*
                         * Not a fsck error because this is checked/repaired by
                         * bch2_check_alloc_key() which runs later:
                         */
-                       if (!bch2_dev_exists(c, k.k->p.inode))
+                       if (!ca) {
+                               bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode + 1, 0));
                                continue;
+                       }
 
-                       struct bch_dev *ca = bch2_dev_bkey_exists(c, k.k->p.inode);
+                       const struct bch_bucket_gens *g = bkey_s_c_to_bucket_gens(k).v;
 
                        for (u64 b = max_t(u64, ca->mi.first_bucket, start);
                             b < min_t(u64, ca->mi.nbuckets, end);
@@ -600,14 +602,15 @@ int bch2_alloc_read(struct bch_fs *c)
        } else {
                ret = for_each_btree_key(trans, iter, BTREE_ID_alloc, POS_MIN,
                                         BTREE_ITER_prefetch, k, ({
+                       ca = bch2_dev_iterate(c, ca, k.k->p.inode);
                        /*
                         * Not a fsck error because this is checked/repaired by
                         * bch2_check_alloc_key() which runs later:
                         */
-                       if (!bch2_dev_bucket_exists(c, k.k->p))
+                       if (!ca) {
+                               bch2_btree_iter_set_pos(&iter, POS(k.k->p.inode + 1, 0));
                                continue;
-
-                       struct bch_dev *ca = bch2_dev_bkey_exists(c, k.k->p.inode);
+                       }
 
                        struct bch_alloc_v4 a;
                        *bucket_gen(ca, k.k->p.offset) = bch2_alloc_to_v4(k, &a)->gen;
@@ -615,6 +618,7 @@ int bch2_alloc_read(struct bch_fs *c)
                }));
        }
 
+       bch2_dev_put(ca);
        bch2_trans_put(trans);
        up_read(&c->gc_lock);
 
index 503b56051d7ebadcf8982f8cceb76c89b7a424bf..d6d391dc21ca7e7a2f89401cdc96810dcb40d9fc 100644 (file)
@@ -262,6 +262,14 @@ static inline struct bch_dev *bch2_dev_bucket_tryget(struct bch_fs *c, struct bp
        return ca;
 }
 
+static inline struct bch_dev *bch2_dev_iterate(struct bch_fs *c, struct bch_dev *ca, unsigned dev_idx)
+{
+       if (ca && ca->dev_idx == dev_idx)
+               return ca;
+       bch2_dev_put(ca);
+       return bch2_dev_tryget(c, dev_idx);
+}
+
 /* XXX kill, move to struct bch_fs */
 static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
 {