diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-12-10 20:58:44 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-12-25 17:37:12 -0500 |
commit | 341283c48f8fa3ca3c4479db38a7cc9e5b2878eb (patch) | |
tree | d36f09719cf1a1e9c16533e29ef072e7d96db6be | |
parent | 9736afd6524b023a34e4a926ddc288685544e2ec (diff) |
bcachefs: bch2_alloc_write()
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@gmail.com>
-rw-r--r-- | fs/bcachefs/alloc_background.c | 54 | ||||
-rw-r--r-- | fs/bcachefs/alloc_background.h | 15 | ||||
-rw-r--r-- | fs/bcachefs/buckets.c | 43 | ||||
-rw-r--r-- | fs/bcachefs/recovery.c | 2 |
4 files changed, 49 insertions, 65 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index bf3611e76912..95788aa152e1 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -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; diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h index b1efc1494dc4..6698d9c75d07 100644 --- a/fs/bcachefs/alloc_background.h +++ b/fs/bcachefs/alloc_background.h @@ -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 *); diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 3d764599a23f..10b05f7b7ada 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -1481,8 +1481,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) { @@ -1490,14 +1489,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 = btree_trans_peek_updates(trans, BTREE_ID_alloc, pos); 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| @@ -1505,7 +1499,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; } if (update && !bpos_cmp(update->k.p, pos)) { @@ -1517,22 +1511,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, @@ -1540,8 +1532,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: @@ -1671,7 +1662,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 @@ -1682,9 +1672,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, @@ -1734,8 +1724,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: @@ -1983,7 +1972,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), @@ -1996,9 +1984,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, @@ -2015,8 +2003,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: diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index 460b1ba22c8e..29fe6260ace5 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -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; |