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