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 12 /* extent entries: */ 13 14 #define extent_entry_last(_e) \ 15 ((typeof(&(_e).v->start[0])) bkey_val_end(_e)) 16 17 #define entry_to_ptr(_entry) \ 18 ({ \ 19 EBUG_ON((_entry) && !extent_entry_is_ptr(_entry)); \ 20 \ 21 __builtin_choose_expr( \ 22 type_is_exact(_entry, const union bch_extent_entry *), \ 23 (const struct bch_extent_ptr *) (_entry), \ 24 (struct bch_extent_ptr *) (_entry)); \ 25 }) 26 27 /* downcast, preserves const */ 28 #define to_entry(_entry) \ 29 ({ \ 30 BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) && \ 31 !type_is(_entry, struct bch_extent_ptr *) && \ 32 !type_is(_entry, struct bch_extent_stripe_ptr *)); \ 33 \ 34 __builtin_choose_expr( \ 35 (type_is_exact(_entry, const union bch_extent_crc *) || \ 36 type_is_exact(_entry, const struct bch_extent_ptr *) ||\ 37 type_is_exact(_entry, const struct bch_extent_stripe_ptr *)),\ 38 (const union bch_extent_entry *) (_entry), \ 39 (union bch_extent_entry *) (_entry)); \ 40 }) 41 42 #define extent_entry_next(_entry) \ 43 ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry))) 44 45 #define extent_entry_next_safe(_entry, _end) \ 46 (likely(__extent_entry_type(_entry) < BCH_EXTENT_ENTRY_MAX) \ 47 ? extent_entry_next(_entry) \ 48 : _end) 49 50 static inline unsigned 51 __extent_entry_type(const union bch_extent_entry *e) 52 { 53 return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX; 54 } 55 56 static inline enum bch_extent_entry_type 57 extent_entry_type(const union bch_extent_entry *e) 58 { 59 int ret = __ffs(e->type); 60 61 EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX); 62 63 return ret; 64 } 65 66 static inline size_t extent_entry_bytes(const union bch_extent_entry *entry) 67 { 68 switch (extent_entry_type(entry)) { 69 #define x(f, n) \ 70 case BCH_EXTENT_ENTRY_##f: \ 71 return sizeof(struct bch_extent_##f); 72 BCH_EXTENT_ENTRY_TYPES() 73 #undef x 74 default: 75 BUG(); 76 } 77 } 78 79 static inline size_t extent_entry_u64s(const union bch_extent_entry *entry) 80 { 81 return extent_entry_bytes(entry) / sizeof(u64); 82 } 83 84 static inline void __extent_entry_insert(struct bkey_i *k, 85 union bch_extent_entry *dst, 86 union bch_extent_entry *new) 87 { 88 union bch_extent_entry *end = bkey_val_end(bkey_i_to_s(k)); 89 90 memmove_u64s_up_small((u64 *) dst + extent_entry_u64s(new), 91 dst, (u64 *) end - (u64 *) dst); 92 k->k.u64s += extent_entry_u64s(new); 93 memcpy_u64s_small(dst, new, extent_entry_u64s(new)); 94 } 95 96 static inline void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry) 97 { 98 union bch_extent_entry *next = extent_entry_next(entry); 99 100 /* stripes have ptrs, but their layout doesn't work with this code */ 101 BUG_ON(k.k->type == KEY_TYPE_stripe); 102 103 memmove_u64s_down(entry, next, 104 (u64 *) bkey_val_end(k) - (u64 *) next); 105 k.k->u64s -= (u64 *) next - (u64 *) entry; 106 } 107 108 static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) 109 { 110 return __extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr; 111 } 112 113 static inline bool extent_entry_is_stripe_ptr(const union bch_extent_entry *e) 114 { 115 return __extent_entry_type(e) == BCH_EXTENT_ENTRY_stripe_ptr; 116 } 117 118 static inline bool extent_entry_is_crc(const union bch_extent_entry *e) 119 { 120 switch (__extent_entry_type(e)) { 121 case BCH_EXTENT_ENTRY_crc32: 122 case BCH_EXTENT_ENTRY_crc64: 123 case BCH_EXTENT_ENTRY_crc128: 124 return true; 125 default: 126 return false; 127 } 128 } 129 130 union bch_extent_crc { 131 u8 type; 132 struct bch_extent_crc32 crc32; 133 struct bch_extent_crc64 crc64; 134 struct bch_extent_crc128 crc128; 135 }; 136 137 #define __entry_to_crc(_entry) \ 138 __builtin_choose_expr( \ 139 type_is_exact(_entry, const union bch_extent_entry *), \ 140 (const union bch_extent_crc *) (_entry), \ 141 (union bch_extent_crc *) (_entry)) 142 143 #define entry_to_crc(_entry) \ 144 ({ \ 145 EBUG_ON((_entry) && !extent_entry_is_crc(_entry)); \ 146 \ 147 __entry_to_crc(_entry); \ 148 }) 149 150 static inline struct bch_extent_crc_unpacked 151 bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc) 152 { 153 #define common_fields(_crc) \ 154 .csum_type = _crc.csum_type, \ 155 .compression_type = _crc.compression_type, \ 156 .compressed_size = _crc._compressed_size + 1, \ 157 .uncompressed_size = _crc._uncompressed_size + 1, \ 158 .offset = _crc.offset, \ 159 .live_size = k->size 160 161 if (!crc) 162 return (struct bch_extent_crc_unpacked) { 163 .compressed_size = k->size, 164 .uncompressed_size = k->size, 165 .live_size = k->size, 166 }; 167 168 switch (extent_entry_type(to_entry(crc))) { 169 case BCH_EXTENT_ENTRY_crc32: { 170 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 171 common_fields(crc->crc32), 172 }; 173 174 *((__le32 *) &ret.csum.lo) = (__le32 __force) crc->crc32.csum; 175 return ret; 176 } 177 case BCH_EXTENT_ENTRY_crc64: { 178 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 179 common_fields(crc->crc64), 180 .nonce = crc->crc64.nonce, 181 .csum.lo = (__force __le64) crc->crc64.csum_lo, 182 }; 183 184 *((__le16 *) &ret.csum.hi) = (__le16 __force) crc->crc64.csum_hi; 185 186 return ret; 187 } 188 case BCH_EXTENT_ENTRY_crc128: { 189 struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 190 common_fields(crc->crc128), 191 .nonce = crc->crc128.nonce, 192 .csum = crc->crc128.csum, 193 }; 194 195 return ret; 196 } 197 default: 198 BUG(); 199 } 200 #undef common_fields 201 } 202 203 static inline bool crc_is_compressed(struct bch_extent_crc_unpacked crc) 204 { 205 return (crc.compression_type != BCH_COMPRESSION_TYPE_none && 206 crc.compression_type != BCH_COMPRESSION_TYPE_incompressible); 207 } 208 209 static inline bool crc_is_encoded(struct bch_extent_crc_unpacked crc) 210 { 211 return crc.csum_type != BCH_CSUM_none || crc_is_compressed(crc); 212 } 213 214 void bch2_extent_crc_unpacked_to_text(struct printbuf *, struct bch_extent_crc_unpacked *); 215 216 /* bkey_ptrs: generically over any key type that has ptrs */ 217 218 struct bkey_ptrs_c { 219 const union bch_extent_entry *start; 220 const union bch_extent_entry *end; 221 }; 222 223 struct bkey_ptrs { 224 union bch_extent_entry *start; 225 union bch_extent_entry *end; 226 }; 227 228 static inline struct bkey_ptrs_c bch2_bkey_ptrs_c(struct bkey_s_c k) 229 { 230 switch (k.k->type) { 231 case KEY_TYPE_btree_ptr: { 232 struct bkey_s_c_btree_ptr e = bkey_s_c_to_btree_ptr(k); 233 234 return (struct bkey_ptrs_c) { 235 to_entry(&e.v->start[0]), 236 to_entry(extent_entry_last(e)) 237 }; 238 } 239 case KEY_TYPE_extent: { 240 struct bkey_s_c_extent e = bkey_s_c_to_extent(k); 241 242 return (struct bkey_ptrs_c) { 243 e.v->start, 244 extent_entry_last(e) 245 }; 246 } 247 case KEY_TYPE_stripe: { 248 struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); 249 250 return (struct bkey_ptrs_c) { 251 to_entry(&s.v->ptrs[0]), 252 to_entry(&s.v->ptrs[s.v->nr_blocks]), 253 }; 254 } 255 case KEY_TYPE_reflink_v: { 256 struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k); 257 258 return (struct bkey_ptrs_c) { 259 r.v->start, 260 bkey_val_end(r), 261 }; 262 } 263 case KEY_TYPE_btree_ptr_v2: { 264 struct bkey_s_c_btree_ptr_v2 e = bkey_s_c_to_btree_ptr_v2(k); 265 266 return (struct bkey_ptrs_c) { 267 to_entry(&e.v->start[0]), 268 to_entry(extent_entry_last(e)) 269 }; 270 } 271 default: 272 return (struct bkey_ptrs_c) { NULL, NULL }; 273 } 274 } 275 276 static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k) 277 { 278 struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k.s_c); 279 280 return (struct bkey_ptrs) { 281 (void *) p.start, 282 (void *) p.end 283 }; 284 } 285 286 #define __bkey_extent_entry_for_each_from(_start, _end, _entry) \ 287 for ((_entry) = (_start); \ 288 (_entry) < (_end); \ 289 (_entry) = extent_entry_next_safe(_entry, _end)) 290 291 #define __bkey_ptr_next(_ptr, _end) \ 292 ({ \ 293 typeof(_end) _entry; \ 294 \ 295 __bkey_extent_entry_for_each_from(to_entry(_ptr), _end, _entry) \ 296 if (extent_entry_is_ptr(_entry)) \ 297 break; \ 298 \ 299 _entry < (_end) ? entry_to_ptr(_entry) : NULL; \ 300 }) 301 302 #define bkey_extent_entry_for_each_from(_p, _entry, _start) \ 303 __bkey_extent_entry_for_each_from(_start, (_p).end, _entry) 304 305 #define bkey_extent_entry_for_each(_p, _entry) \ 306 bkey_extent_entry_for_each_from(_p, _entry, _p.start) 307 308 #define __bkey_for_each_ptr(_start, _end, _ptr) \ 309 for (typeof(_start) (_ptr) = (_start); \ 310 ((_ptr) = __bkey_ptr_next(_ptr, _end)); \ 311 (_ptr)++) 312 313 #define bkey_ptr_next(_p, _ptr) \ 314 __bkey_ptr_next(_ptr, (_p).end) 315 316 #define bkey_for_each_ptr(_p, _ptr) \ 317 __bkey_for_each_ptr(&(_p).start->ptr, (_p).end, _ptr) 318 319 #define __bkey_ptr_next_decode(_k, _end, _ptr, _entry) \ 320 ({ \ 321 __label__ out; \ 322 \ 323 (_ptr).has_ec = false; \ 324 (_ptr).do_ec_reconstruct = false; \ 325 (_ptr).crc_retry_nr = 0; \ 326 \ 327 __bkey_extent_entry_for_each_from(_entry, _end, _entry) \ 328 switch (__extent_entry_type(_entry)) { \ 329 case BCH_EXTENT_ENTRY_ptr: \ 330 (_ptr).ptr = _entry->ptr; \ 331 goto out; \ 332 case BCH_EXTENT_ENTRY_crc32: \ 333 case BCH_EXTENT_ENTRY_crc64: \ 334 case BCH_EXTENT_ENTRY_crc128: \ 335 (_ptr).crc = bch2_extent_crc_unpack(_k, \ 336 entry_to_crc(_entry)); \ 337 break; \ 338 case BCH_EXTENT_ENTRY_stripe_ptr: \ 339 (_ptr).ec = _entry->stripe_ptr; \ 340 (_ptr).has_ec = true; \ 341 break; \ 342 default: \ 343 /* nothing */ \ 344 break; \ 345 } \ 346 out: \ 347 _entry < (_end); \ 348 }) 349 350 #define __bkey_for_each_ptr_decode(_k, _start, _end, _ptr, _entry) \ 351 for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL), \ 352 (_entry) = _start; \ 353 __bkey_ptr_next_decode(_k, _end, _ptr, _entry); \ 354 (_entry) = extent_entry_next_safe(_entry, _end)) 355 356 #define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry) \ 357 __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end, \ 358 _ptr, _entry) 359 360 #define bkey_crc_next(_k, _end, _crc, _iter) \ 361 ({ \ 362 __bkey_extent_entry_for_each_from(_iter, _end, _iter) \ 363 if (extent_entry_is_crc(_iter)) { \ 364 (_crc) = bch2_extent_crc_unpack(_k, \ 365 entry_to_crc(_iter)); \ 366 break; \ 367 } \ 368 \ 369 (_iter) < (_end); \ 370 }) 371 372 #define __bkey_for_each_crc(_k, _start, _end, _crc, _iter) \ 373 for ((_crc) = bch2_extent_crc_unpack(_k, NULL), \ 374 (_iter) = (_start); \ 375 bkey_crc_next(_k, _end, _crc, _iter); \ 376 (_iter) = extent_entry_next(_iter)) 377 378 #define bkey_for_each_crc(_k, _p, _crc, _iter) \ 379 __bkey_for_each_crc(_k, (_p).start, (_p).end, _crc, _iter) 380 381 /* Iterate over pointers in KEY_TYPE_extent: */ 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 393 /* utility code common to all keys with pointers: */ 394 395 void bch2_io_failures_to_text(struct printbuf *, struct bch_fs *, 396 struct bch_io_failures *); 397 struct bch_dev_io_failures *bch2_dev_io_failures(struct bch_io_failures *, 398 unsigned); 399 void bch2_mark_io_failure(struct bch_io_failures *, 400 struct extent_ptr_decoded *, bool); 401 void bch2_mark_btree_validate_failure(struct bch_io_failures *, unsigned); 402 int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, 403 struct bch_io_failures *, 404 struct extent_ptr_decoded *, int); 405 406 /* KEY_TYPE_btree_ptr: */ 407 408 int bch2_btree_ptr_validate(struct bch_fs *, struct bkey_s_c, 409 struct bkey_validate_context); 410 void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, 411 struct bkey_s_c); 412 413 int bch2_btree_ptr_v2_validate(struct bch_fs *, struct bkey_s_c, 414 struct bkey_validate_context); 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_validate = bch2_btree_ptr_validate, \ 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_validate = bch2_btree_ptr_v2_validate, \ 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_validate = bch2_bkey_ptrs_validate, \ 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_validate(struct bch_fs *, struct bkey_s_c, 451 struct bkey_validate_context); 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_validate = bch2_reservation_validate, \ 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 const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned); 611 612 static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsigned dev) 613 { 614 return (void *) bch2_bkey_has_device_c(k.s_c, dev); 615 } 616 617 bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); 618 619 void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *); 620 621 static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr) 622 { 623 struct bch_extent_ptr *dest; 624 625 EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev)); 626 627 switch (k->k.type) { 628 case KEY_TYPE_btree_ptr: 629 case KEY_TYPE_btree_ptr_v2: 630 case KEY_TYPE_extent: 631 EBUG_ON(bkey_val_u64s(&k->k) >= BKEY_EXTENT_VAL_U64s_MAX); 632 633 ptr.type = 1 << BCH_EXTENT_ENTRY_ptr; 634 dest = (struct bch_extent_ptr *)((void *) &k->v + bkey_val_bytes(&k->k)); 635 *dest = ptr; 636 k->k.u64s++; 637 break; 638 default: 639 BUG(); 640 } 641 } 642 643 void bch2_extent_ptr_decoded_append(struct bkey_i *, 644 struct extent_ptr_decoded *); 645 void bch2_bkey_drop_ptr_noerror(struct bkey_s, struct bch_extent_ptr *); 646 void bch2_bkey_drop_ptr(struct bkey_s, struct bch_extent_ptr *); 647 648 void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned); 649 void bch2_bkey_drop_device(struct bkey_s, unsigned); 650 651 #define bch2_bkey_drop_ptrs_noerror(_k, _ptr, _cond) \ 652 do { \ 653 __label__ _again; \ 654 struct bkey_ptrs _ptrs; \ 655 _again: \ 656 _ptrs = bch2_bkey_ptrs(_k); \ 657 \ 658 bkey_for_each_ptr(_ptrs, _ptr) \ 659 if (_cond) { \ 660 bch2_bkey_drop_ptr_noerror(_k, _ptr); \ 661 goto _again; \ 662 } \ 663 } while (0) 664 665 #define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \ 666 do { \ 667 __label__ _again; \ 668 struct bkey_ptrs _ptrs; \ 669 _again: \ 670 _ptrs = bch2_bkey_ptrs(_k); \ 671 \ 672 bkey_for_each_ptr(_ptrs, _ptr) \ 673 if (_cond) { \ 674 bch2_bkey_drop_ptr(_k, _ptr); \ 675 goto _again; \ 676 } \ 677 } while (0) 678 679 bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c, 680 struct bch_extent_ptr, u64); 681 bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c); 682 struct bch_extent_ptr * 683 bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s); 684 685 void bch2_extent_ptr_set_cached(struct bch_fs *, struct bch_io_opts *, 686 struct bkey_s, struct bch_extent_ptr *); 687 688 bool bch2_extent_normalize_by_opts(struct bch_fs *, struct bch_io_opts *, struct bkey_s); 689 bool bch2_extent_normalize(struct bch_fs *, struct bkey_s); 690 691 void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *, const struct bch_extent_ptr *); 692 void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, 693 struct bkey_s_c); 694 int bch2_bkey_ptrs_validate(struct bch_fs *, struct bkey_s_c, 695 struct bkey_validate_context); 696 697 static inline bool bch2_extent_ptr_eq(struct bch_extent_ptr ptr1, 698 struct bch_extent_ptr ptr2) 699 { 700 return (ptr1.cached == ptr2.cached && 701 ptr1.unwritten == ptr2.unwritten && 702 ptr1.offset == ptr2.offset && 703 ptr1.dev == ptr2.dev && 704 ptr1.gen == ptr2.gen); 705 } 706 707 void bch2_ptr_swab(struct bkey_s); 708 709 /* Generic extent code: */ 710 711 enum bch_extent_overlap { 712 BCH_EXTENT_OVERLAP_ALL = 0, 713 BCH_EXTENT_OVERLAP_BACK = 1, 714 BCH_EXTENT_OVERLAP_FRONT = 2, 715 BCH_EXTENT_OVERLAP_MIDDLE = 3, 716 }; 717 718 /* Returns how k overlaps with m */ 719 static inline enum bch_extent_overlap bch2_extent_overlap(const struct bkey *k, 720 const struct bkey *m) 721 { 722 int cmp1 = bkey_lt(k->p, m->p); 723 int cmp2 = bkey_gt(bkey_start_pos(k), bkey_start_pos(m)); 724 725 return (cmp1 << 1) + cmp2; 726 } 727 728 int bch2_cut_front_s(struct bpos, struct bkey_s); 729 int bch2_cut_back_s(struct bpos, struct bkey_s); 730 731 static inline void bch2_cut_front(struct bpos where, struct bkey_i *k) 732 { 733 bch2_cut_front_s(where, bkey_i_to_s(k)); 734 } 735 736 static inline void bch2_cut_back(struct bpos where, struct bkey_i *k) 737 { 738 bch2_cut_back_s(where, bkey_i_to_s(k)); 739 } 740 741 /** 742 * bch_key_resize - adjust size of @k 743 * 744 * bkey_start_offset(k) will be preserved, modifies where the extent ends 745 */ 746 static inline void bch2_key_resize(struct bkey *k, unsigned new_size) 747 { 748 k->p.offset -= k->size; 749 k->p.offset += new_size; 750 k->size = new_size; 751 } 752 753 static inline u64 bch2_bkey_extent_ptrs_flags(struct bkey_ptrs_c ptrs) 754 { 755 if (ptrs.start != ptrs.end && 756 extent_entry_type(ptrs.start) == BCH_EXTENT_ENTRY_flags) 757 return ptrs.start->flags.flags; 758 return 0; 759 } 760 761 static inline u64 bch2_bkey_extent_flags(struct bkey_s_c k) 762 { 763 return bch2_bkey_extent_ptrs_flags(bch2_bkey_ptrs_c(k)); 764 } 765 766 int bch2_bkey_extent_flags_set(struct bch_fs *, struct bkey_i *, u64); 767 768 #endif /* _BCACHEFS_EXTENTS_H */ 769