bcachefs: PTR_BUCKET_POS() now takes bch_dev
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 30 Apr 2024 23:34:28 +0000 (19:34 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:23 +0000 (17:29 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/backpointers.c
fs/bcachefs/backpointers.h
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/data_update.c
fs/bcachefs/ec.c
fs/bcachefs/io_read.c
fs/bcachefs/io_write.c

index 36e5e63ec3d5f1e19fb37b4d534497adf7aa40e0..282aee70a51f8e71df927074eea77592b2659811 100644 (file)
@@ -30,7 +30,9 @@ static bool extent_matches_bp(struct bch_fs *c,
                if (p.ptr.cached)
                        continue;
 
-               bch2_extent_ptr_to_bp(c, btree_id, level, k, p, entry, &bucket2, &bp2);
+               struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
+
+               bch2_extent_ptr_to_bp(c, ca, btree_id, level, k, p, entry, &bucket2, &bp2);
                if (bpos_eq(bucket, bucket2) &&
                    !memcmp(&bp, &bp2, sizeof(bp)))
                        return true;
@@ -666,7 +668,8 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
                if (p.ptr.cached)
                        continue;
 
-               bch2_extent_ptr_to_bp(c, btree, level, k, p, entry, &bucket_pos, &bp);
+               struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
+               bch2_extent_ptr_to_bp(c, ca, btree, level, k, p, entry, &bucket_pos, &bp);
 
                ret = check_bp_exists(trans, s, bucket_pos, bp, k);
                if (ret)
index e7f1eddbf4f483e1bdc99243da53ad6e6364748a..1d270c40fce9ab9f5375ff08ecec99637481e379 100644 (file)
@@ -120,7 +120,7 @@ static inline enum bch_data_type bch2_bkey_ptr_data_type(struct bkey_s_c k,
        }
 }
 
-static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
+static inline void bch2_extent_ptr_to_bp(struct bch_fs *c, struct bch_dev *ca,
                           enum btree_id btree_id, unsigned level,
                           struct bkey_s_c k, struct extent_ptr_decoded p,
                           const union bch_extent_entry *entry,
@@ -130,7 +130,7 @@ static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
        s64 sectors = level ? btree_sectors(c) : k.k->size;
        u32 bucket_offset;
 
-       *bucket_pos = PTR_BUCKET_POS_OFFSET(c, &p.ptr, &bucket_offset);
+       *bucket_pos = PTR_BUCKET_POS_OFFSET(ca, &p.ptr, &bucket_offset);
        *bp = (struct bch_backpointer) {
                .btree_id       = btree_id,
                .level          = level,
index 68f2d5952abdcf4f8670766f2a0e88d447ad2116..4774f9c7f060e0733d86ed8c81ae52c3438a9df2 100644 (file)
@@ -977,7 +977,7 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
 
        struct bpos bucket;
        struct bch_backpointer bp;
-       bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, entry, &bucket, &bp);
+       bch2_extent_ptr_to_bp(trans->c, ca, btree_id, level, k, p, entry, &bucket, &bp);
        *sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);
 
        if (flags & BTREE_TRIGGER_transactional) {
index 46bf66d6b2540ef5fdb6be5608d96d61047b09d7..0a54faf7c50a640100725941d3a3e8d00272cee5 100644 (file)
@@ -120,20 +120,16 @@ static inline size_t PTR_BUCKET_NR(const struct bch_dev *ca,
        return sector_to_bucket(ca, ptr->offset);
 }
 
-static inline struct bpos PTR_BUCKET_POS(const struct bch_fs *c,
-                                  const struct bch_extent_ptr *ptr)
+static inline struct bpos PTR_BUCKET_POS(const struct bch_dev *ca,
+                                        const struct bch_extent_ptr *ptr)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
-
        return POS(ptr->dev, PTR_BUCKET_NR(ca, ptr));
 }
 
-static inline struct bpos PTR_BUCKET_POS_OFFSET(const struct bch_fs *c,
+static inline struct bpos PTR_BUCKET_POS_OFFSET(const struct bch_dev *ca,
                                                const struct bch_extent_ptr *ptr,
                                                u32 *bucket_offset)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
-
        return POS(ptr->dev, sector_to_bucket_and_offset(ca, ptr->offset, bucket_offset));
 }
 
index c252f0619b7362b83ac0b7800ce3818ea2b08971..1cf92bea7f9f7e3d579960ee57a72d93d81ec906 100644 (file)
@@ -357,10 +357,11 @@ void bch2_data_update_exit(struct data_update *update)
                bch2_bkey_ptrs_c(bkey_i_to_s_c(update->k.k));
 
        bkey_for_each_ptr(ptrs, ptr) {
+               struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
                if (c->opts.nocow_enabled)
                        bch2_bucket_nocow_unlock(&c->nocow_locks,
-                                                PTR_BUCKET_POS(c, ptr), 0);
-               bch2_dev_put(bch2_dev_bkey_exists(c, ptr->dev));
+                                                PTR_BUCKET_POS(ca, ptr), 0);
+               bch2_dev_put(ca);
        }
 
        bch2_bkey_buf_exit(&update->k, c);
@@ -547,6 +548,8 @@ int bch2_data_update_init(struct btree_trans *trans,
 
        i = 0;
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
+               struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
+               struct bpos bucket = PTR_BUCKET_POS(ca, &p.ptr);
                bool locked;
 
                if (((1U << i) & m->data_opts.rewrite_ptrs)) {
@@ -580,15 +583,13 @@ int bch2_data_update_init(struct btree_trans *trans,
                        if (ctxt) {
                                move_ctxt_wait_event(ctxt,
                                                (locked = bch2_bucket_nocow_trylock(&c->nocow_locks,
-                                                                         PTR_BUCKET_POS(c, &p.ptr), 0)) ||
+                                                                         bucket, 0)) ||
                                                list_empty(&ctxt->ios));
 
                                if (!locked)
-                                       bch2_bucket_nocow_lock(&c->nocow_locks,
-                                                              PTR_BUCKET_POS(c, &p.ptr), 0);
+                                       bch2_bucket_nocow_lock(&c->nocow_locks, bucket, 0);
                        } else {
-                               if (!bch2_bucket_nocow_trylock(&c->nocow_locks,
-                                                              PTR_BUCKET_POS(c, &p.ptr), 0)) {
+                               if (!bch2_bucket_nocow_trylock(&c->nocow_locks, bucket, 0)) {
                                        ret = -BCH_ERR_nocow_lock_blocked;
                                        goto err;
                                }
@@ -650,10 +651,11 @@ int bch2_data_update_init(struct btree_trans *trans,
 err:
        i = 0;
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
+               struct bch_dev *ca = bch2_dev_bkey_exists(c, p.ptr.dev);
+               struct bpos bucket = PTR_BUCKET_POS(ca, &p.ptr);
                if ((1U << i) & ptrs_locked)
-                       bch2_bucket_nocow_unlock(&c->nocow_locks,
-                                                PTR_BUCKET_POS(c, &p.ptr), 0);
-               bch2_dev_put(bch2_dev_bkey_exists(c, p.ptr.dev));
+                       bch2_bucket_nocow_unlock(&c->nocow_locks, bucket, 0);
+               bch2_dev_put(ca);
                i++;
        }
 
index ea10f838d9ccb9731a213a2902d4e94c4ab75fba..f09df7f9036a0642f4b76bfecf93cce78e5be9c9 100644 (file)
@@ -164,6 +164,7 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
 /* Triggers: */
 
 static int __mark_stripe_bucket(struct btree_trans *trans,
+                               struct bch_dev *ca,
                                struct bkey_s_c_stripe s,
                                unsigned ptr_idx, bool deleting,
                                struct bpos bucket,
@@ -179,13 +180,6 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
        int ret = 0;
 
        struct bch_fs *c = trans->c;
-       struct bch_dev *ca = bch2_dev_tryget(c, ptr->dev);
-       if (unlikely(!ca)) {
-               if (!(flags & BTREE_TRIGGER_overwrite))
-                       ret = -EIO;
-               goto err;
-       }
-
        if (deleting)
                sectors = -sectors;
 
@@ -263,7 +257,6 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
 
        alloc_data_type_set(a, data_type);
 err:
-       bch2_dev_put(ca);
        printbuf_exit(&buf);
        return ret;
 }
@@ -275,34 +268,40 @@ static int mark_stripe_bucket(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        const struct bch_extent_ptr *ptr = s.v->ptrs + ptr_idx;
-       struct bpos bucket = PTR_BUCKET_POS(c, ptr);
+       int ret = 0;
+
+       struct bch_dev *ca = bch2_dev_tryget(c, ptr->dev);
+       if (unlikely(!ca)) {
+               if (!(flags & BTREE_TRIGGER_overwrite))
+                       ret = -EIO;
+               goto err;
+       }
+
+       struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
 
        if (flags & BTREE_TRIGGER_transactional) {
                struct bkey_i_alloc_v4 *a =
                        bch2_trans_start_alloc_update(trans, bucket);
-               return PTR_ERR_OR_ZERO(a) ?:
-                       __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &a->v, flags);
+               ret = PTR_ERR_OR_ZERO(a) ?:
+                       __mark_stripe_bucket(trans, ca, s, ptr_idx, deleting, bucket, &a->v, flags);
        }
 
        if (flags & BTREE_TRIGGER_gc) {
-               struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
-
                percpu_down_read(&c->mark_lock);
                struct bucket *g = gc_bucket(ca, bucket.offset);
                bucket_lock(g);
                struct bch_alloc_v4 old = bucket_m_to_alloc(*g), new = old;
-               int ret = __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &new, flags);
+               ret = __mark_stripe_bucket(trans, ca, s, ptr_idx, deleting, bucket, &new, flags);
                if (!ret) {
                        alloc_to_bucket(g, new);
                        bch2_dev_usage_update(c, ca, &old, &new, 0, true);
                }
                bucket_unlock(g);
                percpu_up_read(&c->mark_lock);
-               return ret;
        }
-
-       BUG();
-       return 0;
+err:
+       bch2_dev_put(ca);
+       return ret;
 }
 
 static int mark_stripe_buckets(struct btree_trans *trans,
@@ -1298,17 +1297,21 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
 {
        struct bch_fs *c = trans->c;
        struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
-       struct bch_extent_ptr bucket = v->ptrs[block];
-       struct bpos bucket_pos = PTR_BUCKET_POS(c, &bucket);
+       struct bch_extent_ptr ptr = v->ptrs[block];
        struct bpos bp_pos = POS_MIN;
        int ret = 0;
 
+       struct bch_dev *ca = bch2_dev_tryget(c, ptr.dev);
+       if (!ca)
+               return -EIO;
+
+       struct bpos bucket_pos = PTR_BUCKET_POS(ca, &ptr);
+
        while (1) {
                ret = commit_do(trans, NULL, NULL,
                                BCH_TRANS_COMMIT_no_check_rw|
                                BCH_TRANS_COMMIT_no_enospc,
-                       ec_stripe_update_extent(trans, bucket_pos, bucket.gen,
-                                               s, &bp_pos));
+                       ec_stripe_update_extent(trans, bucket_pos, ptr.gen, s, &bp_pos));
                if (ret)
                        break;
                if (bkey_eq(bp_pos, POS_MAX))
@@ -1317,6 +1320,7 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
                bp_pos = bpos_nosnap_successor(bp_pos);
        }
 
+       bch2_dev_put(ca);
        return ret;
 }
 
index af9bd7c45f21eab92ad5a7b4a993a337c88f7369..1091b066639e4d0a7ed8bc522d2d85525898c0fe 100644 (file)
@@ -768,7 +768,7 @@ static noinline void read_from_stale_dirty_pointer(struct btree_trans *trans,
        int ret;
 
        bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
-                            PTR_BUCKET_POS(c, &ptr),
+                            PTR_BUCKET_POS(ca, &ptr),
                             BTREE_ITER_cached);
 
        prt_printf(&buf, "Attempting to read from stale dirty pointer:\n");
index 55e24c83fb19788829a85bafc10021b4007263b9..40c8f884422416dae659e1765d9652ea8120dd16 100644 (file)
@@ -1117,10 +1117,12 @@ static inline void bch2_nocow_write_unlock(struct bch_write_op *op)
        for_each_keylist_key(&op->insert_keys, k) {
                struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(k));
 
-               bkey_for_each_ptr(ptrs, ptr)
+               bkey_for_each_ptr(ptrs, ptr) {
+                       struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
                        bch2_bucket_nocow_unlock(&c->nocow_locks,
-                                                PTR_BUCKET_POS(c, ptr),
+                                                PTR_BUCKET_POS(ca, ptr),
                                                 BUCKET_NOCOW_LOCK_UPDATE);
+               }
        }
 }
 
@@ -1270,12 +1272,13 @@ retry:
                /* Get iorefs before dropping btree locks: */
                struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
                bkey_for_each_ptr(ptrs, ptr) {
-                       struct bpos b = PTR_BUCKET_POS(c, ptr);
+                       struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
+                       struct bpos b = PTR_BUCKET_POS(ca, ptr);
                        struct nocow_lock_bucket *l =
                                bucket_nocow_lock(&c->nocow_locks, bucket_to_u64(b));
                        prefetch(l);
 
-                       if (unlikely(!bch2_dev_get_ioref(bch2_dev_bkey_exists(c, ptr->dev), WRITE)))
+                       if (unlikely(!bch2_dev_get_ioref(ca, WRITE)))
                                goto err_get_ioref;
 
                        /* XXX allocating memory with btree locks held - rare */