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; 10 struct btree_trans; 11 enum bch_validate_flags; 12 13 /* extent entries: */ 14 15 #define extent_entry_last(_e) \ 16 ((typeof(&(_e).v->start[0])) bkey_val_end(_e)) 17 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 }) 27 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 }) 42 43 #define extent_entry_next(_entry) \ 44 ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry))) 45 46 #define extent_entry_next_safe(_entry, _end) \ 47 (likely(__extent_entry_type(_entry) < BCH_EXTENT_ENTRY_MAX) \ 48 ? extent_entry_next(_entry) \ 49 : _end) 50 51 static inline unsigned 52 __extent_entry_type(const union bch_extent_entry *e) 53 { 54 return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX; 55 } 56 57 static inline enum bch_extent_entry_type 58 extent_entry_type(const union bch_extent_entry *e) 59 { 60 int ret = __ffs(e->type); 61 62 EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX); 63 64 return ret; 65 } 66 67 static inline size_t extent_entry_bytes(const union bch_extent_entry *entry) 68 { 69 switch (extent_entry_type(entry)) { 70 #define x(f, n) \ 71 case BCH_EXTENT_ENTRY_##f: \ 72 return sizeof(struct bch_extent_##f); 73 BCH_EXTENT_ENTRY_TYPES() 74 #undef x 75 default: 76 BUG(); 77 } 78 } 79 80 static inline size_t extent_entry_u64s(const union bch_extent_entry *entry) 81 { 82 return extent_entry_bytes(entry) / sizeof(u64); 83 } 84 85 static inline void __extent_entry_insert(struct bkey_i *k, 86 union bch_extent_entry *dst, 87 union bch_extent_entry *new) 88 { 89 union bch_extent_entry *end = bkey_val_end(bkey_i_to_s(k)); 90 91 memmove_u64s_up_small((u64 *) dst + extent_entry_u64s(new), 92 dst, (u64 *) end - (u64 *) dst); 93 k->k.u64s += extent_entry_u64s(new); 94 memcpy_u64s_small(dst, new, extent_entry_u64s(new)); 95 } 96 97 static inline void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry) 98 { 99 union bch_extent_entry *next = extent_entry_next(entry); 100 101 /* stripes have ptrs, but their layout doesn't work with this code */ 102 BUG_ON(k.k->type == KEY_TYPE_stripe); 103 104 memmove_u64s_down(entry, next, 105 (u64 *) bkey_val_end(k) - (u64 *) next); 106 k.k->u64s -= (u64 *) next - (u64 *) entry; 107 } 108 109 static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) 110 { 111 return __extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr; 112 } 113 114 static inline bool extent_entry_is_stripe_ptr(const union bch_extent_entry *e) 115 { 116 return __extent_entry_type(e) == BCH_EXTENT_ENTRY_stripe_ptr; 117 } 118 119 static inline bool extent_entry_is_crc(const union bch_extent_entry *e) 120 { 121 switch (__extent_entry_type(e)) { 122 case BCH_EXTENT_ENTRY_crc32: 123 case BCH_EXTENT_ENTRY_crc64: 124 case BCH_EXTENT_ENTRY_crc128: 125 return true; 126 default: 127 return false; 128 } 129 } 130 131 union bch_extent_crc { 132 u8 type; 133 struct bch_extent_crc32 crc32; 134 struct bch_extent_crc64 crc64; 135 struct bch_extent_crc128 crc128; 136 }; 137 138 #define __entry_to_crc(_entry) \ 139 __builtin_choose_expr( \ 140 type_is_exact(_entry, const union bch_extent_entry *), \ 141 (const union bch_extent_crc *) (_entry), \ 142 (union bch_extent_crc *) (_entry)) 143 144 #define entry_to_crc(_entry) \ 145 ({ \ 146 EBUG_ON((_entry) && !extent_entry_is_crc(_entry)); \ 147 \ 148 __entry_to_crc(_entry); \ 149 }) 150 151 static inline struct bch_extent_crc_unpacked 152 bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc) 153 { 154 #define common_fields(_crc) \ 155 .csum_type = _crc.csum_type, \ 156 .compression_type = _crc.compression_type, \ 157 .compressed_size = _crc._compressed_size + 1, \ 158 .uncompressed_size = _crc._uncompressed_size + 1, \ 159 .offset = _crc.offset, \ 160 .live_size = k->size 161 162 if (!crc) 163 return (struct bch_extent_crc_unpacked) { 164 .compressed_size = k->size, 165 .uncompressed_size = k->size, 166 .live_size = k->size, 167 }; 168 169 switch (extent_entry_type(to_entry(crc))) { 170 case BCH_EXTENT_ENTRY_crc32: { 171 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 172 common_fields(crc->crc32), 173 }; 174 175 *((__le32 *) &ret.csum.lo) = (__le32 __force) crc->crc32.csum; 176 return ret; 177 } 178 case BCH_EXTENT_ENTRY_crc64: { 179 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 180 common_fields(crc->crc64), 181 .nonce = crc->crc64.nonce, 182 .csum.lo = (__force __le64) crc->crc64.csum_lo, 183 }; 184 185 *((__le16 *) &ret.csum.hi) = (__le16 __force) crc->crc64.csum_hi; 186 187 return ret; 188 } 189 case BCH_EXTENT_ENTRY_crc128: { 190 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 191 common_fields(crc->crc128), 192 .nonce = crc->crc128.nonce, 193 .csum = crc->crc128.csum, 194 }; 195 196 return ret; 197 } 198 default: 199 BUG(); 200 } 201 #undef common_fields 202 } 203 204 static inline bool crc_is_compressed(struct bch_extent_crc_unpacked crc) 205 { 206 return (crc.compression_type != BCH_COMPRESSION_TYPE_none && 207 crc.compression_type != BCH_COMPRESSION_TYPE_incompressible); 208 } 209 210 static inline bool crc_is_encoded(struct bch_extent_crc_unpacked crc) 211 { 212 return crc.csum_type != BCH_CSUM_none || crc_is_compressed(crc); 213 } 214 215 /* bkey_ptrs: generically over any key type that has ptrs */ 216 217 struct bkey_ptrs_c { 218 const union bch_extent_entry *start; 219 const union bch_extent_entry *end; 220 }; 221 222 struct bkey_ptrs { 223 union bch_extent_entry *start; 224 union bch_extent_entry *end; 225 }; 226 227 static inline struct bkey_ptrs_c bch2_bkey_ptrs_c(struct bkey_s_c k) 228 { 229 switch (k.k->type) { 230 case KEY_TYPE_btree_ptr: { 231 struct bkey_s_c_btree_ptr e = bkey_s_c_to_btree_ptr(k); 232 233 return (struct bkey_ptrs_c) { 234 to_entry(&e.v->start[0]), 235 to_entry(extent_entry_last(e)) 236 }; 237 } 238 case KEY_TYPE_extent: { 239 struct bkey_s_c_extent e = bkey_s_c_to_extent(k); 240 241 return (struct bkey_ptrs_c) { 242 e.v->start, 243 extent_entry_last(e) 244 }; 245 } 246 case KEY_TYPE_stripe: { 247 struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); 248 249 return (struct bkey_ptrs_c) { 250 to_entry(&s.v->ptrs[0]), 251 to_entry(&s.v->ptrs[s.v->nr_blocks]), 252 }; 253 } 254 case KEY_TYPE_reflink_v: { 255 struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k); 256 257 return (struct bkey_ptrs_c) { 258 r.v->start, 259 bkey_val_end(r), 260 }; 261 } 262 case KEY_TYPE_btree_ptr_v2: { 263 struct bkey_s_c_btree_ptr_v2 e = bkey_s_c_to_btree_ptr_v2(k); 264 265 return (struct bkey_ptrs_c) { 266 to_entry(&e.v->start[0]), 267 to_entry(extent_entry_last(e)) 268 }; 269 } 270 default: 271 return (struct bkey_ptrs_c) { NULL, NULL }; 272 } 273 } 274 275 static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k) 276 { 277 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k.s_c); 278 279 return (struct bkey_ptrs) { 280 (void *) p.start, 281 (void *) p.end 282 }; 283 } 284 285 #define __bkey_extent_entry_for_each_from(_start, _end, _entry) \ 286 for ((_entry) = (_start); \ 287 (_entry) < (_end); \ 288 (_entry) = extent_entry_next_safe(_entry, _end)) 289 290 #define __bkey_ptr_next(_ptr, _end) \ 291 ({ \ 292 typeof(_end) _entry; \ 293 \ 294 __bkey_extent_entry_for_each_from(to_entry(_ptr), _end, _entry) \ 295 if (extent_entry_is_ptr(_entry)) \ 296 break; \ 297 \ 298 _entry < (_end) ? entry_to_ptr(_entry) : NULL; \ 299 }) 300 301 #define bkey_extent_entry_for_each_from(_p, _entry, _start) \ 302 __bkey_extent_entry_for_each_from(_start, (_p).end, _entry) 303 304 #define bkey_extent_entry_for_each(_p, _entry) \ 305 bkey_extent_entry_for_each_from(_p, _entry, _p.start) 306 307 #define __bkey_for_each_ptr(_start, _end, _ptr) \ 308 for (typeof(_start) (_ptr) = (_start); \ 309 ((_ptr) = __bkey_ptr_next(_ptr, _end)); \ 310 (_ptr)++) 311 312 #define bkey_ptr_next(_p, _ptr) \ 313 __bkey_ptr_next(_ptr, (_p).end) 314 315 #define bkey_for_each_ptr(_p, _ptr) \ 316 __bkey_for_each_ptr(&(_p).start->ptr, (_p).end, _ptr) 317 318 #define __bkey_ptr_next_decode(_k, _end, _ptr, _entry) \ 319 ({ \ 320 __label__ out; \ 321 \ 322 (_ptr).idx = 0; \ 323 (_ptr).has_ec = false; \ 324 \ 325 __bkey_extent_entry_for_each_from(_entry, _end, _entry) \ 326 switch (__extent_entry_type(_entry)) { \ 327 case BCH_EXTENT_ENTRY_ptr: \ 328 (_ptr).ptr = _entry->ptr; \ 329 goto out; \ 330 case BCH_EXTENT_ENTRY_crc32: \ 331 case BCH_EXTENT_ENTRY_crc64: \ 332 case BCH_EXTENT_ENTRY_crc128: \ 333 (_ptr).crc = bch2_extent_crc_unpack(_k, \ 334 entry_to_crc(_entry)); \ 335 break; \ 336 case BCH_EXTENT_ENTRY_stripe_ptr: \ 337 (_ptr).ec = _entry->stripe_ptr; \ 338 (_ptr).has_ec = true; \ 339 break; \ 340 default: \ 341 /* nothing */ \ 342 break; \ 343 } \ 344 out: \ 345 _entry < (_end); \ 346 }) 347 348 #define __bkey_for_each_ptr_decode(_k, _start, _end, _ptr, _entry) \ 349 for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL), \ 350 (_entry) = _start; \ 351 __bkey_ptr_next_decode(_k, _end, _ptr, _entry); \ 352 (_entry) = extent_entry_next_safe(_entry, _end)) 353 354 #define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry) \ 355 __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end, \ 356 _ptr, _entry) 357 358 #define bkey_crc_next(_k, _start, _end, _crc, _iter) \ 359 ({ \ 360 __bkey_extent_entry_for_each_from(_iter, _end, _iter) \ 361 if (extent_entry_is_crc(_iter)) { \ 362 (_crc) = bch2_extent_crc_unpack(_k, \ 363 entry_to_crc(_iter)); \ 364 break; \ 365 } \ 366 \ 367 (_iter) < (_end); \ 368 }) 369 370 #define __bkey_for_each_crc(_k, _start, _end, _crc, _iter) \ 371 for ((_crc) = bch2_extent_crc_unpack(_k, NULL), \ 372 (_iter) = (_start); \ 373 bkey_crc_next(_k, _start, _end, _crc, _iter); \ 374 (_iter) = extent_entry_next(_iter)) 375 376 #define bkey_for_each_crc(_k, _p, _crc, _iter) \ 377 __bkey_for_each_crc(_k, (_p).start, (_p).end, _crc, _iter) 378 379 /* Iterate over pointers in KEY_TYPE_extent: */ 380 381 #define extent_for_each_entry_from(_e, _entry, _start) \ 382 __bkey_extent_entry_for_each_from(_start, \ 383 extent_entry_last(_e), _entry) 384 385 #define extent_for_each_entry(_e, _entry) \ 386 extent_for_each_entry_from(_e, _entry, (_e).v->start) 387 388 #define extent_ptr_next(_e, _ptr) \ 389 __bkey_ptr_next(_ptr, extent_entry_last(_e)) 390 391 #define extent_for_each_ptr(_e, _ptr) \ 392 __bkey_for_each_ptr(&(_e).v->start->ptr, extent_entry_last(_e), _ptr) 393 394 #define extent_for_each_ptr_decode(_e, _ptr, _entry) \ 395 __bkey_for_each_ptr_decode((_e).k, (_e).v->start, \ 396 extent_entry_last(_e), _ptr, _entry) 397 398 /* utility code common to all keys with pointers: */ 399 400 void bch2_mark_io_failure(struct bch_io_failures *, 401 struct extent_ptr_decoded *); 402 int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, 403 struct bch_io_failures *, 404 struct extent_ptr_decoded *); 405 406 /* KEY_TYPE_btree_ptr: */ 407 408 int bch2_btree_ptr_invalid(struct bch_fs *, struct bkey_s_c, 409 enum bch_validate_flags, struct printbuf *); 410 void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, 411 struct bkey_s_c); 412 413 int bch2_btree_ptr_v2_invalid(struct bch_fs *, struct bkey_s_c, 414 enum bch_validate_flags, struct printbuf *); 415 void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 416 void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned, 417 int, struct bkey_s); 418 419 #define bch2_bkey_ops_btree_ptr ((struct bkey_ops) { \ 420 .key_invalid = bch2_btree_ptr_invalid, \ 421 .val_to_text = bch2_btree_ptr_to_text, \ 422 .swab = bch2_ptr_swab, \ 423 .trigger = bch2_trigger_extent, \ 424 }) 425 426 #define bch2_bkey_ops_btree_ptr_v2 ((struct bkey_ops) { \ 427 .key_invalid = bch2_btree_ptr_v2_invalid, \ 428 .val_to_text = bch2_btree_ptr_v2_to_text, \ 429 .swab = bch2_ptr_swab, \ 430 .compat = bch2_btree_ptr_v2_compat, \ 431 .trigger = bch2_trigger_extent, \ 432 .min_val_size = 40, \ 433 }) 434 435 /* KEY_TYPE_extent: */ 436 437 bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 438 439 #define bch2_bkey_ops_extent ((struct bkey_ops) { \ 440 .key_invalid = bch2_bkey_ptrs_invalid, \ 441 .val_to_text = bch2_bkey_ptrs_to_text, \ 442 .swab = bch2_ptr_swab, \ 443 .key_normalize = bch2_extent_normalize, \ 444 .key_merge = bch2_extent_merge, \ 445 .trigger = bch2_trigger_extent, \ 446 }) 447 448 /* KEY_TYPE_reservation: */ 449 450 int bch2_reservation_invalid(struct bch_fs *, struct bkey_s_c, 451 enum bch_validate_flags, struct printbuf *); 452 void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 453 bool bch2_reservation_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 454 455 #define bch2_bkey_ops_reservation ((struct bkey_ops) { \ 456 .key_invalid = bch2_reservation_invalid, \ 457 .val_to_text = bch2_reservation_to_text, \ 458 .key_merge = bch2_reservation_merge, \ 459 .trigger = bch2_trigger_reservation, \ 460 .min_val_size = 8, \ 461 }) 462 463 /* Extent checksum entries: */ 464 465 bool bch2_can_narrow_extent_crcs(struct bkey_s_c, 466 struct bch_extent_crc_unpacked); 467 bool bch2_bkey_narrow_crcs(struct bkey_i *, struct bch_extent_crc_unpacked); 468 void bch2_extent_crc_append(struct bkey_i *, 469 struct bch_extent_crc_unpacked); 470 471 /* Generic code for keys with pointers: */ 472 473 static inline bool bkey_is_btree_ptr(const struct bkey *k) 474 { 475 switch (k->type) { 476 case KEY_TYPE_btree_ptr: 477 case KEY_TYPE_btree_ptr_v2: 478 return true; 479 default: 480 return false; 481 } 482 } 483 484 static inline bool bkey_extent_is_direct_data(const struct bkey *k) 485 { 486 switch (k->type) { 487 case KEY_TYPE_btree_ptr: 488 case KEY_TYPE_btree_ptr_v2: 489 case KEY_TYPE_extent: 490 case KEY_TYPE_reflink_v: 491 return true; 492 default: 493 return false; 494 } 495 } 496 497 static inline bool bkey_extent_is_inline_data(const struct bkey *k) 498 { 499 return k->type == KEY_TYPE_inline_data || 500 k->type == KEY_TYPE_indirect_inline_data; 501 } 502 503 static inline unsigned bkey_inline_data_offset(const struct bkey *k) 504 { 505 switch (k->type) { 506 case KEY_TYPE_inline_data: 507 return sizeof(struct bch_inline_data); 508 case KEY_TYPE_indirect_inline_data: 509 return sizeof(struct bch_indirect_inline_data); 510 default: 511 BUG(); 512 } 513 } 514 515 static inline unsigned bkey_inline_data_bytes(const struct bkey *k) 516 { 517 return bkey_val_bytes(k) - bkey_inline_data_offset(k); 518 } 519 520 #define bkey_inline_data_p(_k) (((void *) (_k).v) + bkey_inline_data_offset((_k).k)) 521 522 static inline bool bkey_extent_is_data(const struct bkey *k) 523 { 524 return bkey_extent_is_direct_data(k) || 525 bkey_extent_is_inline_data(k) || 526 k->type == KEY_TYPE_reflink_p; 527 } 528 529 /* 530 * Should extent be counted under inode->i_sectors? 531 */ 532 static inline bool bkey_extent_is_allocation(const struct bkey *k) 533 { 534 switch (k->type) { 535 case KEY_TYPE_extent: 536 case KEY_TYPE_reservation: 537 case KEY_TYPE_reflink_p: 538 case KEY_TYPE_reflink_v: 539 case KEY_TYPE_inline_data: 540 case KEY_TYPE_indirect_inline_data: 541 case KEY_TYPE_error: 542 return true; 543 default: 544 return false; 545 } 546 } 547 548 static inline bool bkey_extent_is_unwritten(struct bkey_s_c k) 549 { 550 struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); 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 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 569 bkey_for_each_ptr(p, ptr) 570 ret.data[ret.nr++] = ptr->dev; 571 572 return ret; 573 } 574 575 static inline struct bch_devs_list bch2_bkey_dirty_devs(struct bkey_s_c k) 576 { 577 struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 578 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 579 580 bkey_for_each_ptr(p, ptr) 581 if (!ptr->cached) 582 ret.data[ret.nr++] = ptr->dev; 583 584 return ret; 585 } 586 587 static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k) 588 { 589 struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 590 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 591 592 bkey_for_each_ptr(p, ptr) 593 if (ptr->cached) 594 ret.data[ret.nr++] = ptr->dev; 595 596 return ret; 597 } 598 599 unsigned bch2_bkey_nr_ptrs(struct bkey_s_c); 600 unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c); 601 unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c); 602 bool bch2_bkey_is_incompressible(struct bkey_s_c); 603 unsigned bch2_bkey_sectors_compressed(struct bkey_s_c); 604 605 unsigned bch2_bkey_replicas(struct bch_fs *, struct bkey_s_c); 606 unsigned bch2_extent_ptr_desired_durability(struct bch_fs *, struct extent_ptr_decoded *); 607 unsigned bch2_extent_ptr_durability(struct bch_fs *, struct extent_ptr_decoded *); 608 unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c); 609 610 void bch2_bkey_drop_device(struct bkey_s, unsigned); 611 void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned); 612 613 const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned); 614 615 static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsigned dev) 616 { 617 return (void *) bch2_bkey_has_device_c(k.s_c, dev); 618 } 619 620 bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); 621 622 void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *); 623 624 static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr) 625 { 626 struct bch_extent_ptr *dest; 627 628 EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev)); 629 630 switch (k->k.type) { 631 case KEY_TYPE_btree_ptr: 632 case KEY_TYPE_btree_ptr_v2: 633 case KEY_TYPE_extent: 634 EBUG_ON(bkey_val_u64s(&k->k) >= BKEY_EXTENT_VAL_U64s_MAX); 635 636 ptr.type = 1 << BCH_EXTENT_ENTRY_ptr; 637 dest = (struct bch_extent_ptr *)((void *) &k->v + bkey_val_bytes(&k->k)); 638 *dest = ptr; 639 k->k.u64s++; 640 break; 641 default: 642 BUG(); 643 } 644 } 645 646 void bch2_extent_ptr_decoded_append(struct bkey_i *, 647 struct extent_ptr_decoded *); 648 union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s, 649 struct bch_extent_ptr *); 650 union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s, 651 struct bch_extent_ptr *); 652 653 #define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \ 654 do { \ 655 struct bkey_ptrs _ptrs = bch2_bkey_ptrs(_k); \ 656 \ 657 struct bch_extent_ptr *_ptr = &_ptrs.start->ptr; \ 658 \ 659 while ((_ptr = bkey_ptr_next(_ptrs, _ptr))) { \ 660 if (_cond) { \ 661 _ptr = (void *) bch2_bkey_drop_ptr(_k, _ptr); \ 662 _ptrs = bch2_bkey_ptrs(_k); \ 663 continue; \ 664 } \ 665 \ 666 (_ptr)++; \ 667 } \ 668 } while (0) 669 670 bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c, 671 struct bch_extent_ptr, u64); 672 bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c); 673 struct bch_extent_ptr * 674 bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s); 675 676 void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *); 677 678 bool bch2_extent_normalize(struct bch_fs *, struct bkey_s); 679 void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *, const struct bch_extent_ptr *); 680 void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, 681 struct bkey_s_c); 682 int bch2_bkey_ptrs_invalid(struct bch_fs *, struct bkey_s_c, 683 enum bch_validate_flags, struct printbuf *); 684 685 void bch2_ptr_swab(struct bkey_s); 686 687 const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c); 688 unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c, 689 unsigned, unsigned); 690 bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c); 691 692 int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *, 693 struct bch_io_opts *); 694 695 /* Generic extent code: */ 696 697 enum bch_extent_overlap { 698 BCH_EXTENT_OVERLAP_ALL = 0, 699 BCH_EXTENT_OVERLAP_BACK = 1, 700 BCH_EXTENT_OVERLAP_FRONT = 2, 701 BCH_EXTENT_OVERLAP_MIDDLE = 3, 702 }; 703 704 /* Returns how k overlaps with m */ 705 static inline enum bch_extent_overlap bch2_extent_overlap(const struct bkey *k, 706 const struct bkey *m) 707 { 708 int cmp1 = bkey_lt(k->p, m->p); 709 int cmp2 = bkey_gt(bkey_start_pos(k), bkey_start_pos(m)); 710 711 return (cmp1 << 1) + cmp2; 712 } 713 714 int bch2_cut_front_s(struct bpos, struct bkey_s); 715 int bch2_cut_back_s(struct bpos, struct bkey_s); 716 717 static inline void bch2_cut_front(struct bpos where, struct bkey_i *k) 718 { 719 bch2_cut_front_s(where, bkey_i_to_s(k)); 720 } 721 722 static inline void bch2_cut_back(struct bpos where, struct bkey_i *k) 723 { 724 bch2_cut_back_s(where, bkey_i_to_s(k)); 725 } 726 727 /** 728 * bch_key_resize - adjust size of @k 729 * 730 * bkey_start_offset(k) will be preserved, modifies where the extent ends 731 */ 732 static inline void bch2_key_resize(struct bkey *k, unsigned new_size) 733 { 734 k->p.offset -= k->size; 735 k->p.offset += new_size; 736 k->size = new_size; 737 } 738 739 #endif /* _BCACHEFS_EXTENTS_H */ 740