bcachefs: ob_dev()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 1 May 2024 00:38:05 +0000 (20:38 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:23 +0000 (17:29 -0400)
Wrapper around bch2_dev_have_ref() for open_buckets; we do guarantee
that the device an open_bucket points to exists.

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

index cc182b2630665f86dcff6acba9d6ec11bf8c1ae2..77f3723e0fc0fa43af8369b4e3bdbf985ddd2acb 100644 (file)
@@ -100,7 +100,7 @@ static void bch2_open_bucket_hash_remove(struct bch_fs *c, struct open_bucket *o
 
 void __bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
+       struct bch_dev *ca = ob_dev(c, ob);
 
        if (ob->ec) {
                ec_stripe_new_put(c, ob->ec, STRIPE_REF_io);
@@ -684,8 +684,7 @@ static int add_new_bucket(struct bch_fs *c,
                           unsigned flags,
                           struct open_bucket *ob)
 {
-       unsigned durability =
-               bch2_dev_bkey_exists(c, ob->dev)->mi.durability;
+       unsigned durability = ob_dev(c, ob)->mi.durability;
 
        BUG_ON(*nr_effective >= nr_replicas);
 
@@ -831,7 +830,7 @@ static bool want_bucket(struct bch_fs *c,
                        bool *have_cache, bool ec,
                        struct open_bucket *ob)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
+       struct bch_dev *ca = ob_dev(c, ob);
 
        if (!test_bit(ob->dev, devs_may_alloc->d))
                return false;
@@ -901,7 +900,7 @@ static int bucket_alloc_set_partial(struct bch_fs *c,
                struct open_bucket *ob = c->open_buckets + c->open_buckets_partial[i];
 
                if (want_bucket(c, wp, devs_may_alloc, have_cache, ec, ob)) {
-                       struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
+                       struct bch_dev *ca = ob_dev(c, ob);
                        struct bch_dev_usage usage;
                        u64 avail;
 
@@ -1286,7 +1285,7 @@ deallocate_extra_replicas(struct bch_fs *c,
        unsigned i;
 
        open_bucket_for_each(c, ptrs, ob, i) {
-               unsigned d = bch2_dev_bkey_exists(c, ob->dev)->mi.durability;
+               unsigned d = ob_dev(c, ob)->mi.durability;
 
                if (d && d <= extra_replicas) {
                        extra_replicas -= d;
@@ -1443,7 +1442,7 @@ err:
 
 struct bch_extent_ptr bch2_ob_ptr(struct bch_fs *c, struct open_bucket *ob)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
+       struct bch_dev *ca = ob_dev(c, ob);
 
        return (struct bch_extent_ptr) {
                .type   = 1 << BCH_EXTENT_ENTRY_ptr,
@@ -1519,7 +1518,7 @@ void bch2_fs_allocator_foreground_init(struct bch_fs *c)
 
 static void bch2_open_bucket_to_text(struct printbuf *out, struct bch_fs *c, struct open_bucket *ob)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
+       struct bch_dev *ca = ob_dev(c, ob);
        unsigned data_type = ob->data_type;
        barrier(); /* READ_ONCE() doesn't work on bitfields */
 
index 96f24b67d0663c0fa14722a10cc14734efb8de65..a42c9730d32a8d63d9f19603e0ed122657f8be24 100644 (file)
@@ -30,6 +30,11 @@ void bch2_dev_stripe_increment(struct bch_dev *, struct dev_stripe_state *);
 
 long bch2_bucket_alloc_new_fs(struct bch_dev *);
 
+static inline struct bch_dev *ob_dev(struct bch_fs *c, struct open_bucket *ob)
+{
+       return bch2_dev_have_ref(c, ob->dev);
+}
+
 struct open_bucket *bch2_bucket_alloc(struct bch_fs *, struct bch_dev *,
                                      enum bch_watermark, enum bch_data_type,
                                      struct closure *);
@@ -185,7 +190,7 @@ bch2_alloc_sectors_append_ptrs_inlined(struct bch_fs *c, struct write_point *wp,
        wp->sectors_allocated   += sectors;
 
        open_bucket_for_each(c, &wp->ptrs, ob, i) {
-               struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
+               struct bch_dev *ca = ob_dev(c, ob);
                struct bch_extent_ptr ptr = bch2_ob_ptr(c, ob);
 
                ptr.cached = cached ||
index 6d41530615cbd555c814a664620e1a9fcbef4f38..fb5aa2b763ca3de3b2db584dba59b635dab3e2bd 100644 (file)
@@ -1550,16 +1550,13 @@ void bch2_ec_bucket_cancel(struct bch_fs *c, struct open_bucket *ob)
 void *bch2_writepoint_ec_buf(struct bch_fs *c, struct write_point *wp)
 {
        struct open_bucket *ob = ec_open_bucket(c, &wp->ptrs);
-       struct bch_dev *ca;
-       unsigned offset;
-
        if (!ob)
                return NULL;
 
        BUG_ON(!ob->ec->new_stripe.data[ob->ec_idx]);
 
-       ca      = bch2_dev_bkey_exists(c, ob->dev);
-       offset  = ca->mi.bucket_size - ob->sectors_free;
+       struct bch_dev *ca      = ob_dev(c, ob);
+       unsigned offset         = ca->mi.bucket_size - ob->sectors_free;
 
        return ob->ec->new_stripe.data[ob->ec_idx] + (offset << 9);
 }
index d6d391dc21ca7e7a2f89401cdc96810dcb40d9fc..a3ba1ddebe4d38ae039eeeec716a7cc91bc5b2f7 100644 (file)
@@ -195,6 +195,13 @@ static inline bool bucket_valid(const struct bch_dev *ca, u64 b)
        return b - ca->mi.first_bucket < ca->mi.nbuckets_minus_first;
 }
 
+static inline struct bch_dev *bch2_dev_have_ref(const struct bch_fs *c, unsigned dev)
+{
+       EBUG_ON(!bch2_dev_exists(c, dev));
+
+       return rcu_dereference_check(c->devs[dev], 1);
+}
+
 /*
  * If a key exists that references a device, the device won't be going away and
  * we can omit rcu_read_lock():