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 extern const char * const bch2_alloc_reserves[];
17 struct dev_alloc_list {
19 u8 devs[BCH_SB_MEMBERS_MAX];
22 struct dev_alloc_list bch2_dev_alloc_list(struct bch_fs *,
23 struct dev_stripe_state *,
24 struct bch_devs_mask *);
25 void bch2_dev_stripe_increment(struct bch_dev *, struct dev_stripe_state *);
27 long bch2_bucket_alloc_new_fs(struct bch_dev *);
29 struct open_bucket *bch2_bucket_alloc(struct bch_fs *, struct bch_dev *,
30 enum alloc_reserve, bool,
33 static inline void ob_push(struct bch_fs *c, struct open_buckets *obs,
34 struct open_bucket *ob)
36 BUG_ON(obs->nr >= ARRAY_SIZE(obs->v));
38 obs->v[obs->nr++] = ob - c->open_buckets;
41 #define open_bucket_for_each(_c, _obs, _ob, _i) \
43 (_i) < (_obs)->nr && \
44 ((_ob) = (_c)->open_buckets + (_obs)->v[_i], true); \
47 static inline struct open_bucket *ec_open_bucket(struct bch_fs *c,
48 struct open_buckets *obs)
50 struct open_bucket *ob;
53 open_bucket_for_each(c, obs, ob, i)
60 void bch2_open_bucket_write_error(struct bch_fs *,
61 struct open_buckets *, unsigned);
63 void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
65 static inline void bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
67 if (atomic_dec_and_test(&ob->pin))
68 __bch2_open_bucket_put(c, ob);
71 static inline void bch2_open_buckets_put(struct bch_fs *c,
72 struct open_buckets *ptrs)
74 struct open_bucket *ob;
77 open_bucket_for_each(c, ptrs, ob, i)
78 bch2_open_bucket_put(c, ob);
82 static inline void bch2_open_bucket_get(struct bch_fs *c,
83 struct write_point *wp,
84 struct open_buckets *ptrs)
86 struct open_bucket *ob;
89 open_bucket_for_each(c, &wp->ptrs, ob, i) {
90 ob->data_type = wp->data_type;
96 static inline open_bucket_idx_t *open_bucket_hashslot(struct bch_fs *c,
97 unsigned dev, u64 bucket)
99 return c->open_buckets_hash +
100 (jhash_3words(dev, bucket, bucket >> 32, 0) &
101 (OPEN_BUCKETS_COUNT - 1));
104 static inline bool bch2_bucket_is_open(struct bch_fs *c, unsigned dev, u64 bucket)
106 open_bucket_idx_t slot = *open_bucket_hashslot(c, dev, bucket);
109 struct open_bucket *ob = &c->open_buckets[slot];
111 if (ob->dev == dev && ob->bucket == bucket)
120 static inline bool bch2_bucket_is_open_safe(struct bch_fs *c, unsigned dev, u64 bucket)
124 if (bch2_bucket_is_open(c, dev, bucket))
127 spin_lock(&c->freelist_lock);
128 ret = bch2_bucket_is_open(c, dev, bucket);
129 spin_unlock(&c->freelist_lock);
134 int bch2_bucket_alloc_set(struct bch_fs *, struct open_buckets *,
135 struct dev_stripe_state *, struct bch_devs_mask *,
136 unsigned, unsigned *, bool *, enum alloc_reserve,
137 unsigned, struct closure *);
139 struct write_point *bch2_alloc_sectors_start_trans(struct btree_trans *,
141 struct write_point_specifier,
142 struct bch_devs_list *,
147 struct write_point *bch2_alloc_sectors_start(struct bch_fs *,
149 struct write_point_specifier,
150 struct bch_devs_list *,
156 struct bch_extent_ptr bch2_ob_ptr(struct bch_fs *, struct open_bucket *);
157 void bch2_alloc_sectors_append_ptrs(struct bch_fs *, struct write_point *,
158 struct bkey_i *, unsigned, bool);
159 void bch2_alloc_sectors_done(struct bch_fs *, struct write_point *);
161 void bch2_open_buckets_stop_dev(struct bch_fs *, struct bch_dev *,
162 struct open_buckets *);
164 void bch2_writepoint_stop(struct bch_fs *, struct bch_dev *,
165 struct write_point *);
167 static inline struct write_point_specifier writepoint_hashed(unsigned long v)
169 return (struct write_point_specifier) { .v = v | 1 };
172 static inline struct write_point_specifier writepoint_ptr(struct write_point *wp)
174 return (struct write_point_specifier) { .v = (unsigned long) wp };
177 void bch2_fs_allocator_foreground_init(struct bch_fs *);
179 void bch2_open_buckets_to_text(struct printbuf *, struct bch_fs *);
181 #endif /* _BCACHEFS_ALLOC_FOREGROUND_H */