11c6fdbd8SKent Overstreet /* SPDX-License-Identifier: GPL-2.0 */ 21c6fdbd8SKent Overstreet #ifndef _BCACHEFS_EXTENTS_H 31c6fdbd8SKent Overstreet #define _BCACHEFS_EXTENTS_H 41c6fdbd8SKent Overstreet 51c6fdbd8SKent Overstreet #include "bcachefs.h" 61c6fdbd8SKent Overstreet #include "bkey.h" 71c6fdbd8SKent Overstreet #include "extents_types.h" 81c6fdbd8SKent Overstreet 91c6fdbd8SKent Overstreet struct bch_fs; 100dc17247SKent Overstreet struct btree_trans; 111c6fdbd8SKent Overstreet 1226609b61SKent Overstreet /* extent entries: */ 131c6fdbd8SKent Overstreet 1499aaf570SKent Overstreet #define extent_entry_last(_e) \ 1599aaf570SKent Overstreet ((typeof(&(_e).v->start[0])) bkey_val_end(_e)) 161c6fdbd8SKent Overstreet 1726609b61SKent Overstreet #define entry_to_ptr(_entry) \ 1826609b61SKent Overstreet ({ \ 1926609b61SKent Overstreet EBUG_ON((_entry) && !extent_entry_is_ptr(_entry)); \ 2026609b61SKent Overstreet \ 2126609b61SKent Overstreet __builtin_choose_expr( \ 2226609b61SKent Overstreet type_is_exact(_entry, const union bch_extent_entry *), \ 2326609b61SKent Overstreet (const struct bch_extent_ptr *) (_entry), \ 2426609b61SKent Overstreet (struct bch_extent_ptr *) (_entry)); \ 2526609b61SKent Overstreet }) 261c6fdbd8SKent Overstreet 2726609b61SKent Overstreet /* downcast, preserves const */ 2826609b61SKent Overstreet #define to_entry(_entry) \ 2926609b61SKent Overstreet ({ \ 3026609b61SKent Overstreet BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) && \ 3126609b61SKent Overstreet !type_is(_entry, struct bch_extent_ptr *) && \ 3226609b61SKent Overstreet !type_is(_entry, struct bch_extent_stripe_ptr *)); \ 3326609b61SKent Overstreet \ 3426609b61SKent Overstreet __builtin_choose_expr( \ 3526609b61SKent Overstreet (type_is_exact(_entry, const union bch_extent_crc *) || \ 3626609b61SKent Overstreet type_is_exact(_entry, const struct bch_extent_ptr *) ||\ 3726609b61SKent Overstreet type_is_exact(_entry, const struct bch_extent_stripe_ptr *)),\ 3826609b61SKent Overstreet (const union bch_extent_entry *) (_entry), \ 3926609b61SKent Overstreet (union bch_extent_entry *) (_entry)); \ 4026609b61SKent Overstreet }) 411c6fdbd8SKent Overstreet 424de77495SKent Overstreet #define extent_entry_next(_entry) \ 434de77495SKent Overstreet ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry))) 444de77495SKent Overstreet 451c6fdbd8SKent Overstreet static inline unsigned 461c6fdbd8SKent Overstreet __extent_entry_type(const union bch_extent_entry *e) 471c6fdbd8SKent Overstreet { 481c6fdbd8SKent Overstreet return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX; 491c6fdbd8SKent Overstreet } 501c6fdbd8SKent Overstreet 511c6fdbd8SKent Overstreet static inline enum bch_extent_entry_type 521c6fdbd8SKent Overstreet extent_entry_type(const union bch_extent_entry *e) 531c6fdbd8SKent Overstreet { 541c6fdbd8SKent Overstreet int ret = __ffs(e->type); 551c6fdbd8SKent Overstreet 561c6fdbd8SKent Overstreet EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX); 571c6fdbd8SKent Overstreet 581c6fdbd8SKent Overstreet return ret; 591c6fdbd8SKent Overstreet } 601c6fdbd8SKent Overstreet 611c6fdbd8SKent Overstreet static inline size_t extent_entry_bytes(const union bch_extent_entry *entry) 621c6fdbd8SKent Overstreet { 631c6fdbd8SKent Overstreet switch (extent_entry_type(entry)) { 64abce30b7SKent Overstreet #define x(f, n) \ 65abce30b7SKent Overstreet case BCH_EXTENT_ENTRY_##f: \ 66abce30b7SKent Overstreet return sizeof(struct bch_extent_##f); 67abce30b7SKent Overstreet BCH_EXTENT_ENTRY_TYPES() 68abce30b7SKent Overstreet #undef x 691c6fdbd8SKent Overstreet default: 701c6fdbd8SKent Overstreet BUG(); 711c6fdbd8SKent Overstreet } 721c6fdbd8SKent Overstreet } 731c6fdbd8SKent Overstreet 741c6fdbd8SKent Overstreet static inline size_t extent_entry_u64s(const union bch_extent_entry *entry) 751c6fdbd8SKent Overstreet { 761c6fdbd8SKent Overstreet return extent_entry_bytes(entry) / sizeof(u64); 771c6fdbd8SKent Overstreet } 781c6fdbd8SKent Overstreet 791c6fdbd8SKent Overstreet static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) 801c6fdbd8SKent Overstreet { 811742237bSKent Overstreet switch (extent_entry_type(e)) { 821742237bSKent Overstreet case BCH_EXTENT_ENTRY_ptr: 831742237bSKent Overstreet return true; 841742237bSKent Overstreet default: 851742237bSKent Overstreet return false; 861742237bSKent Overstreet } 871c6fdbd8SKent Overstreet } 881c6fdbd8SKent Overstreet 891c6fdbd8SKent Overstreet static inline bool extent_entry_is_crc(const union bch_extent_entry *e) 901c6fdbd8SKent Overstreet { 911742237bSKent Overstreet switch (extent_entry_type(e)) { 921742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc32: 931742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc64: 941742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc128: 951742237bSKent Overstreet return true; 961742237bSKent Overstreet default: 971742237bSKent Overstreet return false; 981742237bSKent Overstreet } 991c6fdbd8SKent Overstreet } 1001c6fdbd8SKent Overstreet 1011c6fdbd8SKent Overstreet union bch_extent_crc { 1021c6fdbd8SKent Overstreet u8 type; 1031c6fdbd8SKent Overstreet struct bch_extent_crc32 crc32; 1041c6fdbd8SKent Overstreet struct bch_extent_crc64 crc64; 1051c6fdbd8SKent Overstreet struct bch_extent_crc128 crc128; 1061c6fdbd8SKent Overstreet }; 1071c6fdbd8SKent Overstreet 1081c6fdbd8SKent Overstreet #define __entry_to_crc(_entry) \ 1091c6fdbd8SKent Overstreet __builtin_choose_expr( \ 1101c6fdbd8SKent Overstreet type_is_exact(_entry, const union bch_extent_entry *), \ 1111c6fdbd8SKent Overstreet (const union bch_extent_crc *) (_entry), \ 1121c6fdbd8SKent Overstreet (union bch_extent_crc *) (_entry)) 1131c6fdbd8SKent Overstreet 1141c6fdbd8SKent Overstreet #define entry_to_crc(_entry) \ 1151c6fdbd8SKent Overstreet ({ \ 1161c6fdbd8SKent Overstreet EBUG_ON((_entry) && !extent_entry_is_crc(_entry)); \ 1171c6fdbd8SKent Overstreet \ 1181c6fdbd8SKent Overstreet __entry_to_crc(_entry); \ 1191c6fdbd8SKent Overstreet }) 1201c6fdbd8SKent Overstreet 1211c6fdbd8SKent Overstreet static inline struct bch_extent_crc_unpacked 1221c6fdbd8SKent Overstreet bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc) 1231c6fdbd8SKent Overstreet { 1241c6fdbd8SKent Overstreet #define common_fields(_crc) \ 1251c6fdbd8SKent Overstreet .csum_type = _crc.csum_type, \ 1261c6fdbd8SKent Overstreet .compression_type = _crc.compression_type, \ 1271c6fdbd8SKent Overstreet .compressed_size = _crc._compressed_size + 1, \ 1281c6fdbd8SKent Overstreet .uncompressed_size = _crc._uncompressed_size + 1, \ 1291c6fdbd8SKent Overstreet .offset = _crc.offset, \ 1301c6fdbd8SKent Overstreet .live_size = k->size 1311c6fdbd8SKent Overstreet 132642d66d1SKent Overstreet if (!crc) 1331c6fdbd8SKent Overstreet return (struct bch_extent_crc_unpacked) { 1341c6fdbd8SKent Overstreet .compressed_size = k->size, 1351c6fdbd8SKent Overstreet .uncompressed_size = k->size, 1361c6fdbd8SKent Overstreet .live_size = k->size, 1371c6fdbd8SKent Overstreet }; 138642d66d1SKent Overstreet 139642d66d1SKent Overstreet switch (extent_entry_type(to_entry(crc))) { 140642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc32: { 1411c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1421c6fdbd8SKent Overstreet common_fields(crc->crc32), 1431c6fdbd8SKent Overstreet }; 1441c6fdbd8SKent Overstreet 1451c6fdbd8SKent Overstreet *((__le32 *) &ret.csum.lo) = crc->crc32.csum; 1461c6fdbd8SKent Overstreet 1471c6fdbd8SKent Overstreet memcpy(&ret.csum.lo, &crc->crc32.csum, 1481c6fdbd8SKent Overstreet sizeof(crc->crc32.csum)); 1491c6fdbd8SKent Overstreet 1501c6fdbd8SKent Overstreet return ret; 1511c6fdbd8SKent Overstreet } 152642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc64: { 1531c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1541c6fdbd8SKent Overstreet common_fields(crc->crc64), 1551c6fdbd8SKent Overstreet .nonce = crc->crc64.nonce, 1561c6fdbd8SKent Overstreet .csum.lo = (__force __le64) crc->crc64.csum_lo, 1571c6fdbd8SKent Overstreet }; 1581c6fdbd8SKent Overstreet 1591c6fdbd8SKent Overstreet *((__le16 *) &ret.csum.hi) = crc->crc64.csum_hi; 1601c6fdbd8SKent Overstreet 1611c6fdbd8SKent Overstreet return ret; 1621c6fdbd8SKent Overstreet } 163642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc128: { 1641c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1651c6fdbd8SKent Overstreet common_fields(crc->crc128), 1661c6fdbd8SKent Overstreet .nonce = crc->crc128.nonce, 1671c6fdbd8SKent Overstreet .csum = crc->crc128.csum, 1681c6fdbd8SKent Overstreet }; 1691c6fdbd8SKent Overstreet 1701c6fdbd8SKent Overstreet return ret; 1711c6fdbd8SKent Overstreet } 1721c6fdbd8SKent Overstreet default: 1731c6fdbd8SKent Overstreet BUG(); 1741c6fdbd8SKent Overstreet } 1751c6fdbd8SKent Overstreet #undef common_fields 1761c6fdbd8SKent Overstreet } 1771c6fdbd8SKent Overstreet 178ab05de4cSKent Overstreet static inline bool crc_is_compressed(struct bch_extent_crc_unpacked crc) 179ab05de4cSKent Overstreet { 180ab05de4cSKent Overstreet return (crc.compression_type != BCH_COMPRESSION_TYPE_none && 181ab05de4cSKent Overstreet crc.compression_type != BCH_COMPRESSION_TYPE_incompressible); 182ab05de4cSKent Overstreet } 183ab05de4cSKent Overstreet 18426609b61SKent Overstreet /* bkey_ptrs: generically over any key type that has ptrs */ 18526609b61SKent Overstreet 18626609b61SKent Overstreet struct bkey_ptrs_c { 18726609b61SKent Overstreet const union bch_extent_entry *start; 18826609b61SKent Overstreet const union bch_extent_entry *end; 18926609b61SKent Overstreet }; 19026609b61SKent Overstreet 19126609b61SKent Overstreet struct bkey_ptrs { 19226609b61SKent Overstreet union bch_extent_entry *start; 19326609b61SKent Overstreet union bch_extent_entry *end; 19426609b61SKent Overstreet }; 19526609b61SKent Overstreet 1964de77495SKent Overstreet static inline struct bkey_ptrs_c bch2_bkey_ptrs_c(struct bkey_s_c k) 1974de77495SKent Overstreet { 1984de77495SKent Overstreet switch (k.k->type) { 1994de77495SKent Overstreet case KEY_TYPE_btree_ptr: { 2004de77495SKent Overstreet struct bkey_s_c_btree_ptr e = bkey_s_c_to_btree_ptr(k); 2014de77495SKent Overstreet return (struct bkey_ptrs_c) { 2024de77495SKent Overstreet to_entry(&e.v->start[0]), 2034de77495SKent Overstreet to_entry(extent_entry_last(e)) 2044de77495SKent Overstreet }; 2054de77495SKent Overstreet } 2064de77495SKent Overstreet case KEY_TYPE_extent: { 2074de77495SKent Overstreet struct bkey_s_c_extent e = bkey_s_c_to_extent(k); 2084de77495SKent Overstreet return (struct bkey_ptrs_c) { 2094de77495SKent Overstreet e.v->start, 2104de77495SKent Overstreet extent_entry_last(e) 2114de77495SKent Overstreet }; 2124de77495SKent Overstreet } 2134de77495SKent Overstreet case KEY_TYPE_stripe: { 2144de77495SKent Overstreet struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); 2154de77495SKent Overstreet return (struct bkey_ptrs_c) { 2164de77495SKent Overstreet to_entry(&s.v->ptrs[0]), 2174de77495SKent Overstreet to_entry(&s.v->ptrs[s.v->nr_blocks]), 2184de77495SKent Overstreet }; 2194de77495SKent Overstreet } 2204de77495SKent Overstreet case KEY_TYPE_reflink_v: { 2214de77495SKent Overstreet struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k); 2221c6fdbd8SKent Overstreet 2234de77495SKent Overstreet return (struct bkey_ptrs_c) { 2244de77495SKent Overstreet r.v->start, 2254de77495SKent Overstreet bkey_val_end(r), 2264de77495SKent Overstreet }; 2274de77495SKent Overstreet } 228548b3d20SKent Overstreet case KEY_TYPE_btree_ptr_v2: { 229548b3d20SKent Overstreet struct bkey_s_c_btree_ptr_v2 e = bkey_s_c_to_btree_ptr_v2(k); 230548b3d20SKent Overstreet return (struct bkey_ptrs_c) { 231548b3d20SKent Overstreet to_entry(&e.v->start[0]), 232548b3d20SKent Overstreet to_entry(extent_entry_last(e)) 233548b3d20SKent Overstreet }; 234548b3d20SKent Overstreet } 2354de77495SKent Overstreet default: 2364de77495SKent Overstreet return (struct bkey_ptrs_c) { NULL, NULL }; 2374de77495SKent Overstreet } 2384de77495SKent Overstreet } 2394de77495SKent Overstreet 2404de77495SKent Overstreet static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k) 2414de77495SKent Overstreet { 2424de77495SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k.s_c); 2434de77495SKent Overstreet 2444de77495SKent Overstreet return (struct bkey_ptrs) { 2454de77495SKent Overstreet (void *) p.start, 2464de77495SKent Overstreet (void *) p.end 2474de77495SKent Overstreet }; 2484de77495SKent Overstreet } 2491c6fdbd8SKent Overstreet 25026609b61SKent Overstreet #define __bkey_extent_entry_for_each_from(_start, _end, _entry) \ 25126609b61SKent Overstreet for ((_entry) = (_start); \ 25226609b61SKent Overstreet (_entry) < (_end); \ 25326609b61SKent Overstreet (_entry) = extent_entry_next(_entry)) 2541c6fdbd8SKent Overstreet 25526609b61SKent Overstreet #define __bkey_ptr_next(_ptr, _end) \ 25626609b61SKent Overstreet ({ \ 25726609b61SKent Overstreet typeof(_end) _entry; \ 25826609b61SKent Overstreet \ 25926609b61SKent Overstreet __bkey_extent_entry_for_each_from(to_entry(_ptr), _end, _entry) \ 26026609b61SKent Overstreet if (extent_entry_is_ptr(_entry)) \ 26126609b61SKent Overstreet break; \ 26226609b61SKent Overstreet \ 26326609b61SKent Overstreet _entry < (_end) ? entry_to_ptr(_entry) : NULL; \ 26426609b61SKent Overstreet }) 26526609b61SKent Overstreet 26626609b61SKent Overstreet #define bkey_extent_entry_for_each_from(_p, _entry, _start) \ 26726609b61SKent Overstreet __bkey_extent_entry_for_each_from(_start, (_p).end, _entry) 26826609b61SKent Overstreet 26926609b61SKent Overstreet #define bkey_extent_entry_for_each(_p, _entry) \ 27026609b61SKent Overstreet bkey_extent_entry_for_each_from(_p, _entry, _p.start) 27126609b61SKent Overstreet 27226609b61SKent Overstreet #define __bkey_for_each_ptr(_start, _end, _ptr) \ 27326609b61SKent Overstreet for ((_ptr) = (_start); \ 27426609b61SKent Overstreet ((_ptr) = __bkey_ptr_next(_ptr, _end)); \ 27526609b61SKent Overstreet (_ptr)++) 27626609b61SKent Overstreet 27726609b61SKent Overstreet #define bkey_ptr_next(_p, _ptr) \ 27826609b61SKent Overstreet __bkey_ptr_next(_ptr, (_p).end) 27926609b61SKent Overstreet 28026609b61SKent Overstreet #define bkey_for_each_ptr(_p, _ptr) \ 28126609b61SKent Overstreet __bkey_for_each_ptr(&(_p).start->ptr, (_p).end, _ptr) 28226609b61SKent Overstreet 28326609b61SKent Overstreet #define __bkey_ptr_next_decode(_k, _end, _ptr, _entry) \ 28426609b61SKent Overstreet ({ \ 28526609b61SKent Overstreet __label__ out; \ 28626609b61SKent Overstreet \ 28726609b61SKent Overstreet (_ptr).idx = 0; \ 28837954a27SKent Overstreet (_ptr).has_ec = false; \ 28926609b61SKent Overstreet \ 29026609b61SKent Overstreet __bkey_extent_entry_for_each_from(_entry, _end, _entry) \ 29126609b61SKent Overstreet switch (extent_entry_type(_entry)) { \ 29226609b61SKent Overstreet case BCH_EXTENT_ENTRY_ptr: \ 29326609b61SKent Overstreet (_ptr).ptr = _entry->ptr; \ 29426609b61SKent Overstreet goto out; \ 29526609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc32: \ 29626609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc64: \ 29726609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc128: \ 29826609b61SKent Overstreet (_ptr).crc = bch2_extent_crc_unpack(_k, \ 29926609b61SKent Overstreet entry_to_crc(_entry)); \ 30026609b61SKent Overstreet break; \ 30126609b61SKent Overstreet case BCH_EXTENT_ENTRY_stripe_ptr: \ 30237954a27SKent Overstreet (_ptr).ec = _entry->stripe_ptr; \ 30337954a27SKent Overstreet (_ptr).has_ec = true; \ 30426609b61SKent Overstreet break; \ 30526609b61SKent Overstreet } \ 30626609b61SKent Overstreet out: \ 30726609b61SKent Overstreet _entry < (_end); \ 30826609b61SKent Overstreet }) 30926609b61SKent Overstreet 31026609b61SKent Overstreet #define __bkey_for_each_ptr_decode(_k, _start, _end, _ptr, _entry) \ 31126609b61SKent Overstreet for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL), \ 31226609b61SKent Overstreet (_entry) = _start; \ 31326609b61SKent Overstreet __bkey_ptr_next_decode(_k, _end, _ptr, _entry); \ 31426609b61SKent Overstreet (_entry) = extent_entry_next(_entry)) 31526609b61SKent Overstreet 31626609b61SKent Overstreet #define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry) \ 31726609b61SKent Overstreet __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end, \ 31826609b61SKent Overstreet _ptr, _entry) 31926609b61SKent Overstreet 32099aaf570SKent Overstreet #define bkey_crc_next(_k, _start, _end, _crc, _iter) \ 32199aaf570SKent Overstreet ({ \ 32299aaf570SKent Overstreet __bkey_extent_entry_for_each_from(_iter, _end, _iter) \ 32399aaf570SKent Overstreet if (extent_entry_is_crc(_iter)) { \ 32499aaf570SKent Overstreet (_crc) = bch2_extent_crc_unpack(_k, \ 32599aaf570SKent Overstreet entry_to_crc(_iter)); \ 32699aaf570SKent Overstreet break; \ 32799aaf570SKent Overstreet } \ 32899aaf570SKent Overstreet \ 32999aaf570SKent Overstreet (_iter) < (_end); \ 33099aaf570SKent Overstreet }) 33199aaf570SKent Overstreet 33299aaf570SKent Overstreet #define __bkey_for_each_crc(_k, _start, _end, _crc, _iter) \ 33399aaf570SKent Overstreet for ((_crc) = bch2_extent_crc_unpack(_k, NULL), \ 33499aaf570SKent Overstreet (_iter) = (_start); \ 33599aaf570SKent Overstreet bkey_crc_next(_k, _start, _end, _crc, _iter); \ 33699aaf570SKent Overstreet (_iter) = extent_entry_next(_iter)) 33799aaf570SKent Overstreet 33899aaf570SKent Overstreet #define bkey_for_each_crc(_k, _p, _crc, _iter) \ 33999aaf570SKent Overstreet __bkey_for_each_crc(_k, (_p).start, (_p).end, _crc, _iter) 34099aaf570SKent Overstreet 3414de77495SKent Overstreet /* Iterate over pointers in KEY_TYPE_extent: */ 3424de77495SKent Overstreet 3434de77495SKent Overstreet #define extent_for_each_entry_from(_e, _entry, _start) \ 3444de77495SKent Overstreet __bkey_extent_entry_for_each_from(_start, \ 3454de77495SKent Overstreet extent_entry_last(_e),_entry) 3464de77495SKent Overstreet 3474de77495SKent Overstreet #define extent_for_each_entry(_e, _entry) \ 3484de77495SKent Overstreet extent_for_each_entry_from(_e, _entry, (_e).v->start) 3494de77495SKent Overstreet 3504de77495SKent Overstreet #define extent_ptr_next(_e, _ptr) \ 3514de77495SKent Overstreet __bkey_ptr_next(_ptr, extent_entry_last(_e)) 3524de77495SKent Overstreet 3534de77495SKent Overstreet #define extent_for_each_ptr(_e, _ptr) \ 3544de77495SKent Overstreet __bkey_for_each_ptr(&(_e).v->start->ptr, extent_entry_last(_e), _ptr) 3554de77495SKent Overstreet 3564de77495SKent Overstreet #define extent_for_each_ptr_decode(_e, _ptr, _entry) \ 3574de77495SKent Overstreet __bkey_for_each_ptr_decode((_e).k, (_e).v->start, \ 3584de77495SKent Overstreet extent_entry_last(_e), _ptr, _entry) 3594de77495SKent Overstreet 36026609b61SKent Overstreet /* utility code common to all keys with pointers: */ 36126609b61SKent Overstreet 3624de77495SKent Overstreet void bch2_mark_io_failure(struct bch_io_failures *, 3634de77495SKent Overstreet struct extent_ptr_decoded *); 3644de77495SKent Overstreet int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, 3654de77495SKent Overstreet struct bch_io_failures *, 3664de77495SKent Overstreet struct extent_ptr_decoded *); 36776426098SKent Overstreet 3684de77495SKent Overstreet /* KEY_TYPE_btree_ptr: */ 3694de77495SKent Overstreet 3704de77495SKent Overstreet const char *bch2_btree_ptr_invalid(const struct bch_fs *, struct bkey_s_c); 3714de77495SKent Overstreet void bch2_btree_ptr_debugcheck(struct bch_fs *, struct bkey_s_c); 3724de77495SKent Overstreet void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, 3734de77495SKent Overstreet struct bkey_s_c); 374*59a38a38SKent Overstreet 375*59a38a38SKent Overstreet void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, 376*59a38a38SKent Overstreet struct bkey_s_c); 37739fb2983SKent Overstreet void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned, 37839fb2983SKent Overstreet int, struct bkey_s); 3794de77495SKent Overstreet 3804de77495SKent Overstreet #define bch2_bkey_ops_btree_ptr (struct bkey_ops) { \ 3814de77495SKent Overstreet .key_invalid = bch2_btree_ptr_invalid, \ 3824de77495SKent Overstreet .key_debugcheck = bch2_btree_ptr_debugcheck, \ 3834de77495SKent Overstreet .val_to_text = bch2_btree_ptr_to_text, \ 3844de77495SKent Overstreet .swab = bch2_ptr_swab, \ 38576426098SKent Overstreet } 3864de77495SKent Overstreet 387548b3d20SKent Overstreet #define bch2_bkey_ops_btree_ptr_v2 (struct bkey_ops) { \ 388548b3d20SKent Overstreet .key_invalid = bch2_btree_ptr_invalid, \ 389548b3d20SKent Overstreet .key_debugcheck = bch2_btree_ptr_debugcheck, \ 390*59a38a38SKent Overstreet .val_to_text = bch2_btree_ptr_v2_to_text, \ 391548b3d20SKent Overstreet .swab = bch2_ptr_swab, \ 39239fb2983SKent Overstreet .compat = bch2_btree_ptr_v2_compat, \ 393548b3d20SKent Overstreet } 394548b3d20SKent Overstreet 3954de77495SKent Overstreet /* KEY_TYPE_extent: */ 3964de77495SKent Overstreet 3974de77495SKent Overstreet const char *bch2_extent_invalid(const struct bch_fs *, struct bkey_s_c); 3984de77495SKent Overstreet void bch2_extent_debugcheck(struct bch_fs *, struct bkey_s_c); 3994de77495SKent Overstreet void bch2_extent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 4004de77495SKent Overstreet enum merge_result bch2_extent_merge(struct bch_fs *, 4014de77495SKent Overstreet struct bkey_s, struct bkey_s); 4024de77495SKent Overstreet 4034de77495SKent Overstreet #define bch2_bkey_ops_extent (struct bkey_ops) { \ 4044de77495SKent Overstreet .key_invalid = bch2_extent_invalid, \ 4054de77495SKent Overstreet .key_debugcheck = bch2_extent_debugcheck, \ 4064de77495SKent Overstreet .val_to_text = bch2_extent_to_text, \ 4074de77495SKent Overstreet .swab = bch2_ptr_swab, \ 4084de77495SKent Overstreet .key_normalize = bch2_extent_normalize, \ 4094de77495SKent Overstreet .key_merge = bch2_extent_merge, \ 4104de77495SKent Overstreet } 4114de77495SKent Overstreet 4124de77495SKent Overstreet /* KEY_TYPE_reservation: */ 4134de77495SKent Overstreet 4144de77495SKent Overstreet const char *bch2_reservation_invalid(const struct bch_fs *, struct bkey_s_c); 4154de77495SKent Overstreet void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 4164de77495SKent Overstreet enum merge_result bch2_reservation_merge(struct bch_fs *, 4174de77495SKent Overstreet struct bkey_s, struct bkey_s); 4184de77495SKent Overstreet 4194de77495SKent Overstreet #define bch2_bkey_ops_reservation (struct bkey_ops) { \ 4204de77495SKent Overstreet .key_invalid = bch2_reservation_invalid, \ 4214de77495SKent Overstreet .val_to_text = bch2_reservation_to_text, \ 4224de77495SKent Overstreet .key_merge = bch2_reservation_merge, \ 4234de77495SKent Overstreet } 4244de77495SKent Overstreet 4254de77495SKent Overstreet /* Extent checksum entries: */ 4264de77495SKent Overstreet 4274de77495SKent Overstreet bool bch2_can_narrow_extent_crcs(struct bkey_s_c, 4284de77495SKent Overstreet struct bch_extent_crc_unpacked); 4294de77495SKent Overstreet bool bch2_bkey_narrow_crcs(struct bkey_i *, struct bch_extent_crc_unpacked); 4304de77495SKent Overstreet void bch2_extent_crc_append(struct bkey_i *, 4314de77495SKent Overstreet struct bch_extent_crc_unpacked); 4324de77495SKent Overstreet 4334de77495SKent Overstreet /* Generic code for keys with pointers: */ 4344de77495SKent Overstreet 4354de77495SKent Overstreet static inline bool bkey_extent_is_direct_data(const struct bkey *k) 4364de77495SKent Overstreet { 4374de77495SKent Overstreet switch (k->type) { 4384de77495SKent Overstreet case KEY_TYPE_btree_ptr: 439548b3d20SKent Overstreet case KEY_TYPE_btree_ptr_v2: 4404de77495SKent Overstreet case KEY_TYPE_extent: 4414de77495SKent Overstreet case KEY_TYPE_reflink_v: 4424de77495SKent Overstreet return true; 44326609b61SKent Overstreet default: 4444de77495SKent Overstreet return false; 44526609b61SKent Overstreet } 44626609b61SKent Overstreet } 44726609b61SKent Overstreet 4484de77495SKent Overstreet static inline bool bkey_extent_is_data(const struct bkey *k) 44926609b61SKent Overstreet { 4504de77495SKent Overstreet return bkey_extent_is_direct_data(k) || 4514de77495SKent Overstreet k->type == KEY_TYPE_inline_data || 4524de77495SKent Overstreet k->type == KEY_TYPE_reflink_p; 4534de77495SKent Overstreet } 45426609b61SKent Overstreet 4554de77495SKent Overstreet /* 4564de77495SKent Overstreet * Should extent be counted under inode->i_sectors? 4574de77495SKent Overstreet */ 4584de77495SKent Overstreet static inline bool bkey_extent_is_allocation(const struct bkey *k) 4594de77495SKent Overstreet { 4604de77495SKent Overstreet switch (k->type) { 4614de77495SKent Overstreet case KEY_TYPE_extent: 4624de77495SKent Overstreet case KEY_TYPE_reservation: 4634de77495SKent Overstreet case KEY_TYPE_reflink_p: 4644de77495SKent Overstreet case KEY_TYPE_reflink_v: 4654de77495SKent Overstreet case KEY_TYPE_inline_data: 4664de77495SKent Overstreet return true; 4674de77495SKent Overstreet default: 4684de77495SKent Overstreet return false; 4694de77495SKent Overstreet } 47026609b61SKent Overstreet } 47126609b61SKent Overstreet 47226609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_devs(struct bkey_s_c k) 47326609b61SKent Overstreet { 47426609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 47526609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 47626609b61SKent Overstreet const struct bch_extent_ptr *ptr; 47726609b61SKent Overstreet 47826609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 47926609b61SKent Overstreet ret.devs[ret.nr++] = ptr->dev; 48026609b61SKent Overstreet 48126609b61SKent Overstreet return ret; 48226609b61SKent Overstreet } 48326609b61SKent Overstreet 48426609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_dirty_devs(struct bkey_s_c k) 48526609b61SKent Overstreet { 48626609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 48726609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 48826609b61SKent Overstreet const struct bch_extent_ptr *ptr; 48926609b61SKent Overstreet 49026609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 49126609b61SKent Overstreet if (!ptr->cached) 49226609b61SKent Overstreet ret.devs[ret.nr++] = ptr->dev; 49326609b61SKent Overstreet 49426609b61SKent Overstreet return ret; 49526609b61SKent Overstreet } 49626609b61SKent Overstreet 49726609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k) 49826609b61SKent Overstreet { 49926609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 50026609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 50126609b61SKent Overstreet const struct bch_extent_ptr *ptr; 50226609b61SKent Overstreet 50326609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 50426609b61SKent Overstreet if (ptr->cached) 50526609b61SKent Overstreet ret.devs[ret.nr++] = ptr->dev; 50626609b61SKent Overstreet 50726609b61SKent Overstreet return ret; 50826609b61SKent Overstreet } 50926609b61SKent Overstreet 51026609b61SKent Overstreet unsigned bch2_bkey_nr_ptrs(struct bkey_s_c); 5114de77495SKent Overstreet unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c); 5124de77495SKent Overstreet unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c); 513ab05de4cSKent Overstreet bool bch2_bkey_is_incompressible(struct bkey_s_c); 5144de77495SKent Overstreet unsigned bch2_bkey_sectors_compressed(struct bkey_s_c); 5154de77495SKent Overstreet bool bch2_check_range_allocated(struct bch_fs *, struct bpos, u64, unsigned); 51626609b61SKent Overstreet unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c); 51726609b61SKent Overstreet 51876426098SKent Overstreet void bch2_bkey_mark_replicas_cached(struct bch_fs *, struct bkey_s, 51926609b61SKent Overstreet unsigned, unsigned); 52026609b61SKent Overstreet 5214de77495SKent Overstreet void bch2_bkey_append_ptr(struct bkey_i *, struct bch_extent_ptr); 52299aaf570SKent Overstreet void bch2_extent_ptr_decoded_append(struct bkey_i *, 52371c9e0baSKent Overstreet struct extent_ptr_decoded *); 52426609b61SKent Overstreet union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s, 525a2753581SKent Overstreet struct bch_extent_ptr *); 526a2753581SKent Overstreet 52726609b61SKent Overstreet #define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \ 528a2753581SKent Overstreet do { \ 52926609b61SKent Overstreet struct bkey_ptrs _ptrs = bch2_bkey_ptrs(_k); \ 530a2753581SKent Overstreet \ 53126609b61SKent Overstreet _ptr = &_ptrs.start->ptr; \ 53226609b61SKent Overstreet \ 53326609b61SKent Overstreet while ((_ptr = bkey_ptr_next(_ptrs, _ptr))) { \ 534a2753581SKent Overstreet if (_cond) { \ 53526609b61SKent Overstreet _ptr = (void *) bch2_bkey_drop_ptr(_k, _ptr); \ 53626609b61SKent Overstreet _ptrs = bch2_bkey_ptrs(_k); \ 537a2753581SKent Overstreet continue; \ 538a2753581SKent Overstreet } \ 539a2753581SKent Overstreet \ 540a2753581SKent Overstreet (_ptr)++; \ 541a2753581SKent Overstreet } \ 542a2753581SKent Overstreet } while (0) 5431c6fdbd8SKent Overstreet 5444de77495SKent Overstreet void bch2_bkey_drop_device(struct bkey_s, unsigned); 5454de77495SKent Overstreet const struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s_c, unsigned); 5464de77495SKent Overstreet bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); 5474de77495SKent Overstreet 5484de77495SKent Overstreet bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c, 5494de77495SKent Overstreet struct bch_extent_ptr, u64); 5504de77495SKent Overstreet 5514de77495SKent Overstreet bool bch2_extent_normalize(struct bch_fs *, struct bkey_s); 5524de77495SKent Overstreet void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, 5534de77495SKent Overstreet struct bkey_s_c); 5544de77495SKent Overstreet const char *bch2_bkey_ptrs_invalid(const struct bch_fs *, struct bkey_s_c); 5554de77495SKent Overstreet 5561f49dafcSKent Overstreet void bch2_ptr_swab(struct bkey_s); 5574de77495SKent Overstreet 5584de77495SKent Overstreet /* Generic extent code: */ 5594de77495SKent Overstreet 560085ab693SKent Overstreet int bch2_cut_front_s(struct bpos, struct bkey_s); 561085ab693SKent Overstreet int bch2_cut_back_s(struct bpos, struct bkey_s); 5625b8a9227SKent Overstreet 563b1c9358aSKent Overstreet static inline void bch2_cut_front(struct bpos where, struct bkey_i *k) 5645b8a9227SKent Overstreet { 565085ab693SKent Overstreet bch2_cut_front_s(where, bkey_i_to_s(k)); 5665b8a9227SKent Overstreet } 5675b8a9227SKent Overstreet 568085ab693SKent Overstreet static inline void bch2_cut_back(struct bpos where, struct bkey_i *k) 569085ab693SKent Overstreet { 570085ab693SKent Overstreet bch2_cut_back_s(where, bkey_i_to_s(k)); 571085ab693SKent Overstreet } 5723fb5ebcdSKent Overstreet 5733fb5ebcdSKent Overstreet /** 5743fb5ebcdSKent Overstreet * bch_key_resize - adjust size of @k 5753fb5ebcdSKent Overstreet * 5763fb5ebcdSKent Overstreet * bkey_start_offset(k) will be preserved, modifies where the extent ends 5773fb5ebcdSKent Overstreet */ 5783fb5ebcdSKent Overstreet static inline void bch2_key_resize(struct bkey *k, unsigned new_size) 5793fb5ebcdSKent Overstreet { 5803fb5ebcdSKent Overstreet k->p.offset -= k->size; 5813fb5ebcdSKent Overstreet k->p.offset += new_size; 5823fb5ebcdSKent Overstreet k->size = new_size; 5833fb5ebcdSKent Overstreet } 5841c6fdbd8SKent Overstreet 5855b8a9227SKent Overstreet /* 5865b8a9227SKent Overstreet * In extent_sort_fix_overlapping(), insert_fixup_extent(), 5875b8a9227SKent Overstreet * extent_merge_inline() - we're modifying keys in place that are packed. To do 5885b8a9227SKent Overstreet * that we have to unpack the key, modify the unpacked key - then this 5895b8a9227SKent Overstreet * copies/repacks the unpacked to the original as necessary. 5905b8a9227SKent Overstreet */ 5915b8a9227SKent Overstreet static inline void extent_save(struct btree *b, struct bkey_packed *dst, 5925b8a9227SKent Overstreet struct bkey *src) 5935b8a9227SKent Overstreet { 5945b8a9227SKent Overstreet struct bkey_format *f = &b->format; 5955b8a9227SKent Overstreet struct bkey_i *dst_unpacked; 5965b8a9227SKent Overstreet 5975b8a9227SKent Overstreet if ((dst_unpacked = packed_to_bkey(dst))) 5985b8a9227SKent Overstreet dst_unpacked->k = *src; 5995b8a9227SKent Overstreet else 6005b8a9227SKent Overstreet BUG_ON(!bch2_bkey_pack_key(dst, src, f)); 6015b8a9227SKent Overstreet } 6025b8a9227SKent Overstreet 6031c6fdbd8SKent Overstreet #endif /* _BCACHEFS_EXTENTS_H */ 604