]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/alloc_foreground.h
Update bcachefs sources to 9d554fa16d bcachefs: Add .to_text() methods for all superb...
[bcachefs-tools-debian] / libbcachefs / alloc_foreground.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_ALLOC_FOREGROUND_H
3 #define _BCACHEFS_ALLOC_FOREGROUND_H
4
5 #include "bcachefs.h"
6 #include "alloc_types.h"
7
8 #include <linux/hash.h>
9
10 struct bkey;
11 struct bch_dev;
12 struct bch_fs;
13 struct bch_devs_List;
14
15 struct dev_alloc_list {
16         unsigned        nr;
17         u8              devs[BCH_SB_MEMBERS_MAX];
18 };
19
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 *);
24
25 long bch2_bucket_alloc_new_fs(struct bch_dev *);
26
27 struct open_bucket *bch2_bucket_alloc(struct bch_fs *, struct bch_dev *,
28                                       enum alloc_reserve, bool,
29                                       struct closure *);
30
31 static inline void ob_push(struct bch_fs *c, struct open_buckets *obs,
32                            struct open_bucket *ob)
33 {
34         BUG_ON(obs->nr >= ARRAY_SIZE(obs->v));
35
36         obs->v[obs->nr++] = ob - c->open_buckets;
37 }
38
39 #define open_bucket_for_each(_c, _obs, _ob, _i)                         \
40         for ((_i) = 0;                                                  \
41              (_i) < (_obs)->nr &&                                       \
42              ((_ob) = (_c)->open_buckets + (_obs)->v[_i], true);        \
43              (_i)++)
44
45 static inline struct open_bucket *ec_open_bucket(struct bch_fs *c,
46                                                  struct open_buckets *obs)
47 {
48         struct open_bucket *ob;
49         unsigned i;
50
51         open_bucket_for_each(c, obs, ob, i)
52                 if (ob->ec)
53                         return ob;
54
55         return NULL;
56 }
57
58 void bch2_open_bucket_write_error(struct bch_fs *,
59                         struct open_buckets *, unsigned);
60
61 void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
62
63 static inline void bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
64 {
65         if (atomic_dec_and_test(&ob->pin))
66                 __bch2_open_bucket_put(c, ob);
67 }
68
69 static inline void bch2_open_buckets_put(struct bch_fs *c,
70                                          struct open_buckets *ptrs)
71 {
72         struct open_bucket *ob;
73         unsigned i;
74
75         open_bucket_for_each(c, ptrs, ob, i)
76                 bch2_open_bucket_put(c, ob);
77         ptrs->nr = 0;
78 }
79
80 static inline void bch2_open_bucket_get(struct bch_fs *c,
81                                         struct write_point *wp,
82                                         struct open_buckets *ptrs)
83 {
84         struct open_bucket *ob;
85         unsigned i;
86
87         open_bucket_for_each(c, &wp->ptrs, ob, i) {
88                 ob->data_type = wp->data_type;
89                 atomic_inc(&ob->pin);
90                 ob_push(c, ptrs, ob);
91         }
92 }
93
94 static inline open_bucket_idx_t *open_bucket_hashslot(struct bch_fs *c,
95                                                   unsigned dev, u64 bucket)
96 {
97         return c->open_buckets_hash +
98                 (jhash_3words(dev, bucket, bucket >> 32, 0) &
99                  (OPEN_BUCKETS_COUNT - 1));
100 }
101
102 static inline bool bch2_bucket_is_open(struct bch_fs *c, unsigned dev, u64 bucket)
103 {
104         open_bucket_idx_t slot = *open_bucket_hashslot(c, dev, bucket);
105
106         while (slot) {
107                 struct open_bucket *ob = &c->open_buckets[slot];
108
109                 if (ob->dev == dev && ob->bucket == bucket)
110                         return true;
111
112                 slot = ob->hash;
113         }
114
115         return false;
116 }
117
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 *);
122
123 struct write_point *bch2_alloc_sectors_start(struct bch_fs *,
124                                              unsigned, unsigned,
125                                              struct write_point_specifier,
126                                              struct bch_devs_list *,
127                                              unsigned, unsigned,
128                                              enum alloc_reserve,
129                                              unsigned,
130                                              struct closure *);
131
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 *);
136
137 void bch2_open_buckets_stop_dev(struct bch_fs *, struct bch_dev *,
138                                 struct open_buckets *);
139
140 void bch2_writepoint_stop(struct bch_fs *, struct bch_dev *,
141                           struct write_point *);
142
143 static inline struct write_point_specifier writepoint_hashed(unsigned long v)
144 {
145         return (struct write_point_specifier) { .v = v | 1 };
146 }
147
148 static inline struct write_point_specifier writepoint_ptr(struct write_point *wp)
149 {
150         return (struct write_point_specifier) { .v = (unsigned long) wp };
151 }
152
153 void bch2_fs_allocator_foreground_init(struct bch_fs *);
154
155 void bch2_open_buckets_to_text(struct printbuf *, struct bch_fs *);
156
157 #endif /* _BCACHEFS_ALLOC_FOREGROUND_H */