bcachefs: bch2_alloc_write()
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 11 Dec 2021 01:58:44 +0000 (20:58 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:18 +0000 (17:09 -0400)
This adds a new helper that much like the one we have for inode updates,
that allocates the packed alloc key, packs it and calls
bch2_trans_update.

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

index dc1e09b138b622c3d6c91dd4756ccc8abc48e69e..4953cbee2655b1dc7d557231d8c9e27b2d8f9279 100644 (file)
@@ -38,6 +38,15 @@ static const unsigned BCH_ALLOC_V1_FIELD_BYTES[] = {
 #undef x
 };
 
+struct bkey_alloc_buf {
+       struct bkey_i   k;
+       struct bch_alloc_v3 v;
+
+#define x(_name,  _bits)               + _bits / 8
+       u8              _pad[0 + BCH_ALLOC_FIELDS_V2()];
+#undef  x
+} __attribute__((packed, aligned(8)));
+
 /* Persistent alloc info: */
 
 static inline u64 alloc_field_v1_get(const struct bch_alloc *a,
@@ -244,13 +253,26 @@ struct bkey_alloc_unpacked bch2_alloc_unpack(struct bkey_s_c k)
        return ret;
 }
 
-void bch2_alloc_pack(struct bch_fs *c,
-                    struct bkey_alloc_buf *dst,
-                    const struct bkey_alloc_unpacked src)
+static void bch2_alloc_pack(struct bch_fs *c,
+                           struct bkey_alloc_buf *dst,
+                           const struct bkey_alloc_unpacked src)
 {
        bch2_alloc_pack_v3(dst, src);
 }
 
+int bch2_alloc_write(struct btree_trans *trans, struct btree_iter *iter,
+                    struct bkey_alloc_unpacked *u, unsigned trigger_flags)
+{
+       struct bkey_alloc_buf *a;
+
+       a = bch2_trans_kmalloc(trans, sizeof(struct bkey_alloc_buf));
+       if (IS_ERR(a))
+               return PTR_ERR(a);
+
+       bch2_alloc_pack(trans->c, a, *u);
+       return bch2_trans_update(trans, iter, &a->k, trigger_flags);
+}
+
 static unsigned bch_alloc_v1_val_u64s(const struct bch_alloc *a)
 {
        unsigned i, bytes = offsetof(struct bch_alloc, data);
@@ -375,7 +397,6 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
        struct bucket *g;
        struct bucket_mark m;
        struct bkey_alloc_unpacked old_u, new_u;
-       struct bkey_alloc_buf a;
        int ret;
 retry:
        bch2_trans_begin(trans);
@@ -402,8 +423,7 @@ retry:
        if (!bkey_alloc_unpacked_cmp(old_u, new_u))
                return 0;
 
-       bch2_alloc_pack(c, &a, new_u);
-       ret   = bch2_trans_update(trans, iter, &a.k,
+       ret   = bch2_alloc_write(trans, iter, &new_u,
                                  BTREE_TRIGGER_NORUN) ?:
                bch2_trans_commit(trans, NULL, NULL,
                                BTREE_INSERT_NOFAIL|flags);
@@ -413,7 +433,7 @@ err:
        return ret;
 }
 
-int bch2_alloc_write(struct bch_fs *c, unsigned flags)
+int bch2_alloc_write_all(struct bch_fs *c, unsigned flags)
 {
        struct btree_trans trans;
        struct btree_iter iter;
@@ -453,7 +473,6 @@ int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
        struct bch_dev *ca = bch_dev_bkey_exists(c, dev);
        struct btree_iter iter;
        struct bucket *g;
-       struct bkey_alloc_buf *a;
        struct bkey_alloc_unpacked u;
        u64 *time, now;
        int ret = 0;
@@ -466,11 +485,6 @@ int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
        if (ret)
                goto out;
 
-       a = bch2_trans_kmalloc(trans, sizeof(struct bkey_alloc_buf));
-       ret = PTR_ERR_OR_ZERO(a);
-       if (ret)
-               goto out;
-
        percpu_down_read(&c->mark_lock);
        g = bucket(ca, bucket_nr);
        u = alloc_mem_to_key(&iter, g, READ_ONCE(g->mark));
@@ -483,8 +497,7 @@ int bch2_bucket_io_time_reset(struct btree_trans *trans, unsigned dev,
 
        *time = now;
 
-       bch2_alloc_pack(c, a, u);
-       ret   = bch2_trans_update(trans, &iter, &a->k, 0) ?:
+       ret   = bch2_alloc_write(trans, &iter, &u, 0) ?:
                bch2_trans_commit(trans, NULL, NULL, 0);
 out:
        bch2_trans_iter_exit(trans, &iter);
@@ -752,7 +765,6 @@ static int bucket_invalidate_btree(struct btree_trans *trans,
                                   struct bch_dev *ca, u64 b)
 {
        struct bch_fs *c = trans->c;
-       struct bkey_alloc_buf *a;
        struct bkey_alloc_unpacked u;
        struct bucket *g;
        struct bucket_mark m;
@@ -765,11 +777,6 @@ static int bucket_invalidate_btree(struct btree_trans *trans,
                             BTREE_ITER_CACHED_NOFILL|
                             BTREE_ITER_INTENT);
 
-       a = bch2_trans_kmalloc(trans, sizeof(*a));
-       ret = PTR_ERR_OR_ZERO(a);
-       if (ret)
-               goto err;
-
        ret = bch2_btree_iter_traverse(&iter);
        if (ret)
                goto err;
@@ -787,9 +794,8 @@ static int bucket_invalidate_btree(struct btree_trans *trans,
        u.read_time     = atomic64_read(&c->io_clock[READ].now);
        u.write_time    = atomic64_read(&c->io_clock[WRITE].now);
 
-       bch2_alloc_pack(c, a, u);
-       ret = bch2_trans_update(trans, &iter, &a->k,
-                               BTREE_TRIGGER_BUCKET_INVALIDATE);
+       ret = bch2_alloc_write(trans, &iter, &u,
+                              BTREE_TRIGGER_BUCKET_INVALIDATE);
 err:
        bch2_trans_iter_exit(trans, &iter);
        return ret;
index b1efc1494dc4f84e45dd22dc4999280247ee0d6f..6698d9c75d07c12264bcb29cab296ea2f43208bb 100644 (file)
@@ -20,15 +20,6 @@ struct bkey_alloc_unpacked {
 #undef  x
 };
 
-struct bkey_alloc_buf {
-       struct bkey_i   k;
-       struct bch_alloc_v3 v;
-
-#define x(_name,  _bits)               + _bits / 8
-       u8              _pad[0 + BCH_ALLOC_FIELDS_V2()];
-#undef  x
-} __attribute__((packed, aligned(8)));
-
 /* How out of date a pointer gen is allowed to be: */
 #define BUCKET_GC_GEN_MAX      96U
 
@@ -46,8 +37,8 @@ static inline bool bkey_alloc_unpacked_cmp(struct bkey_alloc_unpacked l,
 }
 
 struct bkey_alloc_unpacked bch2_alloc_unpack(struct bkey_s_c);
-void bch2_alloc_pack(struct bch_fs *, struct bkey_alloc_buf *,
-                    const struct bkey_alloc_unpacked);
+int bch2_alloc_write(struct btree_trans *, struct btree_iter *,
+                    struct bkey_alloc_unpacked *, unsigned);
 
 int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int);
 
@@ -137,7 +128,7 @@ void bch2_dev_allocator_quiesce(struct bch_fs *, struct bch_dev *);
 void bch2_dev_allocator_stop(struct bch_dev *);
 int bch2_dev_allocator_start(struct bch_dev *);
 
-int bch2_alloc_write(struct bch_fs *, unsigned);
+int bch2_alloc_write_all(struct bch_fs *, unsigned);
 void bch2_fs_allocator_background_init(struct bch_fs *);
 
 void bch2_open_buckets_to_text(struct printbuf *, struct bch_fs *);
index bf564757aa28ef04b9d8d7c4e24c4bc60bcd12b7..6bbf088cd095b87ffc39542cbd9f81cbb13f3e8c 100644 (file)
@@ -1485,8 +1485,7 @@ need_mark:
 
 /* trans_mark: */
 
-static struct bkey_alloc_buf *
-bch2_trans_start_alloc_update(struct btree_trans *trans, struct btree_iter *iter,
+static int bch2_trans_start_alloc_update(struct btree_trans *trans, struct btree_iter *iter,
                              const struct bch_extent_ptr *ptr,
                              struct bkey_alloc_unpacked *u)
 {
@@ -1494,14 +1493,9 @@ bch2_trans_start_alloc_update(struct btree_trans *trans, struct btree_iter *iter
        struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
        struct bpos pos = POS(ptr->dev, PTR_BUCKET_NR(ca, ptr));
        struct bucket *g;
-       struct bkey_alloc_buf *a;
        struct bkey_i *update;
        int ret;
 
-       a = bch2_trans_kmalloc(trans, sizeof(struct bkey_alloc_buf));
-       if (IS_ERR(a))
-               return a;
-
        bch2_trans_iter_init(trans, iter, BTREE_ID_alloc, pos,
                             BTREE_ITER_CACHED|
                             BTREE_ITER_CACHED_NOFILL|
@@ -1509,7 +1503,7 @@ bch2_trans_start_alloc_update(struct btree_trans *trans, struct btree_iter *iter
        ret = bch2_btree_iter_traverse(iter);
        if (ret) {
                bch2_trans_iter_exit(trans, iter);
-               return ERR_PTR(ret);
+               return ret;
        }
 
        update = __bch2_btree_trans_peek_updates(iter);
@@ -1522,22 +1516,20 @@ bch2_trans_start_alloc_update(struct btree_trans *trans, struct btree_iter *iter
                percpu_up_read(&c->mark_lock);
        }
 
-       return a;
+       return 0;
 }
 
 static int bch2_trans_mark_pointer(struct btree_trans *trans,
                        struct bkey_s_c k, struct extent_ptr_decoded p,
                        s64 sectors, enum bch_data_type data_type)
 {
-       struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct bkey_alloc_unpacked u;
-       struct bkey_alloc_buf *a;
        int ret;
 
-       a = bch2_trans_start_alloc_update(trans, &iter, &p.ptr, &u);
-       if (IS_ERR(a))
-               return PTR_ERR(a);
+       ret = bch2_trans_start_alloc_update(trans, &iter, &p.ptr, &u);
+       if (ret)
+               return ret;
 
        ret = __mark_pointer(trans, k, &p.ptr, sectors, data_type,
                             u.gen, &u.data_type,
@@ -1545,8 +1537,7 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
        if (ret)
                goto out;
 
-       bch2_alloc_pack(c, a, u);
-       ret = bch2_trans_update(trans, &iter, &a->k, 0);
+       ret = bch2_alloc_write(trans, &iter, &u, 0);
        if (ret)
                goto out;
 out:
@@ -1676,7 +1667,6 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans,
 {
        struct bch_fs *c = trans->c;
        const struct bch_extent_ptr *ptr = &s.v->ptrs[idx];
-       struct bkey_alloc_buf *a;
        struct btree_iter iter;
        struct bkey_alloc_unpacked u;
        enum bch_data_type data_type = idx >= s.v->nr_blocks - s.v->nr_redundant
@@ -1687,9 +1677,9 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans,
        if (deleting)
                sectors = -sectors;
 
-       a = bch2_trans_start_alloc_update(trans, &iter, ptr, &u);
-       if (IS_ERR(a))
-               return PTR_ERR(a);
+       ret = bch2_trans_start_alloc_update(trans, &iter, ptr, &u);
+       if (ret)
+               return ret;
 
        ret = check_bucket_ref(c, s.s_c, ptr, sectors, data_type,
                               u.gen, u.data_type,
@@ -1739,8 +1729,7 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans,
        if (data_type)
                u.data_type = !deleting ? data_type : 0;
 
-       bch2_alloc_pack(c, a, u);
-       ret = bch2_trans_update(trans, &iter, &a->k, 0);
+       ret = bch2_alloc_write(trans, &iter, &u, 0);
        if (ret)
                goto err;
 err:
@@ -1988,7 +1977,6 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        struct btree_iter iter;
        struct bkey_alloc_unpacked u;
-       struct bkey_alloc_buf *a;
        struct bch_extent_ptr ptr = {
                .dev = ca->dev_idx,
                .offset = bucket_to_sector(ca, b),
@@ -2001,9 +1989,9 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
        if (b >= ca->mi.nbuckets)
                return 0;
 
-       a = bch2_trans_start_alloc_update(trans, &iter, &ptr, &u);
-       if (IS_ERR(a))
-               return PTR_ERR(a);
+       ret = bch2_trans_start_alloc_update(trans, &iter, &ptr, &u);
+       if (ret)
+               return ret;
 
        if (u.data_type && u.data_type != type) {
                bch2_fsck_err(c, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
@@ -2020,8 +2008,7 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
        u.data_type     = type;
        u.dirty_sectors = sectors;
 
-       bch2_alloc_pack(c, a, u);
-       ret = bch2_trans_update(trans, &iter, &a->k, 0);
+       ret = bch2_alloc_write(trans, &iter, &u, 0);
        if (ret)
                goto out;
 out:
index 460b1ba22c8e40190b1dd9bf10745e5952a2eb41..29fe6260ace5ad6c9ecb6d55765edd6a296f5382 100644 (file)
@@ -1238,7 +1238,7 @@ use_clean:
                 */
                bch_verbose(c, "writing allocation info");
                err = "error writing out alloc info";
-               ret = bch2_alloc_write(c, BTREE_INSERT_LAZY_RW);
+               ret = bch2_alloc_write_all(c, BTREE_INSERT_LAZY_RW);
                if (ret) {
                        bch_err(c, "error writing alloc info");
                        goto err;