]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/extents.h
Update bcachefs sources to 14ce2a2031 bcachefs: fixes for building in userspace
[bcachefs-tools-debian] / libbcachefs / extents.h
1 #ifndef _BCACHEFS_EXTENTS_H
2 #define _BCACHEFS_EXTENTS_H
3
4 #include "bcachefs.h"
5 #include "bkey.h"
6 #include "extents_types.h"
7
8 struct bch_fs;
9 struct journal_res;
10 struct btree_node_iter;
11 struct btree_insert;
12 struct btree_insert_entry;
13 struct extent_insert_hook;
14 struct bch_devs_mask;
15 union bch_extent_crc;
16
17 struct btree_nr_keys bch2_key_sort_fix_overlapping(struct bset *,
18                                                   struct btree *,
19                                                   struct btree_node_iter *);
20 struct btree_nr_keys bch2_extent_sort_fix_overlapping(struct bch_fs *c,
21                                                      struct bset *,
22                                                      struct btree *,
23                                                      struct btree_node_iter *);
24
25 extern const struct bkey_ops bch2_bkey_btree_ops;
26 extern const struct bkey_ops bch2_bkey_extent_ops;
27
28 struct extent_pick_ptr
29 bch2_btree_pick_ptr(struct bch_fs *, const struct btree *,
30                     struct bch_devs_mask *avoid);
31
32 void bch2_extent_pick_ptr(struct bch_fs *, struct bkey_s_c,
33                           struct bch_devs_mask *,
34                           struct extent_pick_ptr *);
35
36 enum btree_insert_ret
37 bch2_insert_fixup_extent(struct btree_insert *,
38                         struct btree_insert_entry *);
39
40 bool bch2_extent_normalize(struct bch_fs *, struct bkey_s);
41 void bch2_extent_mark_replicas_cached(struct bch_fs *, struct bkey_s_extent);
42
43 const struct bch_extent_ptr *
44 bch2_extent_has_device(struct bkey_s_c_extent, unsigned);
45
46 unsigned bch2_extent_nr_ptrs(struct bkey_s_c_extent);
47 unsigned bch2_extent_nr_dirty_ptrs(struct bkey_s_c);
48 unsigned bch2_extent_nr_good_ptrs(struct bch_fs *, struct bkey_s_c_extent);
49 unsigned bch2_extent_is_compressed(struct bkey_s_c);
50
51 bool bch2_extent_matches_ptr(struct bch_fs *, struct bkey_s_c_extent,
52                              struct bch_extent_ptr, u64);
53
54 static inline bool bkey_extent_is_data(const struct bkey *k)
55 {
56         switch (k->type) {
57         case BCH_EXTENT:
58         case BCH_EXTENT_CACHED:
59                 return true;
60         default:
61                 return false;
62         }
63 }
64
65 static inline bool bkey_extent_is_allocation(const struct bkey *k)
66 {
67         switch (k->type) {
68         case BCH_EXTENT:
69         case BCH_EXTENT_CACHED:
70         case BCH_RESERVATION:
71                 return true;
72         default:
73                 return false;
74         }
75 }
76
77 static inline bool bch2_extent_is_fully_allocated(struct bkey_s_c k)
78 {
79         return bkey_extent_is_allocation(k.k) &&
80                 !bch2_extent_is_compressed(k);
81 }
82
83 static inline bool bkey_extent_is_cached(const struct bkey *k)
84 {
85         return k->type == BCH_EXTENT_CACHED;
86 }
87
88 static inline void bkey_extent_set_cached(struct bkey *k, bool cached)
89 {
90         EBUG_ON(k->type != BCH_EXTENT &&
91                 k->type != BCH_EXTENT_CACHED);
92
93         k->type = cached ? BCH_EXTENT_CACHED : BCH_EXTENT;
94 }
95
96 static inline unsigned
97 __extent_entry_type(const union bch_extent_entry *e)
98 {
99         return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX;
100 }
101
102 static inline enum bch_extent_entry_type
103 extent_entry_type(const union bch_extent_entry *e)
104 {
105         int ret = __ffs(e->type);
106
107         EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX);
108
109         return ret;
110 }
111
112 static inline size_t extent_entry_bytes(const union bch_extent_entry *entry)
113 {
114         switch (extent_entry_type(entry)) {
115         case BCH_EXTENT_ENTRY_crc32:
116                 return sizeof(struct bch_extent_crc32);
117         case BCH_EXTENT_ENTRY_crc64:
118                 return sizeof(struct bch_extent_crc64);
119         case BCH_EXTENT_ENTRY_crc128:
120                 return sizeof(struct bch_extent_crc128);
121         case BCH_EXTENT_ENTRY_ptr:
122                 return sizeof(struct bch_extent_ptr);
123         default:
124                 BUG();
125         }
126 }
127
128 static inline size_t extent_entry_u64s(const union bch_extent_entry *entry)
129 {
130         return extent_entry_bytes(entry) / sizeof(u64);
131 }
132
133 static inline bool extent_entry_is_ptr(const union bch_extent_entry *e)
134 {
135         return extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr;
136 }
137
138 static inline bool extent_entry_is_crc(const union bch_extent_entry *e)
139 {
140         return !extent_entry_is_ptr(e);
141 }
142
143 union bch_extent_crc {
144         u8                              type;
145         struct bch_extent_crc32         crc32;
146         struct bch_extent_crc64         crc64;
147         struct bch_extent_crc128        crc128;
148 };
149
150 /* downcast, preserves const */
151 #define to_entry(_entry)                                                \
152 ({                                                                      \
153         BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) &&        \
154                      !type_is(_entry, struct bch_extent_ptr *));        \
155                                                                         \
156         __builtin_choose_expr(                                          \
157                 (type_is_exact(_entry, const union bch_extent_crc *) || \
158                  type_is_exact(_entry, const struct bch_extent_ptr *)), \
159                 (const union bch_extent_entry *) (_entry),              \
160                 (union bch_extent_entry *) (_entry));                   \
161 })
162
163 #define __entry_to_crc(_entry)                                          \
164         __builtin_choose_expr(                                          \
165                 type_is_exact(_entry, const union bch_extent_entry *),  \
166                 (const union bch_extent_crc *) (_entry),                \
167                 (union bch_extent_crc *) (_entry))
168
169 #define entry_to_crc(_entry)                                            \
170 ({                                                                      \
171         EBUG_ON((_entry) && !extent_entry_is_crc(_entry));              \
172                                                                         \
173         __entry_to_crc(_entry);                                         \
174 })
175
176 #define entry_to_ptr(_entry)                                            \
177 ({                                                                      \
178         EBUG_ON((_entry) && !extent_entry_is_ptr(_entry));              \
179                                                                         \
180         __builtin_choose_expr(                                          \
181                 type_is_exact(_entry, const union bch_extent_entry *),  \
182                 (const struct bch_extent_ptr *) (_entry),               \
183                 (struct bch_extent_ptr *) (_entry));                    \
184 })
185
186 /* checksum entries: */
187
188 enum bch_extent_crc_type {
189         BCH_EXTENT_CRC_NONE,
190         BCH_EXTENT_CRC32,
191         BCH_EXTENT_CRC64,
192         BCH_EXTENT_CRC128,
193 };
194
195 static inline enum bch_extent_crc_type
196 __extent_crc_type(const union bch_extent_crc *crc)
197 {
198         if (!crc)
199                 return BCH_EXTENT_CRC_NONE;
200
201         switch (extent_entry_type(to_entry(crc))) {
202         case BCH_EXTENT_ENTRY_crc32:
203                 return BCH_EXTENT_CRC32;
204         case BCH_EXTENT_ENTRY_crc64:
205                 return BCH_EXTENT_CRC64;
206         case BCH_EXTENT_ENTRY_crc128:
207                 return BCH_EXTENT_CRC128;
208         default:
209                 BUG();
210         }
211 }
212
213 #define extent_crc_type(_crc)                                           \
214 ({                                                                      \
215         BUILD_BUG_ON(!type_is(_crc, struct bch_extent_crc32 *) &&       \
216                      !type_is(_crc, struct bch_extent_crc64 *) &&       \
217                      !type_is(_crc, struct bch_extent_crc128 *) &&      \
218                      !type_is(_crc, union bch_extent_crc *));           \
219                                                                         \
220           type_is(_crc, struct bch_extent_crc32 *)  ? BCH_EXTENT_CRC32  \
221         : type_is(_crc, struct bch_extent_crc64 *)  ? BCH_EXTENT_CRC64  \
222         : type_is(_crc, struct bch_extent_crc128 *) ? BCH_EXTENT_CRC128 \
223         : __extent_crc_type((union bch_extent_crc *) _crc);             \
224 })
225
226 static inline struct bch_extent_crc_unpacked
227 bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc)
228 {
229 #define common_fields(_crc)                                             \
230                 .csum_type              = _crc.csum_type,               \
231                 .compression_type       = _crc.compression_type,        \
232                 .compressed_size        = _crc._compressed_size + 1,    \
233                 .uncompressed_size      = _crc._uncompressed_size + 1,  \
234                 .offset                 = _crc.offset,                  \
235                 .live_size              = k->size
236
237         switch (extent_crc_type(crc)) {
238         case BCH_EXTENT_CRC_NONE:
239                 return (struct bch_extent_crc_unpacked) {
240                         .compressed_size        = k->size,
241                         .uncompressed_size      = k->size,
242                         .live_size              = k->size,
243                 };
244         case BCH_EXTENT_CRC32:
245                 return (struct bch_extent_crc_unpacked) {
246                         common_fields(crc->crc32),
247                         .csum.lo                = (__force __le64) crc->crc32.csum,
248                 };
249         case BCH_EXTENT_CRC64:
250                 return (struct bch_extent_crc_unpacked) {
251                         common_fields(crc->crc64),
252                         .nonce                  = crc->crc64.nonce,
253                         .csum.lo                = (__force __le64) crc->crc64.csum_lo,
254                         .csum.hi                = (__force __le64) crc->crc64.csum_hi,
255                 };
256         case BCH_EXTENT_CRC128:
257                 return (struct bch_extent_crc_unpacked) {
258                         common_fields(crc->crc128),
259                         .nonce                  = crc->crc128.nonce,
260                         .csum                   = crc->crc128.csum,
261                 };
262         default:
263                 BUG();
264         }
265 #undef common_fields
266 }
267
268 /* Extent entry iteration: */
269
270 #define extent_entry_next(_entry)                                       \
271         ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry)))
272
273 #define extent_entry_last(_e)                                           \
274         vstruct_idx((_e).v, bkey_val_u64s((_e).k))
275
276 /* Iterate over all entries: */
277
278 #define extent_for_each_entry_from(_e, _entry, _start)                  \
279         for ((_entry) = _start;                                         \
280              (_entry) < extent_entry_last(_e);                          \
281              (_entry) = extent_entry_next(_entry))
282
283 #define extent_for_each_entry(_e, _entry)                               \
284         extent_for_each_entry_from(_e, _entry, (_e).v->start)
285
286 /* Iterate over crcs only: */
287
288 #define __extent_crc_next(_e, _p)                                       \
289 ({                                                                      \
290         typeof(&(_e).v->start[0]) _entry = _p;                          \
291                                                                         \
292         while ((_entry) < extent_entry_last(_e) &&                      \
293                !extent_entry_is_crc(_entry))                            \
294                 (_entry) = extent_entry_next(_entry);                   \
295                                                                         \
296         entry_to_crc(_entry < extent_entry_last(_e) ? _entry : NULL);   \
297 })
298
299 #define __extent_for_each_crc(_e, _crc)                                 \
300         for ((_crc) = __extent_crc_next(_e, (_e).v->start);             \
301              (_crc);                                                    \
302              (_crc) = __extent_crc_next(_e, extent_entry_next(to_entry(_crc))))
303
304 #define extent_crc_next(_e, _crc, _iter)                                \
305 ({                                                                      \
306         extent_for_each_entry_from(_e, _iter, _iter)                    \
307                 if (extent_entry_is_crc(_iter)) {                       \
308                         (_crc) = bch2_extent_crc_unpack((_e).k, entry_to_crc(_iter));\
309                         break;                                          \
310                 }                                                       \
311                                                                         \
312         (_iter) < extent_entry_last(_e);                                \
313 })
314
315 #define extent_for_each_crc(_e, _crc, _iter)                            \
316         for ((_crc) = bch2_extent_crc_unpack((_e).k, NULL),             \
317              (_iter) = (_e).v->start;                                   \
318              extent_crc_next(_e, _crc, _iter);                          \
319              (_iter) = extent_entry_next(_iter))
320
321 /* Iterate over pointers, with crcs: */
322
323 #define extent_ptr_crc_next(_e, _ptr, _crc)                             \
324 ({                                                                      \
325         __label__ out;                                                  \
326         typeof(&(_e).v->start[0]) _entry;                               \
327                                                                         \
328         extent_for_each_entry_from(_e, _entry, to_entry(_ptr))          \
329                 if (extent_entry_is_crc(_entry)) {                      \
330                         (_crc) = bch2_extent_crc_unpack((_e).k, entry_to_crc(_entry));\
331                 } else {                                                \
332                         _ptr = entry_to_ptr(_entry);                    \
333                         goto out;                                       \
334                 }                                                       \
335                                                                         \
336         _ptr = NULL;                                                    \
337 out:                                                                    \
338         _ptr;                                                           \
339 })
340
341 #define extent_for_each_ptr_crc(_e, _ptr, _crc)                         \
342         for ((_crc) = bch2_extent_crc_unpack((_e).k, NULL),             \
343              (_ptr) = &(_e).v->start->ptr;                              \
344              ((_ptr) = extent_ptr_crc_next(_e, _ptr, _crc));            \
345              (_ptr)++)
346
347 /* Iterate over pointers only, and from a given position: */
348
349 #define extent_ptr_next(_e, _ptr)                                       \
350 ({                                                                      \
351         struct bch_extent_crc_unpacked _crc;                            \
352                                                                         \
353         extent_ptr_crc_next(_e, _ptr, _crc);                            \
354 })
355
356 #define extent_for_each_ptr(_e, _ptr)                                   \
357         for ((_ptr) = &(_e).v->start->ptr;                              \
358              ((_ptr) = extent_ptr_next(_e, _ptr));                      \
359              (_ptr)++)
360
361 #define extent_ptr_prev(_e, _ptr)                                       \
362 ({                                                                      \
363         typeof(&(_e).v->start->ptr) _p;                                 \
364         typeof(&(_e).v->start->ptr) _prev = NULL;                       \
365                                                                         \
366         extent_for_each_ptr(_e, _p) {                                   \
367                 if (_p == (_ptr))                                       \
368                         break;                                          \
369                 _prev = _p;                                             \
370         }                                                               \
371                                                                         \
372         _prev;                                                          \
373 })
374
375 /*
376  * Use this when you'll be dropping pointers as you iterate. Quadratic,
377  * unfortunately:
378  */
379 #define extent_for_each_ptr_backwards(_e, _ptr)                         \
380         for ((_ptr) = extent_ptr_prev(_e, NULL);                        \
381              (_ptr);                                                    \
382              (_ptr) = extent_ptr_prev(_e, _ptr))
383
384 void bch2_extent_crc_append(struct bkey_i_extent *,
385                             struct bch_extent_crc_unpacked);
386
387 static inline void __extent_entry_push(struct bkey_i_extent *e)
388 {
389         union bch_extent_entry *entry = extent_entry_last(extent_i_to_s(e));
390
391         EBUG_ON(bkey_val_u64s(&e->k) + extent_entry_u64s(entry) >
392                 BKEY_EXTENT_VAL_U64s_MAX);
393
394         e->k.u64s += extent_entry_u64s(entry);
395 }
396
397 static inline void extent_ptr_append(struct bkey_i_extent *e,
398                                      struct bch_extent_ptr ptr)
399 {
400         ptr.type = 1 << BCH_EXTENT_ENTRY_ptr;
401         extent_entry_last(extent_i_to_s(e))->ptr = ptr;
402         __extent_entry_push(e);
403 }
404
405 static inline struct bch_devs_list bch2_extent_devs(struct bkey_s_c_extent e)
406 {
407         struct bch_devs_list ret = (struct bch_devs_list) { 0 };
408         const struct bch_extent_ptr *ptr;
409
410         extent_for_each_ptr(e, ptr)
411                 ret.devs[ret.nr++] = ptr->dev;
412
413         return ret;
414 }
415
416 bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent,
417                                  struct bch_extent_crc_unpacked);
418 bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked);
419 void bch2_extent_drop_redundant_crcs(struct bkey_s_extent);
420
421 void __bch2_extent_drop_ptr(struct bkey_s_extent, struct bch_extent_ptr *);
422 void bch2_extent_drop_ptr(struct bkey_s_extent, struct bch_extent_ptr *);
423 void bch2_extent_drop_ptr_idx(struct bkey_s_extent, unsigned);
424
425 bool bch2_cut_front(struct bpos, struct bkey_i *);
426 bool bch2_cut_back(struct bpos, struct bkey *);
427 void bch2_key_resize(struct bkey *, unsigned);
428
429 int bch2_check_range_allocated(struct bch_fs *, struct bpos, u64);
430
431 #endif /* _BCACHEFS_EXTENTS_H */