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