blob: a2ce8a3be13ca418a001d8ff93d9091565aed800 [file] [log] [blame]
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -08001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _BCACHEFS_EXTENTS_H
3#define _BCACHEFS_EXTENTS_H
4
5#include "bcachefs.h"
6#include "bkey.h"
7#include "extents_types.h"
8
9struct bch_fs;
Kent Overstreet0dc17242019-03-13 22:44:04 -040010struct btree_trans;
Kent Overstreet8726dc92023-07-06 21:16:10 -040011enum bkey_invalid_flags;
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080012
Kent Overstreet26609b62018-11-01 15:10:01 -040013/* extent entries: */
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080014
Kent Overstreet99aaf572019-07-25 13:52:14 -040015#define extent_entry_last(_e) \
16 ((typeof(&(_e).v->start[0])) bkey_val_end(_e))
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080017
Kent Overstreet26609b62018-11-01 15:10:01 -040018#define entry_to_ptr(_entry) \
19({ \
20 EBUG_ON((_entry) && !extent_entry_is_ptr(_entry)); \
21 \
22 __builtin_choose_expr( \
23 type_is_exact(_entry, const union bch_extent_entry *), \
24 (const struct bch_extent_ptr *) (_entry), \
25 (struct bch_extent_ptr *) (_entry)); \
26})
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080027
Kent Overstreet26609b62018-11-01 15:10:01 -040028/* downcast, preserves const */
29#define to_entry(_entry) \
30({ \
31 BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) && \
32 !type_is(_entry, struct bch_extent_ptr *) && \
33 !type_is(_entry, struct bch_extent_stripe_ptr *)); \
34 \
35 __builtin_choose_expr( \
36 (type_is_exact(_entry, const union bch_extent_crc *) || \
37 type_is_exact(_entry, const struct bch_extent_ptr *) ||\
38 type_is_exact(_entry, const struct bch_extent_stripe_ptr *)),\
39 (const union bch_extent_entry *) (_entry), \
40 (union bch_extent_entry *) (_entry)); \
41})
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080042
Kent Overstreet4de77492019-11-16 16:25:58 -050043#define extent_entry_next(_entry) \
44 ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry)))
45
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080046static inline unsigned
47__extent_entry_type(const union bch_extent_entry *e)
48{
49 return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX;
50}
51
52static inline enum bch_extent_entry_type
53extent_entry_type(const union bch_extent_entry *e)
54{
55 int ret = __ffs(e->type);
56
57 EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX);
58
59 return ret;
60}
61
62static inline size_t extent_entry_bytes(const union bch_extent_entry *entry)
63{
64 switch (extent_entry_type(entry)) {
Kent Overstreetabce30b2018-09-30 18:39:20 -040065#define x(f, n) \
66 case BCH_EXTENT_ENTRY_##f: \
67 return sizeof(struct bch_extent_##f);
68 BCH_EXTENT_ENTRY_TYPES()
69#undef x
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -080070 default:
71 BUG();
72 }
73}
74
75static inline size_t extent_entry_u64s(const union bch_extent_entry *entry)
76{
77 return extent_entry_bytes(entry) / sizeof(u64);
78}
79
Kent Overstreet64784ad2023-02-22 17:57:59 -050080static inline void __extent_entry_insert(struct bkey_i *k,
81 union bch_extent_entry *dst,
82 union bch_extent_entry *new)
83{
84 union bch_extent_entry *end = bkey_val_end(bkey_i_to_s(k));
85
86 memmove_u64s_up_small((u64 *) dst + extent_entry_u64s(new),
87 dst, (u64 *) end - (u64 *) dst);
88 k->k.u64s += extent_entry_u64s(new);
89 memcpy_u64s_small(dst, new, extent_entry_u64s(new));
90}
91
Kent Overstreetfb3f57b2023-10-20 13:33:14 -040092static inline void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry)
93{
94 union bch_extent_entry *next = extent_entry_next(entry);
95
96 /* stripes have ptrs, but their layout doesn't work with this code */
97 BUG_ON(k.k->type == KEY_TYPE_stripe);
98
99 memmove_u64s_down(entry, next,
100 (u64 *) bkey_val_end(k) - (u64 *) next);
101 k.k->u64s -= (u64 *) next - (u64 *) entry;
102}
103
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800104static inline bool extent_entry_is_ptr(const union bch_extent_entry *e)
105{
Kent Overstreetb9a7d8a2021-10-13 13:12:26 -0400106 return extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr;
107}
108
109static inline bool extent_entry_is_stripe_ptr(const union bch_extent_entry *e)
110{
111 return extent_entry_type(e) == BCH_EXTENT_ENTRY_stripe_ptr;
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800112}
113
114static inline bool extent_entry_is_crc(const union bch_extent_entry *e)
115{
Kent Overstreet17422372018-09-27 21:08:39 -0400116 switch (extent_entry_type(e)) {
117 case BCH_EXTENT_ENTRY_crc32:
118 case BCH_EXTENT_ENTRY_crc64:
119 case BCH_EXTENT_ENTRY_crc128:
120 return true;
121 default:
122 return false;
123 }
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800124}
125
126union bch_extent_crc {
127 u8 type;
128 struct bch_extent_crc32 crc32;
129 struct bch_extent_crc64 crc64;
130 struct bch_extent_crc128 crc128;
131};
132
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800133#define __entry_to_crc(_entry) \
134 __builtin_choose_expr( \
135 type_is_exact(_entry, const union bch_extent_entry *), \
136 (const union bch_extent_crc *) (_entry), \
137 (union bch_extent_crc *) (_entry))
138
139#define entry_to_crc(_entry) \
140({ \
141 EBUG_ON((_entry) && !extent_entry_is_crc(_entry)); \
142 \
143 __entry_to_crc(_entry); \
144})
145
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800146static inline struct bch_extent_crc_unpacked
147bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc)
148{
149#define common_fields(_crc) \
150 .csum_type = _crc.csum_type, \
151 .compression_type = _crc.compression_type, \
152 .compressed_size = _crc._compressed_size + 1, \
153 .uncompressed_size = _crc._uncompressed_size + 1, \
154 .offset = _crc.offset, \
155 .live_size = k->size
156
Kent Overstreet642d66d2018-10-02 16:40:12 -0400157 if (!crc)
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800158 return (struct bch_extent_crc_unpacked) {
159 .compressed_size = k->size,
160 .uncompressed_size = k->size,
161 .live_size = k->size,
162 };
Kent Overstreet642d66d2018-10-02 16:40:12 -0400163
164 switch (extent_entry_type(to_entry(crc))) {
165 case BCH_EXTENT_ENTRY_crc32: {
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800166 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) {
167 common_fields(crc->crc32),
168 };
169
Kent Overstreet73bd7742023-07-06 22:47:42 -0400170 *((__le32 *) &ret.csum.lo) = (__le32 __force) crc->crc32.csum;
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800171 return ret;
172 }
Kent Overstreet642d66d2018-10-02 16:40:12 -0400173 case BCH_EXTENT_ENTRY_crc64: {
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800174 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) {
175 common_fields(crc->crc64),
176 .nonce = crc->crc64.nonce,
177 .csum.lo = (__force __le64) crc->crc64.csum_lo,
178 };
179
Kent Overstreet73bd7742023-07-06 22:47:42 -0400180 *((__le16 *) &ret.csum.hi) = (__le16 __force) crc->crc64.csum_hi;
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800181
182 return ret;
183 }
Kent Overstreet642d66d2018-10-02 16:40:12 -0400184 case BCH_EXTENT_ENTRY_crc128: {
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800185 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) {
186 common_fields(crc->crc128),
187 .nonce = crc->crc128.nonce,
188 .csum = crc->crc128.csum,
189 };
190
191 return ret;
192 }
193 default:
194 BUG();
195 }
196#undef common_fields
197}
198
Kent Overstreetab05de42018-02-23 16:26:10 -0500199static inline bool crc_is_compressed(struct bch_extent_crc_unpacked crc)
200{
201 return (crc.compression_type != BCH_COMPRESSION_TYPE_none &&
202 crc.compression_type != BCH_COMPRESSION_TYPE_incompressible);
203}
204
Kent Overstreet9db2f862023-10-22 11:33:02 -0400205static inline bool crc_is_encoded(struct bch_extent_crc_unpacked crc)
206{
207 return crc.csum_type != BCH_CSUM_none || crc_is_compressed(crc);
208}
209
Kent Overstreet26609b62018-11-01 15:10:01 -0400210/* bkey_ptrs: generically over any key type that has ptrs */
211
212struct bkey_ptrs_c {
213 const union bch_extent_entry *start;
214 const union bch_extent_entry *end;
215};
216
217struct bkey_ptrs {
218 union bch_extent_entry *start;
219 union bch_extent_entry *end;
220};
221
Kent Overstreet4de77492019-11-16 16:25:58 -0500222static inline struct bkey_ptrs_c bch2_bkey_ptrs_c(struct bkey_s_c k)
223{
224 switch (k.k->type) {
225 case KEY_TYPE_btree_ptr: {
226 struct bkey_s_c_btree_ptr e = bkey_s_c_to_btree_ptr(k);
Kent Overstreeta1019572022-10-22 15:59:53 -0400227
Kent Overstreet4de77492019-11-16 16:25:58 -0500228 return (struct bkey_ptrs_c) {
229 to_entry(&e.v->start[0]),
230 to_entry(extent_entry_last(e))
231 };
232 }
233 case KEY_TYPE_extent: {
234 struct bkey_s_c_extent e = bkey_s_c_to_extent(k);
Kent Overstreeta1019572022-10-22 15:59:53 -0400235
Kent Overstreet4de77492019-11-16 16:25:58 -0500236 return (struct bkey_ptrs_c) {
237 e.v->start,
238 extent_entry_last(e)
239 };
240 }
241 case KEY_TYPE_stripe: {
242 struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
Kent Overstreeta1019572022-10-22 15:59:53 -0400243
Kent Overstreet4de77492019-11-16 16:25:58 -0500244 return (struct bkey_ptrs_c) {
245 to_entry(&s.v->ptrs[0]),
246 to_entry(&s.v->ptrs[s.v->nr_blocks]),
247 };
248 }
249 case KEY_TYPE_reflink_v: {
250 struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800251
Kent Overstreet4de77492019-11-16 16:25:58 -0500252 return (struct bkey_ptrs_c) {
253 r.v->start,
254 bkey_val_end(r),
255 };
256 }
Kent Overstreet548b3d22020-02-07 13:38:02 -0500257 case KEY_TYPE_btree_ptr_v2: {
258 struct bkey_s_c_btree_ptr_v2 e = bkey_s_c_to_btree_ptr_v2(k);
Kent Overstreeta1019572022-10-22 15:59:53 -0400259
Kent Overstreet548b3d22020-02-07 13:38:02 -0500260 return (struct bkey_ptrs_c) {
261 to_entry(&e.v->start[0]),
262 to_entry(extent_entry_last(e))
263 };
264 }
Kent Overstreet4de77492019-11-16 16:25:58 -0500265 default:
266 return (struct bkey_ptrs_c) { NULL, NULL };
267 }
268}
269
270static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k)
271{
272 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k.s_c);
273
274 return (struct bkey_ptrs) {
275 (void *) p.start,
276 (void *) p.end
277 };
278}
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800279
Kent Overstreet26609b62018-11-01 15:10:01 -0400280#define __bkey_extent_entry_for_each_from(_start, _end, _entry) \
281 for ((_entry) = (_start); \
282 (_entry) < (_end); \
283 (_entry) = extent_entry_next(_entry))
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800284
Kent Overstreet26609b62018-11-01 15:10:01 -0400285#define __bkey_ptr_next(_ptr, _end) \
286({ \
287 typeof(_end) _entry; \
288 \
289 __bkey_extent_entry_for_each_from(to_entry(_ptr), _end, _entry) \
290 if (extent_entry_is_ptr(_entry)) \
291 break; \
292 \
293 _entry < (_end) ? entry_to_ptr(_entry) : NULL; \
294})
295
296#define bkey_extent_entry_for_each_from(_p, _entry, _start) \
297 __bkey_extent_entry_for_each_from(_start, (_p).end, _entry)
298
299#define bkey_extent_entry_for_each(_p, _entry) \
300 bkey_extent_entry_for_each_from(_p, _entry, _p.start)
301
302#define __bkey_for_each_ptr(_start, _end, _ptr) \
303 for ((_ptr) = (_start); \
304 ((_ptr) = __bkey_ptr_next(_ptr, _end)); \
305 (_ptr)++)
306
307#define bkey_ptr_next(_p, _ptr) \
308 __bkey_ptr_next(_ptr, (_p).end)
309
310#define bkey_for_each_ptr(_p, _ptr) \
311 __bkey_for_each_ptr(&(_p).start->ptr, (_p).end, _ptr)
312
313#define __bkey_ptr_next_decode(_k, _end, _ptr, _entry) \
314({ \
315 __label__ out; \
316 \
317 (_ptr).idx = 0; \
Kent Overstreet37954a22019-10-08 18:45:29 -0400318 (_ptr).has_ec = false; \
Kent Overstreet26609b62018-11-01 15:10:01 -0400319 \
320 __bkey_extent_entry_for_each_from(_entry, _end, _entry) \
321 switch (extent_entry_type(_entry)) { \
322 case BCH_EXTENT_ENTRY_ptr: \
323 (_ptr).ptr = _entry->ptr; \
324 goto out; \
325 case BCH_EXTENT_ENTRY_crc32: \
326 case BCH_EXTENT_ENTRY_crc64: \
327 case BCH_EXTENT_ENTRY_crc128: \
328 (_ptr).crc = bch2_extent_crc_unpack(_k, \
329 entry_to_crc(_entry)); \
330 break; \
331 case BCH_EXTENT_ENTRY_stripe_ptr: \
Kent Overstreet37954a22019-10-08 18:45:29 -0400332 (_ptr).ec = _entry->stripe_ptr; \
333 (_ptr).has_ec = true; \
Kent Overstreet26609b62018-11-01 15:10:01 -0400334 break; \
Kent Overstreet27668762023-06-27 19:02:17 -0400335 default: \
336 /* nothing */ \
337 break; \
Kent Overstreet26609b62018-11-01 15:10:01 -0400338 } \
339out: \
340 _entry < (_end); \
341})
342
343#define __bkey_for_each_ptr_decode(_k, _start, _end, _ptr, _entry) \
344 for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL), \
345 (_entry) = _start; \
346 __bkey_ptr_next_decode(_k, _end, _ptr, _entry); \
347 (_entry) = extent_entry_next(_entry))
348
349#define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry) \
350 __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end, \
351 _ptr, _entry)
352
Kent Overstreet99aaf572019-07-25 13:52:14 -0400353#define bkey_crc_next(_k, _start, _end, _crc, _iter) \
354({ \
355 __bkey_extent_entry_for_each_from(_iter, _end, _iter) \
356 if (extent_entry_is_crc(_iter)) { \
357 (_crc) = bch2_extent_crc_unpack(_k, \
358 entry_to_crc(_iter)); \
359 break; \
360 } \
361 \
362 (_iter) < (_end); \
363})
364
365#define __bkey_for_each_crc(_k, _start, _end, _crc, _iter) \
366 for ((_crc) = bch2_extent_crc_unpack(_k, NULL), \
367 (_iter) = (_start); \
368 bkey_crc_next(_k, _start, _end, _crc, _iter); \
369 (_iter) = extent_entry_next(_iter))
370
371#define bkey_for_each_crc(_k, _p, _crc, _iter) \
372 __bkey_for_each_crc(_k, (_p).start, (_p).end, _crc, _iter)
373
Kent Overstreet4de77492019-11-16 16:25:58 -0500374/* Iterate over pointers in KEY_TYPE_extent: */
375
376#define extent_for_each_entry_from(_e, _entry, _start) \
377 __bkey_extent_entry_for_each_from(_start, \
Kent Overstreeta1019572022-10-22 15:59:53 -0400378 extent_entry_last(_e), _entry)
Kent Overstreet4de77492019-11-16 16:25:58 -0500379
380#define extent_for_each_entry(_e, _entry) \
381 extent_for_each_entry_from(_e, _entry, (_e).v->start)
382
383#define extent_ptr_next(_e, _ptr) \
384 __bkey_ptr_next(_ptr, extent_entry_last(_e))
385
386#define extent_for_each_ptr(_e, _ptr) \
387 __bkey_for_each_ptr(&(_e).v->start->ptr, extent_entry_last(_e), _ptr)
388
389#define extent_for_each_ptr_decode(_e, _ptr, _entry) \
390 __bkey_for_each_ptr_decode((_e).k, (_e).v->start, \
391 extent_entry_last(_e), _ptr, _entry)
392
Kent Overstreet26609b62018-11-01 15:10:01 -0400393/* utility code common to all keys with pointers: */
394
Kent Overstreet4de77492019-11-16 16:25:58 -0500395void bch2_mark_io_failure(struct bch_io_failures *,
396 struct extent_ptr_decoded *);
397int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c,
398 struct bch_io_failures *,
399 struct extent_ptr_decoded *);
Kent Overstreet76426092019-08-16 09:59:56 -0400400
Kent Overstreet4de77492019-11-16 16:25:58 -0500401/* KEY_TYPE_btree_ptr: */
402
Kent Overstreetb65db752023-10-24 20:44:36 -0400403int bch2_btree_ptr_invalid(struct bch_fs *, struct bkey_s_c,
Kent Overstreet8726dc92023-07-06 21:16:10 -0400404 enum bkey_invalid_flags, struct printbuf *);
Kent Overstreet4de77492019-11-16 16:25:58 -0500405void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *,
406 struct bkey_s_c);
Kent Overstreet59a38a32020-03-31 16:25:30 -0400407
Kent Overstreetb65db752023-10-24 20:44:36 -0400408int bch2_btree_ptr_v2_invalid(struct bch_fs *, struct bkey_s_c,
Kent Overstreet8726dc92023-07-06 21:16:10 -0400409 enum bkey_invalid_flags, struct printbuf *);
Kent Overstreetf0ac7df2022-04-03 17:50:01 -0400410void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
Kent Overstreet39fb2982020-01-07 13:29:32 -0500411void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned,
412 int, struct bkey_s);
Kent Overstreet4de77492019-11-16 16:25:58 -0500413
Kent Overstreeta1019572022-10-22 15:59:53 -0400414#define bch2_bkey_ops_btree_ptr ((struct bkey_ops) { \
Kent Overstreet4de77492019-11-16 16:25:58 -0500415 .key_invalid = bch2_btree_ptr_invalid, \
Kent Overstreet4de77492019-11-16 16:25:58 -0500416 .val_to_text = bch2_btree_ptr_to_text, \
417 .swab = bch2_ptr_swab, \
Kent Overstreet880e2272022-03-13 00:26:52 -0500418 .trans_trigger = bch2_trans_mark_extent, \
419 .atomic_trigger = bch2_mark_extent, \
Kent Overstreeta1019572022-10-22 15:59:53 -0400420})
Kent Overstreet4de77492019-11-16 16:25:58 -0500421
Kent Overstreeta1019572022-10-22 15:59:53 -0400422#define bch2_bkey_ops_btree_ptr_v2 ((struct bkey_ops) { \
Kent Overstreetfad7cfe2021-03-22 17:23:30 -0400423 .key_invalid = bch2_btree_ptr_v2_invalid, \
Kent Overstreet59a38a32020-03-31 16:25:30 -0400424 .val_to_text = bch2_btree_ptr_v2_to_text, \
Kent Overstreet548b3d22020-02-07 13:38:02 -0500425 .swab = bch2_ptr_swab, \
Kent Overstreet39fb2982020-01-07 13:29:32 -0500426 .compat = bch2_btree_ptr_v2_compat, \
Kent Overstreet880e2272022-03-13 00:26:52 -0500427 .trans_trigger = bch2_trans_mark_extent, \
428 .atomic_trigger = bch2_mark_extent, \
Kent Overstreet174f9302023-04-29 13:24:18 -0400429 .min_val_size = 40, \
Kent Overstreeta1019572022-10-22 15:59:53 -0400430})
Kent Overstreet548b3d22020-02-07 13:38:02 -0500431
Kent Overstreet4de77492019-11-16 16:25:58 -0500432/* KEY_TYPE_extent: */
433
Kent Overstreet59ba21d2021-04-28 23:49:30 -0400434bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
Kent Overstreet4de77492019-11-16 16:25:58 -0500435
Kent Overstreeta1019572022-10-22 15:59:53 -0400436#define bch2_bkey_ops_extent ((struct bkey_ops) { \
Kent Overstreetf0ac7df2022-04-03 17:50:01 -0400437 .key_invalid = bch2_bkey_ptrs_invalid, \
438 .val_to_text = bch2_bkey_ptrs_to_text, \
Kent Overstreet4de77492019-11-16 16:25:58 -0500439 .swab = bch2_ptr_swab, \
440 .key_normalize = bch2_extent_normalize, \
441 .key_merge = bch2_extent_merge, \
Kent Overstreet880e2272022-03-13 00:26:52 -0500442 .trans_trigger = bch2_trans_mark_extent, \
443 .atomic_trigger = bch2_mark_extent, \
Kent Overstreeta1019572022-10-22 15:59:53 -0400444})
Kent Overstreet4de77492019-11-16 16:25:58 -0500445
446/* KEY_TYPE_reservation: */
447
Kent Overstreetb65db752023-10-24 20:44:36 -0400448int bch2_reservation_invalid(struct bch_fs *, struct bkey_s_c,
Kent Overstreet8726dc92023-07-06 21:16:10 -0400449 enum bkey_invalid_flags, struct printbuf *);
Kent Overstreet4de77492019-11-16 16:25:58 -0500450void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
Kent Overstreet59ba21d2021-04-28 23:49:30 -0400451bool bch2_reservation_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
Kent Overstreet4de77492019-11-16 16:25:58 -0500452
Kent Overstreeta1019572022-10-22 15:59:53 -0400453#define bch2_bkey_ops_reservation ((struct bkey_ops) { \
Kent Overstreet4de77492019-11-16 16:25:58 -0500454 .key_invalid = bch2_reservation_invalid, \
455 .val_to_text = bch2_reservation_to_text, \
456 .key_merge = bch2_reservation_merge, \
Kent Overstreet880e2272022-03-13 00:26:52 -0500457 .trans_trigger = bch2_trans_mark_reservation, \
458 .atomic_trigger = bch2_mark_reservation, \
Kent Overstreet174f9302023-04-29 13:24:18 -0400459 .min_val_size = 8, \
Kent Overstreeta1019572022-10-22 15:59:53 -0400460})
Kent Overstreet4de77492019-11-16 16:25:58 -0500461
462/* Extent checksum entries: */
463
464bool bch2_can_narrow_extent_crcs(struct bkey_s_c,
465 struct bch_extent_crc_unpacked);
466bool bch2_bkey_narrow_crcs(struct bkey_i *, struct bch_extent_crc_unpacked);
467void bch2_extent_crc_append(struct bkey_i *,
468 struct bch_extent_crc_unpacked);
469
470/* Generic code for keys with pointers: */
471
Kent Overstreet297d8932021-06-10 21:44:27 -0400472static inline bool bkey_is_btree_ptr(const struct bkey *k)
473{
474 switch (k->type) {
475 case KEY_TYPE_btree_ptr:
476 case KEY_TYPE_btree_ptr_v2:
477 return true;
478 default:
479 return false;
480 }
481}
482
Kent Overstreet4de77492019-11-16 16:25:58 -0500483static inline bool bkey_extent_is_direct_data(const struct bkey *k)
484{
485 switch (k->type) {
486 case KEY_TYPE_btree_ptr:
Kent Overstreet548b3d22020-02-07 13:38:02 -0500487 case KEY_TYPE_btree_ptr_v2:
Kent Overstreet4de77492019-11-16 16:25:58 -0500488 case KEY_TYPE_extent:
489 case KEY_TYPE_reflink_v:
490 return true;
Kent Overstreet26609b62018-11-01 15:10:01 -0400491 default:
Kent Overstreet4de77492019-11-16 16:25:58 -0500492 return false;
Kent Overstreet26609b62018-11-01 15:10:01 -0400493 }
494}
495
Kent Overstreet801a3de2020-10-24 19:51:34 -0400496static inline bool bkey_extent_is_inline_data(const struct bkey *k)
497{
498 return k->type == KEY_TYPE_inline_data ||
499 k->type == KEY_TYPE_indirect_inline_data;
500}
501
502static inline unsigned bkey_inline_data_offset(const struct bkey *k)
503{
504 switch (k->type) {
505 case KEY_TYPE_inline_data:
506 return sizeof(struct bch_inline_data);
507 case KEY_TYPE_indirect_inline_data:
508 return sizeof(struct bch_indirect_inline_data);
509 default:
510 BUG();
511 }
512}
513
514static inline unsigned bkey_inline_data_bytes(const struct bkey *k)
515{
516 return bkey_val_bytes(k) - bkey_inline_data_offset(k);
517}
518
519#define bkey_inline_data_p(_k) (((void *) (_k).v) + bkey_inline_data_offset((_k).k))
520
Kent Overstreet4de77492019-11-16 16:25:58 -0500521static inline bool bkey_extent_is_data(const struct bkey *k)
Kent Overstreet26609b62018-11-01 15:10:01 -0400522{
Kent Overstreet801a3de2020-10-24 19:51:34 -0400523 return bkey_extent_is_direct_data(k) ||
524 bkey_extent_is_inline_data(k) ||
Kent Overstreet4de77492019-11-16 16:25:58 -0500525 k->type == KEY_TYPE_reflink_p;
526}
Kent Overstreet26609b62018-11-01 15:10:01 -0400527
Kent Overstreet4de77492019-11-16 16:25:58 -0500528/*
529 * Should extent be counted under inode->i_sectors?
530 */
531static inline bool bkey_extent_is_allocation(const struct bkey *k)
532{
533 switch (k->type) {
534 case KEY_TYPE_extent:
535 case KEY_TYPE_reservation:
536 case KEY_TYPE_reflink_p:
537 case KEY_TYPE_reflink_v:
538 case KEY_TYPE_inline_data:
Kent Overstreet801a3de2020-10-24 19:51:34 -0400539 case KEY_TYPE_indirect_inline_data:
Kent Overstreetbe47e0b2023-09-29 15:49:16 -0400540 case KEY_TYPE_error:
Kent Overstreet4de77492019-11-16 16:25:58 -0500541 return true;
542 default:
543 return false;
544 }
Kent Overstreet26609b62018-11-01 15:10:01 -0400545}
546
Kent Overstreet79203112022-11-13 18:59:01 -0500547static inline bool bkey_extent_is_unwritten(struct bkey_s_c k)
548{
549 struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
550 const struct bch_extent_ptr *ptr;
551
552 bkey_for_each_ptr(ptrs, ptr)
553 if (ptr->unwritten)
554 return true;
555 return false;
556}
557
558static inline bool bkey_extent_is_reservation(struct bkey_s_c k)
559{
560 return k.k->type == KEY_TYPE_reservation ||
561 bkey_extent_is_unwritten(k);
562}
563
Kent Overstreet26609b62018-11-01 15:10:01 -0400564static inline struct bch_devs_list bch2_bkey_devs(struct bkey_s_c k)
565{
566 struct bch_devs_list ret = (struct bch_devs_list) { 0 };
567 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k);
568 const struct bch_extent_ptr *ptr;
569
570 bkey_for_each_ptr(p, ptr)
571 ret.devs[ret.nr++] = ptr->dev;
572
573 return ret;
574}
575
576static inline struct bch_devs_list bch2_bkey_dirty_devs(struct bkey_s_c k)
577{
578 struct bch_devs_list ret = (struct bch_devs_list) { 0 };
579 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k);
580 const struct bch_extent_ptr *ptr;
581
582 bkey_for_each_ptr(p, ptr)
583 if (!ptr->cached)
584 ret.devs[ret.nr++] = ptr->dev;
585
586 return ret;
587}
588
589static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k)
590{
591 struct bch_devs_list ret = (struct bch_devs_list) { 0 };
592 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k);
593 const struct bch_extent_ptr *ptr;
594
595 bkey_for_each_ptr(p, ptr)
596 if (ptr->cached)
597 ret.devs[ret.nr++] = ptr->dev;
598
599 return ret;
600}
601
Kent Overstreete1036ce2021-05-14 21:28:37 -0400602static inline unsigned bch2_bkey_ptr_data_type(struct bkey_s_c k, const struct bch_extent_ptr *ptr)
603{
604 switch (k.k->type) {
605 case KEY_TYPE_btree_ptr:
606 case KEY_TYPE_btree_ptr_v2:
607 return BCH_DATA_btree;
608 case KEY_TYPE_extent:
609 case KEY_TYPE_reflink_v:
610 return BCH_DATA_user;
611 case KEY_TYPE_stripe: {
612 struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
613
614 BUG_ON(ptr < s.v->ptrs ||
615 ptr >= s.v->ptrs + s.v->nr_blocks);
616
617 return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant
618 ? BCH_DATA_parity
619 : BCH_DATA_user;
620 }
621 default:
622 BUG();
623 }
624}
625
Kent Overstreet26609b62018-11-01 15:10:01 -0400626unsigned bch2_bkey_nr_ptrs(struct bkey_s_c);
Kent Overstreet4de77492019-11-16 16:25:58 -0500627unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c);
628unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c);
Kent Overstreetab05de42018-02-23 16:26:10 -0500629bool bch2_bkey_is_incompressible(struct bkey_s_c);
Kent Overstreet4de77492019-11-16 16:25:58 -0500630unsigned bch2_bkey_sectors_compressed(struct bkey_s_c);
Kent Overstreet35a067b2020-12-14 21:59:33 -0500631
632unsigned bch2_bkey_replicas(struct bch_fs *, struct bkey_s_c);
Kent Overstreet91ecd412023-06-13 15:12:04 -0400633unsigned bch2_extent_ptr_desired_durability(struct bch_fs *, struct extent_ptr_decoded *);
Kent Overstreeta8b3a672022-11-02 17:12:00 -0400634unsigned bch2_extent_ptr_durability(struct bch_fs *, struct extent_ptr_decoded *);
Kent Overstreet26609b62018-11-01 15:10:01 -0400635unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c);
636
Kent Overstreet393a1f62022-11-24 18:03:55 -0500637void bch2_bkey_drop_device(struct bkey_s, unsigned);
638void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned);
Kent Overstreet702ffea2023-03-10 16:28:37 -0500639
640const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned);
641
642static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsigned dev)
643{
644 return (void *) bch2_bkey_has_device_c(k.s_c, dev);
645}
646
Kent Overstreet393a1f62022-11-24 18:03:55 -0500647bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned);
648
Kent Overstreet05079622021-02-17 13:37:22 -0500649void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *);
Kent Overstreet393a1f62022-11-24 18:03:55 -0500650
651static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr)
652{
Kees Cook7413ab72023-10-18 16:07:32 -0700653 struct bch_extent_ptr *dest;
654
Kent Overstreet702ffea2023-03-10 16:28:37 -0500655 EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev));
Kent Overstreet393a1f62022-11-24 18:03:55 -0500656
657 switch (k->k.type) {
658 case KEY_TYPE_btree_ptr:
659 case KEY_TYPE_btree_ptr_v2:
660 case KEY_TYPE_extent:
661 EBUG_ON(bkey_val_u64s(&k->k) >= BKEY_EXTENT_VAL_U64s_MAX);
662
663 ptr.type = 1 << BCH_EXTENT_ENTRY_ptr;
Kees Cook7413ab72023-10-18 16:07:32 -0700664 dest = (struct bch_extent_ptr *)((void *) &k->v + bkey_val_bytes(&k->k));
665 *dest = ptr;
Kent Overstreetac2ccdd2023-03-04 23:05:55 -0500666 k->k.u64s++;
Kent Overstreet393a1f62022-11-24 18:03:55 -0500667 break;
668 default:
669 BUG();
670 }
671}
672
Kent Overstreet99aaf572019-07-25 13:52:14 -0400673void bch2_extent_ptr_decoded_append(struct bkey_i *,
Kent Overstreet71c9e0b2018-09-27 21:08:39 -0400674 struct extent_ptr_decoded *);
Kent Overstreet702ffea2023-03-10 16:28:37 -0500675union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s,
676 struct bch_extent_ptr *);
Kent Overstreet26609b62018-11-01 15:10:01 -0400677union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s,
678 struct bch_extent_ptr *);
Kent Overstreeta2753582018-09-30 18:28:23 -0400679
Kent Overstreet26609b62018-11-01 15:10:01 -0400680#define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \
Kent Overstreeta2753582018-09-30 18:28:23 -0400681do { \
Kent Overstreet26609b62018-11-01 15:10:01 -0400682 struct bkey_ptrs _ptrs = bch2_bkey_ptrs(_k); \
Kent Overstreeta2753582018-09-30 18:28:23 -0400683 \
Kent Overstreet26609b62018-11-01 15:10:01 -0400684 _ptr = &_ptrs.start->ptr; \
685 \
686 while ((_ptr = bkey_ptr_next(_ptrs, _ptr))) { \
Kent Overstreeta2753582018-09-30 18:28:23 -0400687 if (_cond) { \
Kent Overstreet26609b62018-11-01 15:10:01 -0400688 _ptr = (void *) bch2_bkey_drop_ptr(_k, _ptr); \
689 _ptrs = bch2_bkey_ptrs(_k); \
Kent Overstreeta2753582018-09-30 18:28:23 -0400690 continue; \
691 } \
692 \
693 (_ptr)++; \
694 } \
695} while (0)
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800696
Kent Overstreet4de77492019-11-16 16:25:58 -0500697bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c,
698 struct bch_extent_ptr, u64);
Kent Overstreet7f5c5d22022-06-13 19:17:45 -0400699bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c);
Kent Overstreet702ffea2023-03-10 16:28:37 -0500700struct bch_extent_ptr *
701bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s);
Kent Overstreet4de77492019-11-16 16:25:58 -0500702
Kent Overstreetc9163bb2023-02-21 19:22:44 -0500703void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *);
704
Kent Overstreet4de77492019-11-16 16:25:58 -0500705bool bch2_extent_normalize(struct bch_fs *, struct bkey_s);
706void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *,
707 struct bkey_s_c);
Kent Overstreetb65db752023-10-24 20:44:36 -0400708int bch2_bkey_ptrs_invalid(struct bch_fs *, struct bkey_s_c,
Kent Overstreet8726dc92023-07-06 21:16:10 -0400709 enum bkey_invalid_flags, struct printbuf *);
Kent Overstreet4de77492019-11-16 16:25:58 -0500710
Kent Overstreet1f49daf2020-02-06 20:15:15 -0500711void bch2_ptr_swab(struct bkey_s);
Kent Overstreet4de77492019-11-16 16:25:58 -0500712
Kent Overstreetfb3f57b2023-10-20 13:33:14 -0400713const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c);
714unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c,
715 unsigned, unsigned);
716bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c);
717
718int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *,
719 unsigned, unsigned);
720
Kent Overstreet4de77492019-11-16 16:25:58 -0500721/* Generic extent code: */
722
Kent Overstreet4cf91b02021-03-04 16:20:16 -0500723enum bch_extent_overlap {
724 BCH_EXTENT_OVERLAP_ALL = 0,
725 BCH_EXTENT_OVERLAP_BACK = 1,
726 BCH_EXTENT_OVERLAP_FRONT = 2,
727 BCH_EXTENT_OVERLAP_MIDDLE = 3,
728};
729
730/* Returns how k overlaps with m */
731static inline enum bch_extent_overlap bch2_extent_overlap(const struct bkey *k,
732 const struct bkey *m)
733{
Kent Overstreete88a75e2022-11-24 03:12:22 -0500734 int cmp1 = bkey_lt(k->p, m->p);
735 int cmp2 = bkey_gt(bkey_start_pos(k), bkey_start_pos(m));
Kent Overstreet4cf91b02021-03-04 16:20:16 -0500736
737 return (cmp1 << 1) + cmp2;
738}
739
Kent Overstreet085ab692019-11-09 19:02:48 -0500740int bch2_cut_front_s(struct bpos, struct bkey_s);
741int bch2_cut_back_s(struct bpos, struct bkey_s);
Kent Overstreet5b8a9222018-11-27 18:30:56 -0500742
Kent Overstreetb1c93582019-07-18 17:21:21 -0400743static inline void bch2_cut_front(struct bpos where, struct bkey_i *k)
Kent Overstreet5b8a9222018-11-27 18:30:56 -0500744{
Kent Overstreet085ab692019-11-09 19:02:48 -0500745 bch2_cut_front_s(where, bkey_i_to_s(k));
Kent Overstreet5b8a9222018-11-27 18:30:56 -0500746}
747
Kent Overstreet085ab692019-11-09 19:02:48 -0500748static inline void bch2_cut_back(struct bpos where, struct bkey_i *k)
749{
750 bch2_cut_back_s(where, bkey_i_to_s(k));
751}
Kent Overstreet3fb5ebc2019-08-22 16:07:37 -0400752
753/**
754 * bch_key_resize - adjust size of @k
755 *
756 * bkey_start_offset(k) will be preserved, modifies where the extent ends
757 */
758static inline void bch2_key_resize(struct bkey *k, unsigned new_size)
759{
760 k->p.offset -= k->size;
761 k->p.offset += new_size;
762 k->size = new_size;
763}
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800764
Kent Overstreet1c6fdbd2017-03-16 22:18:50 -0800765#endif /* _BCACHEFS_EXTENTS_H */