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