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