bcachefs: bch2_bucket_ref_update() now takes bch_dev
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 30 Apr 2024 20:20:49 +0000 (16:20 -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/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/ec.c

index 525a7548fab7a9866760f28908051c7abb96d510..68f2d5952abdcf4f8670766f2a0e88d447ad2116 100644 (file)
@@ -700,15 +700,14 @@ fsck_err:
        return ret;
 }
 
-int bch2_bucket_ref_update(struct btree_trans *trans,
-                         struct bkey_s_c k,
-                         const struct bch_extent_ptr *ptr,
-                         s64 sectors, enum bch_data_type ptr_data_type,
-                         u8 b_gen, u8 bucket_data_type,
-                         u32 *bucket_sectors)
+int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
+                          struct bkey_s_c k,
+                          const struct bch_extent_ptr *ptr,
+                          s64 sectors, enum bch_data_type ptr_data_type,
+                          u8 b_gen, u8 bucket_data_type,
+                          u32 *bucket_sectors)
 {
        struct bch_fs *c = trans->c;
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
        size_t bucket_nr = PTR_BUCKET_NR(ca, ptr);
        struct printbuf buf = PRINTBUF;
        bool inserting = sectors > 0;
@@ -939,7 +938,7 @@ need_mark:
 
 /* KEY_TYPE_extent: */
 
-static int __mark_pointer(struct btree_trans *trans,
+static int __mark_pointer(struct btree_trans *trans, struct bch_dev *ca,
                          struct bkey_s_c k,
                          const struct bch_extent_ptr *ptr,
                          s64 sectors, enum bch_data_type ptr_data_type,
@@ -948,7 +947,7 @@ static int __mark_pointer(struct btree_trans *trans,
        u32 *dst_sectors = !ptr->cached
                ? &a->dirty_sectors
                : &a->cached_sectors;
-       int ret = bch2_bucket_ref_update(trans, k, ptr, sectors, ptr_data_type,
+       int ret = bch2_bucket_ref_update(trans, ca, k, ptr, sectors, ptr_data_type,
                                         a->gen, a->data_type, dst_sectors);
 
        if (ret)
@@ -966,45 +965,51 @@ static int bch2_trigger_pointer(struct btree_trans *trans,
                        enum btree_iter_update_trigger_flags flags)
 {
        bool insert = !(flags & BTREE_TRIGGER_overwrite);
+       int ret = 0;
+
+       struct bch_fs *c = trans->c;
+       struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev);
+       if (unlikely(!ca)) {
+               if (insert)
+                       ret = -EIO;
+               goto err;
+       }
+
        struct bpos bucket;
        struct bch_backpointer bp;
-
        bch2_extent_ptr_to_bp(trans->c, btree_id, level, k, p, entry, &bucket, &bp);
        *sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);
 
        if (flags & BTREE_TRIGGER_transactional) {
                struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket);
-               int ret = PTR_ERR_OR_ZERO(a) ?:
-                       __mark_pointer(trans, k, &p.ptr, *sectors, bp.data_type, &a->v);
+               ret = PTR_ERR_OR_ZERO(a) ?:
+                       __mark_pointer(trans, ca, k, &p.ptr, *sectors, bp.data_type, &a->v);
                if (ret)
-                       return ret;
+                       goto err;
 
                if (!p.ptr.cached) {
                        ret = bch2_bucket_backpointer_mod(trans, bucket, bp, k, insert);
                        if (ret)
-                               return ret;
+                               goto err;
                }
        }
 
        if (flags & BTREE_TRIGGER_gc) {
-               struct bch_fs *c = trans->c;
-               struct bch_dev *ca = bch2_dev_bkey_exists(c, p.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_pointer(trans, k, &p.ptr, *sectors, bp.data_type, &new);
+               ret = __mark_pointer(trans, ca, k, &p.ptr, *sectors, bp.data_type, &new);
                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;
        }
-
-       return 0;
+err:
+       bch2_dev_put(ca);
+       return ret;
 }
 
 static int bch2_trigger_stripe_ptr(struct btree_trans *trans,
index 95cf3c2907344106e15ac90468e4f736c552e5b8..46bf66d6b2540ef5fdb6be5608d96d61047b09d7 100644 (file)
@@ -330,8 +330,8 @@ int bch2_replicas_deltas_realloc(struct btree_trans *, unsigned);
 
 void bch2_fs_usage_initialize(struct bch_fs *);
 
-int bch2_bucket_ref_update(struct btree_trans *, struct bkey_s_c,
-                          const struct bch_extent_ptr *,
+int bch2_bucket_ref_update(struct btree_trans *, struct bch_dev *,
+                          struct bkey_s_c, const struct bch_extent_ptr *,
                           s64, enum bch_data_type, u8, u8, u32 *);
 
 int bch2_check_fix_ptrs(struct btree_trans *,
index 330c3da70b96fd1f322df7ba1d083870e15f49e0..ea10f838d9ccb9731a213a2902d4e94c4ab75fba 100644 (file)
@@ -167,9 +167,9 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
                                struct bkey_s_c_stripe s,
                                unsigned ptr_idx, bool deleting,
                                struct bpos bucket,
-                               struct bch_alloc_v4 *a)
+                               struct bch_alloc_v4 *a,
+                               enum btree_iter_update_trigger_flags flags)
 {
-       struct bch_fs *c = trans->c;
        const struct bch_extent_ptr *ptr = s.v->ptrs + ptr_idx;
        unsigned nr_data = s.v->nr_blocks - s.v->nr_redundant;
        bool parity = ptr_idx >= nr_data;
@@ -178,6 +178,14 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
        struct printbuf buf = PRINTBUF;
        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;
 
@@ -239,7 +247,7 @@ static int __mark_stripe_bucket(struct btree_trans *trans,
        }
 
        if (sectors) {
-               ret = bch2_bucket_ref_update(trans, s.s_c, ptr, sectors, data_type,
+               ret = bch2_bucket_ref_update(trans, ca, s.s_c, ptr, sectors, data_type,
                                             a->gen, a->data_type, &a->dirty_sectors);
                if (ret)
                        goto err;
@@ -255,6 +263,7 @@ 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;
 }
@@ -272,7 +281,7 @@ static int mark_stripe_bucket(struct btree_trans *trans,
                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);
+                       __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &a->v, flags);
        }
 
        if (flags & BTREE_TRIGGER_gc) {
@@ -282,7 +291,7 @@ static int mark_stripe_bucket(struct btree_trans *trans,
                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);
+               int ret = __mark_stripe_bucket(trans, s, ptr_idx, deleting, bucket, &new, flags);
                if (!ret) {
                        alloc_to_bucket(g, new);
                        bch2_dev_usage_update(c, ca, &old, &new, 0, true);