1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_ALLOC_FOREGROUND_H
3 #define _BCACHEFS_ALLOC_FOREGROUND_H
6 #include "alloc_types.h"
8 #include <linux/hash.h>
15 struct dev_alloc_list {
17 u8 devs[BCH_SB_MEMBERS_MAX];
20 struct dev_alloc_list bch2_dev_alloc_list(struct bch_fs *,
21 struct dev_stripe_state *,
22 struct bch_devs_mask *);
23 void bch2_dev_stripe_increment(struct bch_dev *, struct dev_stripe_state *);
25 long bch2_bucket_alloc_new_fs(struct bch_dev *);
27 struct open_bucket *bch2_bucket_alloc(struct bch_fs *, struct bch_dev *,
28 enum alloc_reserve, bool,
31 static inline void ob_push(struct bch_fs *c, struct open_buckets *obs,
32 struct open_bucket *ob)
34 BUG_ON(obs->nr >= ARRAY_SIZE(obs->v));
36 obs->v[obs->nr++] = ob - c->open_buckets;
39 #define open_bucket_for_each(_c, _obs, _ob, _i) \
41 (_i) < (_obs)->nr && \
42 ((_ob) = (_c)->open_buckets + (_obs)->v[_i], true); \
45 static inline struct open_bucket *ec_open_bucket(struct bch_fs *c,
46 struct open_buckets *obs)
48 struct open_bucket *ob;
51 open_bucket_for_each(c, obs, ob, i)
58 void bch2_open_bucket_write_error(struct bch_fs *,
59 struct open_buckets *, unsigned);
61 void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
63 static inline void bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
65 if (atomic_dec_and_test(&ob->pin))
66 __bch2_open_bucket_put(c, ob);
69 static inline void bch2_open_buckets_put(struct bch_fs *c,
70 struct open_buckets *ptrs)
72 struct open_bucket *ob;
75 open_bucket_for_each(c, ptrs, ob, i)
76 bch2_open_bucket_put(c, ob);
80 static inline void bch2_open_bucket_get(struct bch_fs *c,
81 struct write_point *wp,
82 struct open_buckets *ptrs)
84 struct open_bucket *ob;
87 open_bucket_for_each(c, &wp->ptrs, ob, i) {
88 ob->data_type = wp->data_type;
94 static inline open_bucket_idx_t *open_bucket_hashslot(struct bch_fs *c,
95 unsigned dev, u64 bucket)
97 return c->open_buckets_hash +
98 (jhash_3words(dev, bucket, bucket >> 32, 0) &
99 (OPEN_BUCKETS_COUNT - 1));
102 static inline bool bch2_bucket_is_open(struct bch_fs *c, unsigned dev, u64 bucket)
104 open_bucket_idx_t slot = *open_bucket_hashslot(c, dev, bucket);
107 struct open_bucket *ob = &c->open_buckets[slot];
109 if (ob->dev == dev && ob->bucket == bucket)
118 int bch2_bucket_alloc_set(struct bch_fs *, struct open_buckets *,
119 struct dev_stripe_state *, struct bch_devs_mask *,
120 unsigned, unsigned *, bool *, enum alloc_reserve,
121 unsigned, struct closure *);
123 struct write_point *bch2_alloc_sectors_start(struct bch_fs *,
125 struct write_point_specifier,
126 struct bch_devs_list *,
132 struct bch_extent_ptr bch2_ob_ptr(struct bch_fs *, struct open_bucket *);
133 void bch2_alloc_sectors_append_ptrs(struct bch_fs *, struct write_point *,
134 struct bkey_i *, unsigned, bool);
135 void bch2_alloc_sectors_done(struct bch_fs *, struct write_point *);
137 void bch2_open_buckets_stop_dev(struct bch_fs *, struct bch_dev *,
138 struct open_buckets *);
140 void bch2_writepoint_stop(struct bch_fs *, struct bch_dev *,
141 struct write_point *);
143 static inline struct write_point_specifier writepoint_hashed(unsigned long v)
145 return (struct write_point_specifier) { .v = v | 1 };
148 static inline struct write_point_specifier writepoint_ptr(struct write_point *wp)
150 return (struct write_point_specifier) { .v = (unsigned long) wp };
153 void bch2_fs_allocator_foreground_init(struct bch_fs *);
155 void bch2_open_buckets_to_text(struct printbuf *, struct bch_fs *);
157 #endif /* _BCACHEFS_ALLOC_FOREGROUND_H */