Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 1 | /* 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 | |
| 9 | struct bch_fs; |
Kent Overstreet | 0dc1724 | 2019-03-13 22:44:04 -0400 | [diff] [blame] | 10 | struct btree_trans; |
Kent Overstreet | 8726dc9 | 2023-07-06 21:16:10 -0400 | [diff] [blame] | 11 | enum bkey_invalid_flags; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 12 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 13 | /* extent entries: */ |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 14 | |
Kent Overstreet | 99aaf57 | 2019-07-25 13:52:14 -0400 | [diff] [blame] | 15 | #define extent_entry_last(_e) \ |
| 16 | ((typeof(&(_e).v->start[0])) bkey_val_end(_e)) |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 17 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 18 | #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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 27 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 28 | /* 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 42 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 43 | #define extent_entry_next(_entry) \ |
| 44 | ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry))) |
| 45 | |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 46 | static 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 | |
| 52 | static inline enum bch_extent_entry_type |
| 53 | extent_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 | |
| 62 | static inline size_t extent_entry_bytes(const union bch_extent_entry *entry) |
| 63 | { |
| 64 | switch (extent_entry_type(entry)) { |
Kent Overstreet | abce30b | 2018-09-30 18:39:20 -0400 | [diff] [blame] | 65 | #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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 70 | default: |
| 71 | BUG(); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | static inline size_t extent_entry_u64s(const union bch_extent_entry *entry) |
| 76 | { |
| 77 | return extent_entry_bytes(entry) / sizeof(u64); |
| 78 | } |
| 79 | |
Kent Overstreet | 64784ad | 2023-02-22 17:57:59 -0500 | [diff] [blame] | 80 | static 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 Overstreet | fb3f57b | 2023-10-20 13:33:14 -0400 | [diff] [blame] | 92 | static 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 104 | static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) |
| 105 | { |
Kent Overstreet | b9a7d8a | 2021-10-13 13:12:26 -0400 | [diff] [blame] | 106 | return extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr; |
| 107 | } |
| 108 | |
| 109 | static 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | static inline bool extent_entry_is_crc(const union bch_extent_entry *e) |
| 115 | { |
Kent Overstreet | 1742237 | 2018-09-27 21:08:39 -0400 | [diff] [blame] | 116 | 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | union 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 133 | #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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 146 | static inline struct bch_extent_crc_unpacked |
| 147 | bch2_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 Overstreet | 642d66d | 2018-10-02 16:40:12 -0400 | [diff] [blame] | 157 | if (!crc) |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 158 | return (struct bch_extent_crc_unpacked) { |
| 159 | .compressed_size = k->size, |
| 160 | .uncompressed_size = k->size, |
| 161 | .live_size = k->size, |
| 162 | }; |
Kent Overstreet | 642d66d | 2018-10-02 16:40:12 -0400 | [diff] [blame] | 163 | |
| 164 | switch (extent_entry_type(to_entry(crc))) { |
| 165 | case BCH_EXTENT_ENTRY_crc32: { |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 166 | struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { |
| 167 | common_fields(crc->crc32), |
| 168 | }; |
| 169 | |
Kent Overstreet | 73bd774 | 2023-07-06 22:47:42 -0400 | [diff] [blame] | 170 | *((__le32 *) &ret.csum.lo) = (__le32 __force) crc->crc32.csum; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 171 | return ret; |
| 172 | } |
Kent Overstreet | 642d66d | 2018-10-02 16:40:12 -0400 | [diff] [blame] | 173 | case BCH_EXTENT_ENTRY_crc64: { |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 174 | 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 Overstreet | 73bd774 | 2023-07-06 22:47:42 -0400 | [diff] [blame] | 180 | *((__le16 *) &ret.csum.hi) = (__le16 __force) crc->crc64.csum_hi; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 181 | |
| 182 | return ret; |
| 183 | } |
Kent Overstreet | 642d66d | 2018-10-02 16:40:12 -0400 | [diff] [blame] | 184 | case BCH_EXTENT_ENTRY_crc128: { |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 185 | 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 Overstreet | ab05de4 | 2018-02-23 16:26:10 -0500 | [diff] [blame] | 199 | static 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 Overstreet | 9db2f86 | 2023-10-22 11:33:02 -0400 | [diff] [blame] | 205 | static 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 Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 210 | /* bkey_ptrs: generically over any key type that has ptrs */ |
| 211 | |
| 212 | struct bkey_ptrs_c { |
| 213 | const union bch_extent_entry *start; |
| 214 | const union bch_extent_entry *end; |
| 215 | }; |
| 216 | |
| 217 | struct bkey_ptrs { |
| 218 | union bch_extent_entry *start; |
| 219 | union bch_extent_entry *end; |
| 220 | }; |
| 221 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 222 | static 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 Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 227 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 228 | 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 Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 235 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 236 | 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 Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 243 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 244 | 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 251 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 252 | return (struct bkey_ptrs_c) { |
| 253 | r.v->start, |
| 254 | bkey_val_end(r), |
| 255 | }; |
| 256 | } |
Kent Overstreet | 548b3d2 | 2020-02-07 13:38:02 -0500 | [diff] [blame] | 257 | case KEY_TYPE_btree_ptr_v2: { |
| 258 | struct bkey_s_c_btree_ptr_v2 e = bkey_s_c_to_btree_ptr_v2(k); |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 259 | |
Kent Overstreet | 548b3d2 | 2020-02-07 13:38:02 -0500 | [diff] [blame] | 260 | return (struct bkey_ptrs_c) { |
| 261 | to_entry(&e.v->start[0]), |
| 262 | to_entry(extent_entry_last(e)) |
| 263 | }; |
| 264 | } |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 265 | default: |
| 266 | return (struct bkey_ptrs_c) { NULL, NULL }; |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | static 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 279 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 280 | #define __bkey_extent_entry_for_each_from(_start, _end, _entry) \ |
| 281 | for ((_entry) = (_start); \ |
| 282 | (_entry) < (_end); \ |
| 283 | (_entry) = extent_entry_next(_entry)) |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 284 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 285 | #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 Overstreet | 37954a2 | 2019-10-08 18:45:29 -0400 | [diff] [blame] | 318 | (_ptr).has_ec = false; \ |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 319 | \ |
| 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 Overstreet | 37954a2 | 2019-10-08 18:45:29 -0400 | [diff] [blame] | 332 | (_ptr).ec = _entry->stripe_ptr; \ |
| 333 | (_ptr).has_ec = true; \ |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 334 | break; \ |
Kent Overstreet | 2766876 | 2023-06-27 19:02:17 -0400 | [diff] [blame] | 335 | default: \ |
| 336 | /* nothing */ \ |
| 337 | break; \ |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 338 | } \ |
| 339 | out: \ |
| 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 Overstreet | 99aaf57 | 2019-07-25 13:52:14 -0400 | [diff] [blame] | 353 | #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 Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 374 | /* 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 Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 378 | extent_entry_last(_e), _entry) |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 379 | |
| 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 Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 393 | /* utility code common to all keys with pointers: */ |
| 394 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 395 | void bch2_mark_io_failure(struct bch_io_failures *, |
| 396 | struct extent_ptr_decoded *); |
| 397 | int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, |
| 398 | struct bch_io_failures *, |
| 399 | struct extent_ptr_decoded *); |
Kent Overstreet | 7642609 | 2019-08-16 09:59:56 -0400 | [diff] [blame] | 400 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 401 | /* KEY_TYPE_btree_ptr: */ |
| 402 | |
Kent Overstreet | b65db75 | 2023-10-24 20:44:36 -0400 | [diff] [blame] | 403 | int bch2_btree_ptr_invalid(struct bch_fs *, struct bkey_s_c, |
Kent Overstreet | 8726dc9 | 2023-07-06 21:16:10 -0400 | [diff] [blame] | 404 | enum bkey_invalid_flags, struct printbuf *); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 405 | void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, |
| 406 | struct bkey_s_c); |
Kent Overstreet | 59a38a3 | 2020-03-31 16:25:30 -0400 | [diff] [blame] | 407 | |
Kent Overstreet | b65db75 | 2023-10-24 20:44:36 -0400 | [diff] [blame] | 408 | int bch2_btree_ptr_v2_invalid(struct bch_fs *, struct bkey_s_c, |
Kent Overstreet | 8726dc9 | 2023-07-06 21:16:10 -0400 | [diff] [blame] | 409 | enum bkey_invalid_flags, struct printbuf *); |
Kent Overstreet | f0ac7df | 2022-04-03 17:50:01 -0400 | [diff] [blame] | 410 | void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); |
Kent Overstreet | 39fb298 | 2020-01-07 13:29:32 -0500 | [diff] [blame] | 411 | void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned, |
| 412 | int, struct bkey_s); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 413 | |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 414 | #define bch2_bkey_ops_btree_ptr ((struct bkey_ops) { \ |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 415 | .key_invalid = bch2_btree_ptr_invalid, \ |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 416 | .val_to_text = bch2_btree_ptr_to_text, \ |
| 417 | .swab = bch2_ptr_swab, \ |
Kent Overstreet | 880e227 | 2022-03-13 00:26:52 -0500 | [diff] [blame] | 418 | .trans_trigger = bch2_trans_mark_extent, \ |
| 419 | .atomic_trigger = bch2_mark_extent, \ |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 420 | }) |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 421 | |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 422 | #define bch2_bkey_ops_btree_ptr_v2 ((struct bkey_ops) { \ |
Kent Overstreet | fad7cfe | 2021-03-22 17:23:30 -0400 | [diff] [blame] | 423 | .key_invalid = bch2_btree_ptr_v2_invalid, \ |
Kent Overstreet | 59a38a3 | 2020-03-31 16:25:30 -0400 | [diff] [blame] | 424 | .val_to_text = bch2_btree_ptr_v2_to_text, \ |
Kent Overstreet | 548b3d2 | 2020-02-07 13:38:02 -0500 | [diff] [blame] | 425 | .swab = bch2_ptr_swab, \ |
Kent Overstreet | 39fb298 | 2020-01-07 13:29:32 -0500 | [diff] [blame] | 426 | .compat = bch2_btree_ptr_v2_compat, \ |
Kent Overstreet | 880e227 | 2022-03-13 00:26:52 -0500 | [diff] [blame] | 427 | .trans_trigger = bch2_trans_mark_extent, \ |
| 428 | .atomic_trigger = bch2_mark_extent, \ |
Kent Overstreet | 174f930 | 2023-04-29 13:24:18 -0400 | [diff] [blame] | 429 | .min_val_size = 40, \ |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 430 | }) |
Kent Overstreet | 548b3d2 | 2020-02-07 13:38:02 -0500 | [diff] [blame] | 431 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 432 | /* KEY_TYPE_extent: */ |
| 433 | |
Kent Overstreet | 59ba21d | 2021-04-28 23:49:30 -0400 | [diff] [blame] | 434 | bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 435 | |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 436 | #define bch2_bkey_ops_extent ((struct bkey_ops) { \ |
Kent Overstreet | f0ac7df | 2022-04-03 17:50:01 -0400 | [diff] [blame] | 437 | .key_invalid = bch2_bkey_ptrs_invalid, \ |
| 438 | .val_to_text = bch2_bkey_ptrs_to_text, \ |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 439 | .swab = bch2_ptr_swab, \ |
| 440 | .key_normalize = bch2_extent_normalize, \ |
| 441 | .key_merge = bch2_extent_merge, \ |
Kent Overstreet | 880e227 | 2022-03-13 00:26:52 -0500 | [diff] [blame] | 442 | .trans_trigger = bch2_trans_mark_extent, \ |
| 443 | .atomic_trigger = bch2_mark_extent, \ |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 444 | }) |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 445 | |
| 446 | /* KEY_TYPE_reservation: */ |
| 447 | |
Kent Overstreet | b65db75 | 2023-10-24 20:44:36 -0400 | [diff] [blame] | 448 | int bch2_reservation_invalid(struct bch_fs *, struct bkey_s_c, |
Kent Overstreet | 8726dc9 | 2023-07-06 21:16:10 -0400 | [diff] [blame] | 449 | enum bkey_invalid_flags, struct printbuf *); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 450 | void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); |
Kent Overstreet | 59ba21d | 2021-04-28 23:49:30 -0400 | [diff] [blame] | 451 | bool bch2_reservation_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 452 | |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 453 | #define bch2_bkey_ops_reservation ((struct bkey_ops) { \ |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 454 | .key_invalid = bch2_reservation_invalid, \ |
| 455 | .val_to_text = bch2_reservation_to_text, \ |
| 456 | .key_merge = bch2_reservation_merge, \ |
Kent Overstreet | 880e227 | 2022-03-13 00:26:52 -0500 | [diff] [blame] | 457 | .trans_trigger = bch2_trans_mark_reservation, \ |
| 458 | .atomic_trigger = bch2_mark_reservation, \ |
Kent Overstreet | 174f930 | 2023-04-29 13:24:18 -0400 | [diff] [blame] | 459 | .min_val_size = 8, \ |
Kent Overstreet | a101957 | 2022-10-22 15:59:53 -0400 | [diff] [blame] | 460 | }) |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 461 | |
| 462 | /* Extent checksum entries: */ |
| 463 | |
| 464 | bool bch2_can_narrow_extent_crcs(struct bkey_s_c, |
| 465 | struct bch_extent_crc_unpacked); |
| 466 | bool bch2_bkey_narrow_crcs(struct bkey_i *, struct bch_extent_crc_unpacked); |
| 467 | void bch2_extent_crc_append(struct bkey_i *, |
| 468 | struct bch_extent_crc_unpacked); |
| 469 | |
| 470 | /* Generic code for keys with pointers: */ |
| 471 | |
Kent Overstreet | 297d893 | 2021-06-10 21:44:27 -0400 | [diff] [blame] | 472 | static 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 Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 483 | static inline bool bkey_extent_is_direct_data(const struct bkey *k) |
| 484 | { |
| 485 | switch (k->type) { |
| 486 | case KEY_TYPE_btree_ptr: |
Kent Overstreet | 548b3d2 | 2020-02-07 13:38:02 -0500 | [diff] [blame] | 487 | case KEY_TYPE_btree_ptr_v2: |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 488 | case KEY_TYPE_extent: |
| 489 | case KEY_TYPE_reflink_v: |
| 490 | return true; |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 491 | default: |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 492 | return false; |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 493 | } |
| 494 | } |
| 495 | |
Kent Overstreet | 801a3de | 2020-10-24 19:51:34 -0400 | [diff] [blame] | 496 | static 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 | |
| 502 | static 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 | |
| 514 | static 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 Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 521 | static inline bool bkey_extent_is_data(const struct bkey *k) |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 522 | { |
Kent Overstreet | 801a3de | 2020-10-24 19:51:34 -0400 | [diff] [blame] | 523 | return bkey_extent_is_direct_data(k) || |
| 524 | bkey_extent_is_inline_data(k) || |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 525 | k->type == KEY_TYPE_reflink_p; |
| 526 | } |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 527 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 528 | /* |
| 529 | * Should extent be counted under inode->i_sectors? |
| 530 | */ |
| 531 | static 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 Overstreet | 801a3de | 2020-10-24 19:51:34 -0400 | [diff] [blame] | 539 | case KEY_TYPE_indirect_inline_data: |
Kent Overstreet | be47e0b | 2023-09-29 15:49:16 -0400 | [diff] [blame] | 540 | case KEY_TYPE_error: |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 541 | return true; |
| 542 | default: |
| 543 | return false; |
| 544 | } |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 545 | } |
| 546 | |
Kent Overstreet | 7920311 | 2022-11-13 18:59:01 -0500 | [diff] [blame] | 547 | static 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 | |
| 558 | static 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 Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 564 | static 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 | |
| 576 | static 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 | |
| 589 | static 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 Overstreet | e1036ce | 2021-05-14 21:28:37 -0400 | [diff] [blame] | 602 | static 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 Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 626 | unsigned bch2_bkey_nr_ptrs(struct bkey_s_c); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 627 | unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c); |
| 628 | unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c); |
Kent Overstreet | ab05de4 | 2018-02-23 16:26:10 -0500 | [diff] [blame] | 629 | bool bch2_bkey_is_incompressible(struct bkey_s_c); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 630 | unsigned bch2_bkey_sectors_compressed(struct bkey_s_c); |
Kent Overstreet | 35a067b | 2020-12-14 21:59:33 -0500 | [diff] [blame] | 631 | |
| 632 | unsigned bch2_bkey_replicas(struct bch_fs *, struct bkey_s_c); |
Kent Overstreet | 91ecd41 | 2023-06-13 15:12:04 -0400 | [diff] [blame] | 633 | unsigned bch2_extent_ptr_desired_durability(struct bch_fs *, struct extent_ptr_decoded *); |
Kent Overstreet | a8b3a67 | 2022-11-02 17:12:00 -0400 | [diff] [blame] | 634 | unsigned bch2_extent_ptr_durability(struct bch_fs *, struct extent_ptr_decoded *); |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 635 | unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c); |
| 636 | |
Kent Overstreet | 393a1f6 | 2022-11-24 18:03:55 -0500 | [diff] [blame] | 637 | void bch2_bkey_drop_device(struct bkey_s, unsigned); |
| 638 | void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned); |
Kent Overstreet | 702ffea | 2023-03-10 16:28:37 -0500 | [diff] [blame] | 639 | |
| 640 | const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned); |
| 641 | |
| 642 | static 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 Overstreet | 393a1f6 | 2022-11-24 18:03:55 -0500 | [diff] [blame] | 647 | bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); |
| 648 | |
Kent Overstreet | 0507962 | 2021-02-17 13:37:22 -0500 | [diff] [blame] | 649 | void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *); |
Kent Overstreet | 393a1f6 | 2022-11-24 18:03:55 -0500 | [diff] [blame] | 650 | |
| 651 | static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr) |
| 652 | { |
Kees Cook | 7413ab7 | 2023-10-18 16:07:32 -0700 | [diff] [blame] | 653 | struct bch_extent_ptr *dest; |
| 654 | |
Kent Overstreet | 702ffea | 2023-03-10 16:28:37 -0500 | [diff] [blame] | 655 | EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev)); |
Kent Overstreet | 393a1f6 | 2022-11-24 18:03:55 -0500 | [diff] [blame] | 656 | |
| 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 Cook | 7413ab7 | 2023-10-18 16:07:32 -0700 | [diff] [blame] | 664 | dest = (struct bch_extent_ptr *)((void *) &k->v + bkey_val_bytes(&k->k)); |
| 665 | *dest = ptr; |
Kent Overstreet | ac2ccdd | 2023-03-04 23:05:55 -0500 | [diff] [blame] | 666 | k->k.u64s++; |
Kent Overstreet | 393a1f6 | 2022-11-24 18:03:55 -0500 | [diff] [blame] | 667 | break; |
| 668 | default: |
| 669 | BUG(); |
| 670 | } |
| 671 | } |
| 672 | |
Kent Overstreet | 99aaf57 | 2019-07-25 13:52:14 -0400 | [diff] [blame] | 673 | void bch2_extent_ptr_decoded_append(struct bkey_i *, |
Kent Overstreet | 71c9e0b | 2018-09-27 21:08:39 -0400 | [diff] [blame] | 674 | struct extent_ptr_decoded *); |
Kent Overstreet | 702ffea | 2023-03-10 16:28:37 -0500 | [diff] [blame] | 675 | union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s, |
| 676 | struct bch_extent_ptr *); |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 677 | union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s, |
| 678 | struct bch_extent_ptr *); |
Kent Overstreet | a275358 | 2018-09-30 18:28:23 -0400 | [diff] [blame] | 679 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 680 | #define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \ |
Kent Overstreet | a275358 | 2018-09-30 18:28:23 -0400 | [diff] [blame] | 681 | do { \ |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 682 | struct bkey_ptrs _ptrs = bch2_bkey_ptrs(_k); \ |
Kent Overstreet | a275358 | 2018-09-30 18:28:23 -0400 | [diff] [blame] | 683 | \ |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 684 | _ptr = &_ptrs.start->ptr; \ |
| 685 | \ |
| 686 | while ((_ptr = bkey_ptr_next(_ptrs, _ptr))) { \ |
Kent Overstreet | a275358 | 2018-09-30 18:28:23 -0400 | [diff] [blame] | 687 | if (_cond) { \ |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 688 | _ptr = (void *) bch2_bkey_drop_ptr(_k, _ptr); \ |
| 689 | _ptrs = bch2_bkey_ptrs(_k); \ |
Kent Overstreet | a275358 | 2018-09-30 18:28:23 -0400 | [diff] [blame] | 690 | continue; \ |
| 691 | } \ |
| 692 | \ |
| 693 | (_ptr)++; \ |
| 694 | } \ |
| 695 | } while (0) |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 696 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 697 | bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c, |
| 698 | struct bch_extent_ptr, u64); |
Kent Overstreet | 7f5c5d2 | 2022-06-13 19:17:45 -0400 | [diff] [blame] | 699 | bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c); |
Kent Overstreet | 702ffea | 2023-03-10 16:28:37 -0500 | [diff] [blame] | 700 | struct bch_extent_ptr * |
| 701 | bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 702 | |
Kent Overstreet | c9163bb | 2023-02-21 19:22:44 -0500 | [diff] [blame] | 703 | void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *); |
| 704 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 705 | bool bch2_extent_normalize(struct bch_fs *, struct bkey_s); |
| 706 | void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, |
| 707 | struct bkey_s_c); |
Kent Overstreet | b65db75 | 2023-10-24 20:44:36 -0400 | [diff] [blame] | 708 | int bch2_bkey_ptrs_invalid(struct bch_fs *, struct bkey_s_c, |
Kent Overstreet | 8726dc9 | 2023-07-06 21:16:10 -0400 | [diff] [blame] | 709 | enum bkey_invalid_flags, struct printbuf *); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 710 | |
Kent Overstreet | 1f49daf | 2020-02-06 20:15:15 -0500 | [diff] [blame] | 711 | void bch2_ptr_swab(struct bkey_s); |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 712 | |
Kent Overstreet | fb3f57b | 2023-10-20 13:33:14 -0400 | [diff] [blame] | 713 | const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c); |
| 714 | unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c, |
| 715 | unsigned, unsigned); |
| 716 | bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c); |
| 717 | |
| 718 | int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *, |
| 719 | unsigned, unsigned); |
| 720 | |
Kent Overstreet | 4de7749 | 2019-11-16 16:25:58 -0500 | [diff] [blame] | 721 | /* Generic extent code: */ |
| 722 | |
Kent Overstreet | 4cf91b0 | 2021-03-04 16:20:16 -0500 | [diff] [blame] | 723 | enum 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 */ |
| 731 | static inline enum bch_extent_overlap bch2_extent_overlap(const struct bkey *k, |
| 732 | const struct bkey *m) |
| 733 | { |
Kent Overstreet | e88a75e | 2022-11-24 03:12:22 -0500 | [diff] [blame] | 734 | int cmp1 = bkey_lt(k->p, m->p); |
| 735 | int cmp2 = bkey_gt(bkey_start_pos(k), bkey_start_pos(m)); |
Kent Overstreet | 4cf91b0 | 2021-03-04 16:20:16 -0500 | [diff] [blame] | 736 | |
| 737 | return (cmp1 << 1) + cmp2; |
| 738 | } |
| 739 | |
Kent Overstreet | 085ab69 | 2019-11-09 19:02:48 -0500 | [diff] [blame] | 740 | int bch2_cut_front_s(struct bpos, struct bkey_s); |
| 741 | int bch2_cut_back_s(struct bpos, struct bkey_s); |
Kent Overstreet | 5b8a922 | 2018-11-27 18:30:56 -0500 | [diff] [blame] | 742 | |
Kent Overstreet | b1c9358 | 2019-07-18 17:21:21 -0400 | [diff] [blame] | 743 | static inline void bch2_cut_front(struct bpos where, struct bkey_i *k) |
Kent Overstreet | 5b8a922 | 2018-11-27 18:30:56 -0500 | [diff] [blame] | 744 | { |
Kent Overstreet | 085ab69 | 2019-11-09 19:02:48 -0500 | [diff] [blame] | 745 | bch2_cut_front_s(where, bkey_i_to_s(k)); |
Kent Overstreet | 5b8a922 | 2018-11-27 18:30:56 -0500 | [diff] [blame] | 746 | } |
| 747 | |
Kent Overstreet | 085ab69 | 2019-11-09 19:02:48 -0500 | [diff] [blame] | 748 | static 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 Overstreet | 3fb5ebc | 2019-08-22 16:07:37 -0400 | [diff] [blame] | 752 | |
| 753 | /** |
| 754 | * bch_key_resize - adjust size of @k |
| 755 | * |
| 756 | * bkey_start_offset(k) will be preserved, modifies where the extent ends |
| 757 | */ |
| 758 | static 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 Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 764 | |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 765 | #endif /* _BCACHEFS_EXTENTS_H */ |