]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/extents.h
08ad9647240616749830c1fae7a7f19812086523
[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                 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) {
283                         common_fields(crc->crc32),
284                 };
285
286                 *((__le32 *) &ret.csum.lo) = crc->crc32.csum;
287
288                 memcpy(&ret.csum.lo, &crc->crc32.csum,
289                        sizeof(crc->crc32.csum));
290
291                 return ret;
292         }
293         case BCH_EXTENT_CRC64: {
294                 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) {
295                         common_fields(crc->crc64),
296                         .nonce                  = crc->crc64.nonce,
297                         .csum.lo                = (__force __le64) crc->crc64.csum_lo,
298                 };
299
300                 *((__le16 *) &ret.csum.hi) = crc->crc64.csum_hi;
301
302                 return ret;
303         }
304         case BCH_EXTENT_CRC128: {
305                 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) {
306                         common_fields(crc->crc128),
307                         .nonce                  = crc->crc128.nonce,
308                         .csum                   = crc->crc128.csum,
309                 };
310
311                 return ret;
312         }
313         default:
314                 BUG();
315         }
316 #undef common_fields
317 }
318
319 /* Extent entry iteration: */
320
321 #define extent_entry_next(_entry)                                       \
322         ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry)))
323
324 #define extent_entry_last(_e)                                           \
325         vstruct_idx((_e).v, bkey_val_u64s((_e).k))
326
327 /* Iterate over all entries: */
328
329 #define extent_for_each_entry_from(_e, _entry, _start)                  \
330         for ((_entry) = _start;                                         \
331              (_entry) < extent_entry_last(_e);                          \
332              (_entry) = extent_entry_next(_entry))
333
334 #define extent_for_each_entry(_e, _entry)                               \
335         extent_for_each_entry_from(_e, _entry, (_e).v->start)
336
337 /* Iterate over crcs only: */
338
339 #define __extent_crc_next(_e, _p)                                       \
340 ({                                                                      \
341         typeof(&(_e).v->start[0]) _entry = _p;                          \
342                                                                         \
343         while ((_entry) < extent_entry_last(_e) &&                      \
344                !extent_entry_is_crc(_entry))                            \
345                 (_entry) = extent_entry_next(_entry);                   \
346                                                                         \
347         entry_to_crc(_entry < extent_entry_last(_e) ? _entry : NULL);   \
348 })
349
350 #define __extent_for_each_crc(_e, _crc)                                 \
351         for ((_crc) = __extent_crc_next(_e, (_e).v->start);             \
352              (_crc);                                                    \
353              (_crc) = __extent_crc_next(_e, extent_entry_next(to_entry(_crc))))
354
355 #define extent_crc_next(_e, _crc, _iter)                                \
356 ({                                                                      \
357         extent_for_each_entry_from(_e, _iter, _iter)                    \
358                 if (extent_entry_is_crc(_iter)) {                       \
359                         (_crc) = bch2_extent_crc_unpack((_e).k, entry_to_crc(_iter));\
360                         break;                                          \
361                 }                                                       \
362                                                                         \
363         (_iter) < extent_entry_last(_e);                                \
364 })
365
366 #define extent_for_each_crc(_e, _crc, _iter)                            \
367         for ((_crc) = bch2_extent_crc_unpack((_e).k, NULL),             \
368              (_iter) = (_e).v->start;                                   \
369              extent_crc_next(_e, _crc, _iter);                          \
370              (_iter) = extent_entry_next(_iter))
371
372 /* Iterate over pointers, with crcs: */
373
374 #define extent_ptr_crc_next(_e, _ptr, _crc)                             \
375 ({                                                                      \
376         __label__ out;                                                  \
377         typeof(&(_e).v->start[0]) _entry;                               \
378                                                                         \
379         extent_for_each_entry_from(_e, _entry, to_entry(_ptr))          \
380                 if (extent_entry_is_crc(_entry)) {                      \
381                         (_crc) = bch2_extent_crc_unpack((_e).k, entry_to_crc(_entry));\
382                 } else {                                                \
383                         _ptr = entry_to_ptr(_entry);                    \
384                         goto out;                                       \
385                 }                                                       \
386                                                                         \
387         _ptr = NULL;                                                    \
388 out:                                                                    \
389         _ptr;                                                           \
390 })
391
392 #define extent_for_each_ptr_crc(_e, _ptr, _crc)                         \
393         for ((_crc) = bch2_extent_crc_unpack((_e).k, NULL),             \
394              (_ptr) = &(_e).v->start->ptr;                              \
395              ((_ptr) = extent_ptr_crc_next(_e, _ptr, _crc));            \
396              (_ptr)++)
397
398 /* Iterate over pointers only, and from a given position: */
399
400 #define extent_ptr_next(_e, _ptr)                                       \
401 ({                                                                      \
402         struct bch_extent_crc_unpacked _crc;                            \
403                                                                         \
404         extent_ptr_crc_next(_e, _ptr, _crc);                            \
405 })
406
407 #define extent_for_each_ptr(_e, _ptr)                                   \
408         for ((_ptr) = &(_e).v->start->ptr;                              \
409              ((_ptr) = extent_ptr_next(_e, _ptr));                      \
410              (_ptr)++)
411
412 #define extent_ptr_prev(_e, _ptr)                                       \
413 ({                                                                      \
414         typeof(&(_e).v->start->ptr) _p;                                 \
415         typeof(&(_e).v->start->ptr) _prev = NULL;                       \
416                                                                         \
417         extent_for_each_ptr(_e, _p) {                                   \
418                 if (_p == (_ptr))                                       \
419                         break;                                          \
420                 _prev = _p;                                             \
421         }                                                               \
422                                                                         \
423         _prev;                                                          \
424 })
425
426 /*
427  * Use this when you'll be dropping pointers as you iterate. Quadratic,
428  * unfortunately:
429  */
430 #define extent_for_each_ptr_backwards(_e, _ptr)                         \
431         for ((_ptr) = extent_ptr_prev(_e, NULL);                        \
432              (_ptr);                                                    \
433              (_ptr) = extent_ptr_prev(_e, _ptr))
434
435 void bch2_extent_crc_append(struct bkey_i_extent *,
436                             struct bch_extent_crc_unpacked);
437
438 static inline void __extent_entry_push(struct bkey_i_extent *e)
439 {
440         union bch_extent_entry *entry = extent_entry_last(extent_i_to_s(e));
441
442         EBUG_ON(bkey_val_u64s(&e->k) + extent_entry_u64s(entry) >
443                 BKEY_EXTENT_VAL_U64s_MAX);
444
445         e->k.u64s += extent_entry_u64s(entry);
446 }
447
448 static inline void extent_ptr_append(struct bkey_i_extent *e,
449                                      struct bch_extent_ptr ptr)
450 {
451         ptr.type = 1 << BCH_EXTENT_ENTRY_ptr;
452         extent_entry_last(extent_i_to_s(e))->ptr = ptr;
453         __extent_entry_push(e);
454 }
455
456 static inline struct bch_devs_list bch2_extent_devs(struct bkey_s_c_extent e)
457 {
458         struct bch_devs_list ret = (struct bch_devs_list) { 0 };
459         const struct bch_extent_ptr *ptr;
460
461         extent_for_each_ptr(e, ptr)
462                 ret.devs[ret.nr++] = ptr->dev;
463
464         return ret;
465 }
466
467 static inline struct bch_devs_list bch2_extent_dirty_devs(struct bkey_s_c_extent e)
468 {
469         struct bch_devs_list ret = (struct bch_devs_list) { 0 };
470         const struct bch_extent_ptr *ptr;
471
472         extent_for_each_ptr(e, ptr)
473                 if (!ptr->cached)
474                         ret.devs[ret.nr++] = ptr->dev;
475
476         return ret;
477 }
478
479 static inline struct bch_devs_list bch2_extent_cached_devs(struct bkey_s_c_extent e)
480 {
481         struct bch_devs_list ret = (struct bch_devs_list) { 0 };
482         const struct bch_extent_ptr *ptr;
483
484         extent_for_each_ptr(e, ptr)
485                 if (ptr->cached)
486                         ret.devs[ret.nr++] = ptr->dev;
487
488         return ret;
489 }
490
491 static inline struct bch_devs_list bch2_bkey_devs(struct bkey_s_c k)
492 {
493         switch (k.k->type) {
494         case BCH_EXTENT:
495         case BCH_EXTENT_CACHED:
496                 return bch2_extent_devs(bkey_s_c_to_extent(k));
497         default:
498                 return (struct bch_devs_list) { .nr = 0 };
499         }
500 }
501
502 static inline struct bch_devs_list bch2_bkey_dirty_devs(struct bkey_s_c k)
503 {
504         switch (k.k->type) {
505         case BCH_EXTENT:
506         case BCH_EXTENT_CACHED:
507                 return bch2_extent_dirty_devs(bkey_s_c_to_extent(k));
508         default:
509                 return (struct bch_devs_list) { .nr = 0 };
510         }
511 }
512
513 static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k)
514 {
515         switch (k.k->type) {
516         case BCH_EXTENT:
517         case BCH_EXTENT_CACHED:
518                 return bch2_extent_cached_devs(bkey_s_c_to_extent(k));
519         default:
520                 return (struct bch_devs_list) { .nr = 0 };
521         }
522 }
523
524 bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent,
525                                  struct bch_extent_crc_unpacked);
526 bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked);
527 void bch2_extent_drop_redundant_crcs(struct bkey_s_extent);
528
529 void __bch2_extent_drop_ptr(struct bkey_s_extent, struct bch_extent_ptr *);
530 void bch2_extent_drop_ptr(struct bkey_s_extent, struct bch_extent_ptr *);
531
532 bool bch2_cut_front(struct bpos, struct bkey_i *);
533 bool bch2_cut_back(struct bpos, struct bkey *);
534 void bch2_key_resize(struct bkey *, unsigned);
535
536 int bch2_check_range_allocated(struct bch_fs *, struct bpos, u64);
537
538 #endif /* _BCACHEFS_EXTENTS_H */