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; 118726dc93SKent Overstreet enum bkey_invalid_flags; 121c6fdbd8SKent Overstreet 1326609b61SKent Overstreet /* extent entries: */ 141c6fdbd8SKent Overstreet 1599aaf570SKent Overstreet #define extent_entry_last(_e) \ 1699aaf570SKent Overstreet ((typeof(&(_e).v->start[0])) bkey_val_end(_e)) 171c6fdbd8SKent Overstreet 1826609b61SKent Overstreet #define entry_to_ptr(_entry) \ 1926609b61SKent Overstreet ({ \ 2026609b61SKent Overstreet EBUG_ON((_entry) && !extent_entry_is_ptr(_entry)); \ 2126609b61SKent Overstreet \ 2226609b61SKent Overstreet __builtin_choose_expr( \ 2326609b61SKent Overstreet type_is_exact(_entry, const union bch_extent_entry *), \ 2426609b61SKent Overstreet (const struct bch_extent_ptr *) (_entry), \ 2526609b61SKent Overstreet (struct bch_extent_ptr *) (_entry)); \ 2626609b61SKent Overstreet }) 271c6fdbd8SKent Overstreet 2826609b61SKent Overstreet /* downcast, preserves const */ 2926609b61SKent Overstreet #define to_entry(_entry) \ 3026609b61SKent Overstreet ({ \ 3126609b61SKent Overstreet BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) && \ 3226609b61SKent Overstreet !type_is(_entry, struct bch_extent_ptr *) && \ 3326609b61SKent Overstreet !type_is(_entry, struct bch_extent_stripe_ptr *)); \ 3426609b61SKent Overstreet \ 3526609b61SKent Overstreet __builtin_choose_expr( \ 3626609b61SKent Overstreet (type_is_exact(_entry, const union bch_extent_crc *) || \ 3726609b61SKent Overstreet type_is_exact(_entry, const struct bch_extent_ptr *) ||\ 3826609b61SKent Overstreet type_is_exact(_entry, const struct bch_extent_stripe_ptr *)),\ 3926609b61SKent Overstreet (const union bch_extent_entry *) (_entry), \ 4026609b61SKent Overstreet (union bch_extent_entry *) (_entry)); \ 4126609b61SKent Overstreet }) 421c6fdbd8SKent Overstreet 434de77495SKent Overstreet #define extent_entry_next(_entry) \ 444de77495SKent Overstreet ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry))) 454de77495SKent Overstreet 4688005d5dSKent Overstreet #define extent_entry_next_safe(_entry, _end) \ 4788005d5dSKent Overstreet (likely(__extent_entry_type(_entry) < BCH_EXTENT_ENTRY_MAX) \ 4888005d5dSKent Overstreet ? extent_entry_next(_entry) \ 4988005d5dSKent Overstreet : _end) 5088005d5dSKent Overstreet 511c6fdbd8SKent Overstreet static inline unsigned 521c6fdbd8SKent Overstreet __extent_entry_type(const union bch_extent_entry *e) 531c6fdbd8SKent Overstreet { 541c6fdbd8SKent Overstreet return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX; 551c6fdbd8SKent Overstreet } 561c6fdbd8SKent Overstreet 571c6fdbd8SKent Overstreet static inline enum bch_extent_entry_type 581c6fdbd8SKent Overstreet extent_entry_type(const union bch_extent_entry *e) 591c6fdbd8SKent Overstreet { 601c6fdbd8SKent Overstreet int ret = __ffs(e->type); 611c6fdbd8SKent Overstreet 621c6fdbd8SKent Overstreet EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX); 631c6fdbd8SKent Overstreet 641c6fdbd8SKent Overstreet return ret; 651c6fdbd8SKent Overstreet } 661c6fdbd8SKent Overstreet 671c6fdbd8SKent Overstreet static inline size_t extent_entry_bytes(const union bch_extent_entry *entry) 681c6fdbd8SKent Overstreet { 691c6fdbd8SKent Overstreet switch (extent_entry_type(entry)) { 70abce30b7SKent Overstreet #define x(f, n) \ 71abce30b7SKent Overstreet case BCH_EXTENT_ENTRY_##f: \ 72abce30b7SKent Overstreet return sizeof(struct bch_extent_##f); 73abce30b7SKent Overstreet BCH_EXTENT_ENTRY_TYPES() 74abce30b7SKent Overstreet #undef x 751c6fdbd8SKent Overstreet default: 761c6fdbd8SKent Overstreet BUG(); 771c6fdbd8SKent Overstreet } 781c6fdbd8SKent Overstreet } 791c6fdbd8SKent Overstreet 801c6fdbd8SKent Overstreet static inline size_t extent_entry_u64s(const union bch_extent_entry *entry) 811c6fdbd8SKent Overstreet { 821c6fdbd8SKent Overstreet return extent_entry_bytes(entry) / sizeof(u64); 831c6fdbd8SKent Overstreet } 841c6fdbd8SKent Overstreet 8564784adeSKent Overstreet static inline void __extent_entry_insert(struct bkey_i *k, 8664784adeSKent Overstreet union bch_extent_entry *dst, 8764784adeSKent Overstreet union bch_extent_entry *new) 8864784adeSKent Overstreet { 8964784adeSKent Overstreet union bch_extent_entry *end = bkey_val_end(bkey_i_to_s(k)); 9064784adeSKent Overstreet 9164784adeSKent Overstreet memmove_u64s_up_small((u64 *) dst + extent_entry_u64s(new), 9264784adeSKent Overstreet dst, (u64 *) end - (u64 *) dst); 9364784adeSKent Overstreet k->k.u64s += extent_entry_u64s(new); 9464784adeSKent Overstreet memcpy_u64s_small(dst, new, extent_entry_u64s(new)); 9564784adeSKent Overstreet } 9664784adeSKent Overstreet 97fb3f57bbSKent Overstreet static inline void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry) 98fb3f57bbSKent Overstreet { 99fb3f57bbSKent Overstreet union bch_extent_entry *next = extent_entry_next(entry); 100fb3f57bbSKent Overstreet 101fb3f57bbSKent Overstreet /* stripes have ptrs, but their layout doesn't work with this code */ 102fb3f57bbSKent Overstreet BUG_ON(k.k->type == KEY_TYPE_stripe); 103fb3f57bbSKent Overstreet 104fb3f57bbSKent Overstreet memmove_u64s_down(entry, next, 105fb3f57bbSKent Overstreet (u64 *) bkey_val_end(k) - (u64 *) next); 106fb3f57bbSKent Overstreet k.k->u64s -= (u64 *) next - (u64 *) entry; 107fb3f57bbSKent Overstreet } 108fb3f57bbSKent Overstreet 1091c6fdbd8SKent Overstreet static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) 1101c6fdbd8SKent Overstreet { 111*264b501fSKent Overstreet return __extent_entry_type(e) == BCH_EXTENT_ENTRY_ptr; 1121742237bSKent Overstreet } 113b9a7d8acSKent Overstreet 114b9a7d8acSKent Overstreet static inline bool extent_entry_is_stripe_ptr(const union bch_extent_entry *e) 115b9a7d8acSKent Overstreet { 116*264b501fSKent Overstreet return __extent_entry_type(e) == BCH_EXTENT_ENTRY_stripe_ptr; 1171c6fdbd8SKent Overstreet } 1181c6fdbd8SKent Overstreet 1191c6fdbd8SKent Overstreet static inline bool extent_entry_is_crc(const union bch_extent_entry *e) 1201c6fdbd8SKent Overstreet { 121*264b501fSKent Overstreet switch (__extent_entry_type(e)) { 1221742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc32: 1231742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc64: 1241742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc128: 1251742237bSKent Overstreet return true; 1261742237bSKent Overstreet default: 1271742237bSKent Overstreet return false; 1281742237bSKent Overstreet } 1291c6fdbd8SKent Overstreet } 1301c6fdbd8SKent Overstreet 1311c6fdbd8SKent Overstreet union bch_extent_crc { 1321c6fdbd8SKent Overstreet u8 type; 1331c6fdbd8SKent Overstreet struct bch_extent_crc32 crc32; 1341c6fdbd8SKent Overstreet struct bch_extent_crc64 crc64; 1351c6fdbd8SKent Overstreet struct bch_extent_crc128 crc128; 1361c6fdbd8SKent Overstreet }; 1371c6fdbd8SKent Overstreet 1381c6fdbd8SKent Overstreet #define __entry_to_crc(_entry) \ 1391c6fdbd8SKent Overstreet __builtin_choose_expr( \ 1401c6fdbd8SKent Overstreet type_is_exact(_entry, const union bch_extent_entry *), \ 1411c6fdbd8SKent Overstreet (const union bch_extent_crc *) (_entry), \ 1421c6fdbd8SKent Overstreet (union bch_extent_crc *) (_entry)) 1431c6fdbd8SKent Overstreet 1441c6fdbd8SKent Overstreet #define entry_to_crc(_entry) \ 1451c6fdbd8SKent Overstreet ({ \ 1461c6fdbd8SKent Overstreet EBUG_ON((_entry) && !extent_entry_is_crc(_entry)); \ 1471c6fdbd8SKent Overstreet \ 1481c6fdbd8SKent Overstreet __entry_to_crc(_entry); \ 1491c6fdbd8SKent Overstreet }) 1501c6fdbd8SKent Overstreet 1511c6fdbd8SKent Overstreet static inline struct bch_extent_crc_unpacked 1521c6fdbd8SKent Overstreet bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc) 1531c6fdbd8SKent Overstreet { 1541c6fdbd8SKent Overstreet #define common_fields(_crc) \ 1551c6fdbd8SKent Overstreet .csum_type = _crc.csum_type, \ 1561c6fdbd8SKent Overstreet .compression_type = _crc.compression_type, \ 1571c6fdbd8SKent Overstreet .compressed_size = _crc._compressed_size + 1, \ 1581c6fdbd8SKent Overstreet .uncompressed_size = _crc._uncompressed_size + 1, \ 1591c6fdbd8SKent Overstreet .offset = _crc.offset, \ 1601c6fdbd8SKent Overstreet .live_size = k->size 1611c6fdbd8SKent Overstreet 162642d66d1SKent Overstreet if (!crc) 1631c6fdbd8SKent Overstreet return (struct bch_extent_crc_unpacked) { 1641c6fdbd8SKent Overstreet .compressed_size = k->size, 1651c6fdbd8SKent Overstreet .uncompressed_size = k->size, 1661c6fdbd8SKent Overstreet .live_size = k->size, 1671c6fdbd8SKent Overstreet }; 168642d66d1SKent Overstreet 169642d66d1SKent Overstreet switch (extent_entry_type(to_entry(crc))) { 170642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc32: { 1711c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1721c6fdbd8SKent Overstreet common_fields(crc->crc32), 1731c6fdbd8SKent Overstreet }; 1741c6fdbd8SKent Overstreet 17573bd774dSKent Overstreet *((__le32 *) &ret.csum.lo) = (__le32 __force) crc->crc32.csum; 1761c6fdbd8SKent Overstreet return ret; 1771c6fdbd8SKent Overstreet } 178642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc64: { 1791c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1801c6fdbd8SKent Overstreet common_fields(crc->crc64), 1811c6fdbd8SKent Overstreet .nonce = crc->crc64.nonce, 1821c6fdbd8SKent Overstreet .csum.lo = (__force __le64) crc->crc64.csum_lo, 1831c6fdbd8SKent Overstreet }; 1841c6fdbd8SKent Overstreet 18573bd774dSKent Overstreet *((__le16 *) &ret.csum.hi) = (__le16 __force) crc->crc64.csum_hi; 1861c6fdbd8SKent Overstreet 1871c6fdbd8SKent Overstreet return ret; 1881c6fdbd8SKent Overstreet } 189642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc128: { 1901c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1911c6fdbd8SKent Overstreet common_fields(crc->crc128), 1921c6fdbd8SKent Overstreet .nonce = crc->crc128.nonce, 1931c6fdbd8SKent Overstreet .csum = crc->crc128.csum, 1941c6fdbd8SKent Overstreet }; 1951c6fdbd8SKent Overstreet 1961c6fdbd8SKent Overstreet return ret; 1971c6fdbd8SKent Overstreet } 1981c6fdbd8SKent Overstreet default: 1991c6fdbd8SKent Overstreet BUG(); 2001c6fdbd8SKent Overstreet } 2011c6fdbd8SKent Overstreet #undef common_fields 2021c6fdbd8SKent Overstreet } 2031c6fdbd8SKent Overstreet 204ab05de4cSKent Overstreet static inline bool crc_is_compressed(struct bch_extent_crc_unpacked crc) 205ab05de4cSKent Overstreet { 206ab05de4cSKent Overstreet return (crc.compression_type != BCH_COMPRESSION_TYPE_none && 207ab05de4cSKent Overstreet crc.compression_type != BCH_COMPRESSION_TYPE_incompressible); 208ab05de4cSKent Overstreet } 209ab05de4cSKent Overstreet 2109db2f860SKent Overstreet static inline bool crc_is_encoded(struct bch_extent_crc_unpacked crc) 2119db2f860SKent Overstreet { 2129db2f860SKent Overstreet return crc.csum_type != BCH_CSUM_none || crc_is_compressed(crc); 2139db2f860SKent Overstreet } 2149db2f860SKent Overstreet 21526609b61SKent Overstreet /* bkey_ptrs: generically over any key type that has ptrs */ 21626609b61SKent Overstreet 21726609b61SKent Overstreet struct bkey_ptrs_c { 21826609b61SKent Overstreet const union bch_extent_entry *start; 21926609b61SKent Overstreet const union bch_extent_entry *end; 22026609b61SKent Overstreet }; 22126609b61SKent Overstreet 22226609b61SKent Overstreet struct bkey_ptrs { 22326609b61SKent Overstreet union bch_extent_entry *start; 22426609b61SKent Overstreet union bch_extent_entry *end; 22526609b61SKent Overstreet }; 22626609b61SKent Overstreet 2274de77495SKent Overstreet static inline struct bkey_ptrs_c bch2_bkey_ptrs_c(struct bkey_s_c k) 2284de77495SKent Overstreet { 2294de77495SKent Overstreet switch (k.k->type) { 2304de77495SKent Overstreet case KEY_TYPE_btree_ptr: { 2314de77495SKent Overstreet struct bkey_s_c_btree_ptr e = bkey_s_c_to_btree_ptr(k); 232a1019576SKent Overstreet 2334de77495SKent Overstreet return (struct bkey_ptrs_c) { 2344de77495SKent Overstreet to_entry(&e.v->start[0]), 2354de77495SKent Overstreet to_entry(extent_entry_last(e)) 2364de77495SKent Overstreet }; 2374de77495SKent Overstreet } 2384de77495SKent Overstreet case KEY_TYPE_extent: { 2394de77495SKent Overstreet struct bkey_s_c_extent e = bkey_s_c_to_extent(k); 240a1019576SKent Overstreet 2414de77495SKent Overstreet return (struct bkey_ptrs_c) { 2424de77495SKent Overstreet e.v->start, 2434de77495SKent Overstreet extent_entry_last(e) 2444de77495SKent Overstreet }; 2454de77495SKent Overstreet } 2464de77495SKent Overstreet case KEY_TYPE_stripe: { 2474de77495SKent Overstreet struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); 248a1019576SKent Overstreet 2494de77495SKent Overstreet return (struct bkey_ptrs_c) { 2504de77495SKent Overstreet to_entry(&s.v->ptrs[0]), 2514de77495SKent Overstreet to_entry(&s.v->ptrs[s.v->nr_blocks]), 2524de77495SKent Overstreet }; 2534de77495SKent Overstreet } 2544de77495SKent Overstreet case KEY_TYPE_reflink_v: { 2554de77495SKent Overstreet struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k); 2561c6fdbd8SKent Overstreet 2574de77495SKent Overstreet return (struct bkey_ptrs_c) { 2584de77495SKent Overstreet r.v->start, 2594de77495SKent Overstreet bkey_val_end(r), 2604de77495SKent Overstreet }; 2614de77495SKent Overstreet } 262548b3d20SKent Overstreet case KEY_TYPE_btree_ptr_v2: { 263548b3d20SKent Overstreet struct bkey_s_c_btree_ptr_v2 e = bkey_s_c_to_btree_ptr_v2(k); 264a1019576SKent Overstreet 265548b3d20SKent Overstreet return (struct bkey_ptrs_c) { 266548b3d20SKent Overstreet to_entry(&e.v->start[0]), 267548b3d20SKent Overstreet to_entry(extent_entry_last(e)) 268548b3d20SKent Overstreet }; 269548b3d20SKent Overstreet } 2704de77495SKent Overstreet default: 2714de77495SKent Overstreet return (struct bkey_ptrs_c) { NULL, NULL }; 2724de77495SKent Overstreet } 2734de77495SKent Overstreet } 2744de77495SKent Overstreet 2754de77495SKent Overstreet static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k) 2764de77495SKent Overstreet { 2774de77495SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k.s_c); 2784de77495SKent Overstreet 2794de77495SKent Overstreet return (struct bkey_ptrs) { 2804de77495SKent Overstreet (void *) p.start, 2814de77495SKent Overstreet (void *) p.end 2824de77495SKent Overstreet }; 2834de77495SKent Overstreet } 2841c6fdbd8SKent Overstreet 28526609b61SKent Overstreet #define __bkey_extent_entry_for_each_from(_start, _end, _entry) \ 28626609b61SKent Overstreet for ((_entry) = (_start); \ 28726609b61SKent Overstreet (_entry) < (_end); \ 28888005d5dSKent Overstreet (_entry) = extent_entry_next_safe(_entry, _end)) 2891c6fdbd8SKent Overstreet 29026609b61SKent Overstreet #define __bkey_ptr_next(_ptr, _end) \ 29126609b61SKent Overstreet ({ \ 29226609b61SKent Overstreet typeof(_end) _entry; \ 29326609b61SKent Overstreet \ 29426609b61SKent Overstreet __bkey_extent_entry_for_each_from(to_entry(_ptr), _end, _entry) \ 29526609b61SKent Overstreet if (extent_entry_is_ptr(_entry)) \ 29626609b61SKent Overstreet break; \ 29726609b61SKent Overstreet \ 29826609b61SKent Overstreet _entry < (_end) ? entry_to_ptr(_entry) : NULL; \ 29926609b61SKent Overstreet }) 30026609b61SKent Overstreet 30126609b61SKent Overstreet #define bkey_extent_entry_for_each_from(_p, _entry, _start) \ 30226609b61SKent Overstreet __bkey_extent_entry_for_each_from(_start, (_p).end, _entry) 30326609b61SKent Overstreet 30426609b61SKent Overstreet #define bkey_extent_entry_for_each(_p, _entry) \ 30526609b61SKent Overstreet bkey_extent_entry_for_each_from(_p, _entry, _p.start) 30626609b61SKent Overstreet 30726609b61SKent Overstreet #define __bkey_for_each_ptr(_start, _end, _ptr) \ 3080beebd92SKent Overstreet for (typeof(_start) (_ptr) = (_start); \ 30926609b61SKent Overstreet ((_ptr) = __bkey_ptr_next(_ptr, _end)); \ 31026609b61SKent Overstreet (_ptr)++) 31126609b61SKent Overstreet 31226609b61SKent Overstreet #define bkey_ptr_next(_p, _ptr) \ 31326609b61SKent Overstreet __bkey_ptr_next(_ptr, (_p).end) 31426609b61SKent Overstreet 31526609b61SKent Overstreet #define bkey_for_each_ptr(_p, _ptr) \ 31626609b61SKent Overstreet __bkey_for_each_ptr(&(_p).start->ptr, (_p).end, _ptr) 31726609b61SKent Overstreet 31826609b61SKent Overstreet #define __bkey_ptr_next_decode(_k, _end, _ptr, _entry) \ 31926609b61SKent Overstreet ({ \ 32026609b61SKent Overstreet __label__ out; \ 32126609b61SKent Overstreet \ 32226609b61SKent Overstreet (_ptr).idx = 0; \ 32337954a27SKent Overstreet (_ptr).has_ec = false; \ 32426609b61SKent Overstreet \ 32526609b61SKent Overstreet __bkey_extent_entry_for_each_from(_entry, _end, _entry) \ 32688005d5dSKent Overstreet switch (__extent_entry_type(_entry)) { \ 32726609b61SKent Overstreet case BCH_EXTENT_ENTRY_ptr: \ 32826609b61SKent Overstreet (_ptr).ptr = _entry->ptr; \ 32926609b61SKent Overstreet goto out; \ 33026609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc32: \ 33126609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc64: \ 33226609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc128: \ 33326609b61SKent Overstreet (_ptr).crc = bch2_extent_crc_unpack(_k, \ 33426609b61SKent Overstreet entry_to_crc(_entry)); \ 33526609b61SKent Overstreet break; \ 33626609b61SKent Overstreet case BCH_EXTENT_ENTRY_stripe_ptr: \ 33737954a27SKent Overstreet (_ptr).ec = _entry->stripe_ptr; \ 33837954a27SKent Overstreet (_ptr).has_ec = true; \ 33926609b61SKent Overstreet break; \ 3402766876dSKent Overstreet default: \ 3412766876dSKent Overstreet /* nothing */ \ 3422766876dSKent Overstreet break; \ 34326609b61SKent Overstreet } \ 34426609b61SKent Overstreet out: \ 34526609b61SKent Overstreet _entry < (_end); \ 34626609b61SKent Overstreet }) 34726609b61SKent Overstreet 34826609b61SKent Overstreet #define __bkey_for_each_ptr_decode(_k, _start, _end, _ptr, _entry) \ 34926609b61SKent Overstreet for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL), \ 35026609b61SKent Overstreet (_entry) = _start; \ 35126609b61SKent Overstreet __bkey_ptr_next_decode(_k, _end, _ptr, _entry); \ 35288005d5dSKent Overstreet (_entry) = extent_entry_next_safe(_entry, _end)) 35326609b61SKent Overstreet 35426609b61SKent Overstreet #define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry) \ 35526609b61SKent Overstreet __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end, \ 35626609b61SKent Overstreet _ptr, _entry) 35726609b61SKent Overstreet 35899aaf570SKent Overstreet #define bkey_crc_next(_k, _start, _end, _crc, _iter) \ 35999aaf570SKent Overstreet ({ \ 36099aaf570SKent Overstreet __bkey_extent_entry_for_each_from(_iter, _end, _iter) \ 36199aaf570SKent Overstreet if (extent_entry_is_crc(_iter)) { \ 36299aaf570SKent Overstreet (_crc) = bch2_extent_crc_unpack(_k, \ 36399aaf570SKent Overstreet entry_to_crc(_iter)); \ 36499aaf570SKent Overstreet break; \ 36599aaf570SKent Overstreet } \ 36699aaf570SKent Overstreet \ 36799aaf570SKent Overstreet (_iter) < (_end); \ 36899aaf570SKent Overstreet }) 36999aaf570SKent Overstreet 37099aaf570SKent Overstreet #define __bkey_for_each_crc(_k, _start, _end, _crc, _iter) \ 37199aaf570SKent Overstreet for ((_crc) = bch2_extent_crc_unpack(_k, NULL), \ 37299aaf570SKent Overstreet (_iter) = (_start); \ 37399aaf570SKent Overstreet bkey_crc_next(_k, _start, _end, _crc, _iter); \ 37499aaf570SKent Overstreet (_iter) = extent_entry_next(_iter)) 37599aaf570SKent Overstreet 37699aaf570SKent Overstreet #define bkey_for_each_crc(_k, _p, _crc, _iter) \ 37799aaf570SKent Overstreet __bkey_for_each_crc(_k, (_p).start, (_p).end, _crc, _iter) 37899aaf570SKent Overstreet 3794de77495SKent Overstreet /* Iterate over pointers in KEY_TYPE_extent: */ 3804de77495SKent Overstreet 3814de77495SKent Overstreet #define extent_for_each_entry_from(_e, _entry, _start) \ 3824de77495SKent Overstreet __bkey_extent_entry_for_each_from(_start, \ 3834de77495SKent Overstreet extent_entry_last(_e), _entry) 3844de77495SKent Overstreet 3854de77495SKent Overstreet #define extent_for_each_entry(_e, _entry) \ 3864de77495SKent Overstreet extent_for_each_entry_from(_e, _entry, (_e).v->start) 3874de77495SKent Overstreet 3884de77495SKent Overstreet #define extent_ptr_next(_e, _ptr) \ 3894de77495SKent Overstreet __bkey_ptr_next(_ptr, extent_entry_last(_e)) 3904de77495SKent Overstreet 3914de77495SKent Overstreet #define extent_for_each_ptr(_e, _ptr) \ 3924de77495SKent Overstreet __bkey_for_each_ptr(&(_e).v->start->ptr, extent_entry_last(_e), _ptr) 3934de77495SKent Overstreet 3944de77495SKent Overstreet #define extent_for_each_ptr_decode(_e, _ptr, _entry) \ 3954de77495SKent Overstreet __bkey_for_each_ptr_decode((_e).k, (_e).v->start, \ 3964de77495SKent Overstreet extent_entry_last(_e), _ptr, _entry) 3974de77495SKent Overstreet 39826609b61SKent Overstreet /* utility code common to all keys with pointers: */ 39926609b61SKent Overstreet 4004de77495SKent Overstreet void bch2_mark_io_failure(struct bch_io_failures *, 4014de77495SKent Overstreet struct extent_ptr_decoded *); 4024de77495SKent Overstreet int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, 4034de77495SKent Overstreet struct bch_io_failures *, 4044de77495SKent Overstreet struct extent_ptr_decoded *); 40576426098SKent Overstreet 4064de77495SKent Overstreet /* KEY_TYPE_btree_ptr: */ 4074de77495SKent Overstreet 408b65db750SKent Overstreet int bch2_btree_ptr_invalid(struct bch_fs *, struct bkey_s_c, 4098726dc93SKent Overstreet enum bkey_invalid_flags, struct printbuf *); 4104de77495SKent Overstreet void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, 4114de77495SKent Overstreet struct bkey_s_c); 41259a38a38SKent Overstreet 413b65db750SKent Overstreet int bch2_btree_ptr_v2_invalid(struct bch_fs *, struct bkey_s_c, 4148726dc93SKent Overstreet enum bkey_invalid_flags, struct printbuf *); 415f0ac7df2SKent Overstreet void bch2_btree_ptr_v2_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 41639fb2983SKent Overstreet void bch2_btree_ptr_v2_compat(enum btree_id, unsigned, unsigned, 41739fb2983SKent Overstreet int, struct bkey_s); 4184de77495SKent Overstreet 419a1019576SKent Overstreet #define bch2_bkey_ops_btree_ptr ((struct bkey_ops) { \ 4204de77495SKent Overstreet .key_invalid = bch2_btree_ptr_invalid, \ 4214de77495SKent Overstreet .val_to_text = bch2_btree_ptr_to_text, \ 4224de77495SKent Overstreet .swab = bch2_ptr_swab, \ 423f0431c5fSKent Overstreet .trigger = bch2_trigger_extent, \ 424a1019576SKent Overstreet }) 4254de77495SKent Overstreet 426a1019576SKent Overstreet #define bch2_bkey_ops_btree_ptr_v2 ((struct bkey_ops) { \ 427fad7cfedSKent Overstreet .key_invalid = bch2_btree_ptr_v2_invalid, \ 42859a38a38SKent Overstreet .val_to_text = bch2_btree_ptr_v2_to_text, \ 429548b3d20SKent Overstreet .swab = bch2_ptr_swab, \ 43039fb2983SKent Overstreet .compat = bch2_btree_ptr_v2_compat, \ 431f0431c5fSKent Overstreet .trigger = bch2_trigger_extent, \ 432174f930bSKent Overstreet .min_val_size = 40, \ 433a1019576SKent Overstreet }) 434548b3d20SKent Overstreet 4354de77495SKent Overstreet /* KEY_TYPE_extent: */ 4364de77495SKent Overstreet 43759ba21d9SKent Overstreet bool bch2_extent_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 4384de77495SKent Overstreet 439a1019576SKent Overstreet #define bch2_bkey_ops_extent ((struct bkey_ops) { \ 440f0ac7df2SKent Overstreet .key_invalid = bch2_bkey_ptrs_invalid, \ 441f0ac7df2SKent Overstreet .val_to_text = bch2_bkey_ptrs_to_text, \ 4424de77495SKent Overstreet .swab = bch2_ptr_swab, \ 4434de77495SKent Overstreet .key_normalize = bch2_extent_normalize, \ 4444de77495SKent Overstreet .key_merge = bch2_extent_merge, \ 445f0431c5fSKent Overstreet .trigger = bch2_trigger_extent, \ 446a1019576SKent Overstreet }) 4474de77495SKent Overstreet 4484de77495SKent Overstreet /* KEY_TYPE_reservation: */ 4494de77495SKent Overstreet 450b65db750SKent Overstreet int bch2_reservation_invalid(struct bch_fs *, struct bkey_s_c, 4518726dc93SKent Overstreet enum bkey_invalid_flags, struct printbuf *); 4524de77495SKent Overstreet void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 45359ba21d9SKent Overstreet bool bch2_reservation_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c); 4544de77495SKent Overstreet 455a1019576SKent Overstreet #define bch2_bkey_ops_reservation ((struct bkey_ops) { \ 4564de77495SKent Overstreet .key_invalid = bch2_reservation_invalid, \ 4574de77495SKent Overstreet .val_to_text = bch2_reservation_to_text, \ 4584de77495SKent Overstreet .key_merge = bch2_reservation_merge, \ 459f0431c5fSKent Overstreet .trigger = bch2_trigger_reservation, \ 460174f930bSKent Overstreet .min_val_size = 8, \ 461a1019576SKent Overstreet }) 4624de77495SKent Overstreet 4634de77495SKent Overstreet /* Extent checksum entries: */ 4644de77495SKent Overstreet 4654de77495SKent Overstreet bool bch2_can_narrow_extent_crcs(struct bkey_s_c, 4664de77495SKent Overstreet struct bch_extent_crc_unpacked); 4674de77495SKent Overstreet bool bch2_bkey_narrow_crcs(struct bkey_i *, struct bch_extent_crc_unpacked); 4684de77495SKent Overstreet void bch2_extent_crc_append(struct bkey_i *, 4694de77495SKent Overstreet struct bch_extent_crc_unpacked); 4704de77495SKent Overstreet 4714de77495SKent Overstreet /* Generic code for keys with pointers: */ 4724de77495SKent Overstreet 473297d8934SKent Overstreet static inline bool bkey_is_btree_ptr(const struct bkey *k) 474297d8934SKent Overstreet { 475297d8934SKent Overstreet switch (k->type) { 476297d8934SKent Overstreet case KEY_TYPE_btree_ptr: 477297d8934SKent Overstreet case KEY_TYPE_btree_ptr_v2: 478297d8934SKent Overstreet return true; 479297d8934SKent Overstreet default: 480297d8934SKent Overstreet return false; 481297d8934SKent Overstreet } 482297d8934SKent Overstreet } 483297d8934SKent Overstreet 4844de77495SKent Overstreet static inline bool bkey_extent_is_direct_data(const struct bkey *k) 4854de77495SKent Overstreet { 4864de77495SKent Overstreet switch (k->type) { 4874de77495SKent Overstreet case KEY_TYPE_btree_ptr: 488548b3d20SKent Overstreet case KEY_TYPE_btree_ptr_v2: 4894de77495SKent Overstreet case KEY_TYPE_extent: 4904de77495SKent Overstreet case KEY_TYPE_reflink_v: 4914de77495SKent Overstreet return true; 49226609b61SKent Overstreet default: 4934de77495SKent Overstreet return false; 49426609b61SKent Overstreet } 49526609b61SKent Overstreet } 49626609b61SKent Overstreet 497801a3de6SKent Overstreet static inline bool bkey_extent_is_inline_data(const struct bkey *k) 498801a3de6SKent Overstreet { 499801a3de6SKent Overstreet return k->type == KEY_TYPE_inline_data || 500801a3de6SKent Overstreet k->type == KEY_TYPE_indirect_inline_data; 501801a3de6SKent Overstreet } 502801a3de6SKent Overstreet 503801a3de6SKent Overstreet static inline unsigned bkey_inline_data_offset(const struct bkey *k) 504801a3de6SKent Overstreet { 505801a3de6SKent Overstreet switch (k->type) { 506801a3de6SKent Overstreet case KEY_TYPE_inline_data: 507801a3de6SKent Overstreet return sizeof(struct bch_inline_data); 508801a3de6SKent Overstreet case KEY_TYPE_indirect_inline_data: 509801a3de6SKent Overstreet return sizeof(struct bch_indirect_inline_data); 510801a3de6SKent Overstreet default: 511801a3de6SKent Overstreet BUG(); 512801a3de6SKent Overstreet } 513801a3de6SKent Overstreet } 514801a3de6SKent Overstreet 515801a3de6SKent Overstreet static inline unsigned bkey_inline_data_bytes(const struct bkey *k) 516801a3de6SKent Overstreet { 517801a3de6SKent Overstreet return bkey_val_bytes(k) - bkey_inline_data_offset(k); 518801a3de6SKent Overstreet } 519801a3de6SKent Overstreet 520801a3de6SKent Overstreet #define bkey_inline_data_p(_k) (((void *) (_k).v) + bkey_inline_data_offset((_k).k)) 521801a3de6SKent Overstreet 5224de77495SKent Overstreet static inline bool bkey_extent_is_data(const struct bkey *k) 52326609b61SKent Overstreet { 5244de77495SKent Overstreet return bkey_extent_is_direct_data(k) || 525801a3de6SKent Overstreet bkey_extent_is_inline_data(k) || 5264de77495SKent Overstreet k->type == KEY_TYPE_reflink_p; 5274de77495SKent Overstreet } 52826609b61SKent Overstreet 5294de77495SKent Overstreet /* 5304de77495SKent Overstreet * Should extent be counted under inode->i_sectors? 5314de77495SKent Overstreet */ 5324de77495SKent Overstreet static inline bool bkey_extent_is_allocation(const struct bkey *k) 5334de77495SKent Overstreet { 5344de77495SKent Overstreet switch (k->type) { 5354de77495SKent Overstreet case KEY_TYPE_extent: 5364de77495SKent Overstreet case KEY_TYPE_reservation: 5374de77495SKent Overstreet case KEY_TYPE_reflink_p: 5384de77495SKent Overstreet case KEY_TYPE_reflink_v: 5394de77495SKent Overstreet case KEY_TYPE_inline_data: 540801a3de6SKent Overstreet case KEY_TYPE_indirect_inline_data: 541be47e0baSKent Overstreet case KEY_TYPE_error: 5424de77495SKent Overstreet return true; 5434de77495SKent Overstreet default: 5444de77495SKent Overstreet return false; 5454de77495SKent Overstreet } 54626609b61SKent Overstreet } 54726609b61SKent Overstreet 54879203111SKent Overstreet static inline bool bkey_extent_is_unwritten(struct bkey_s_c k) 54979203111SKent Overstreet { 55079203111SKent Overstreet struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k); 55179203111SKent Overstreet 55279203111SKent Overstreet bkey_for_each_ptr(ptrs, ptr) 55379203111SKent Overstreet if (ptr->unwritten) 55479203111SKent Overstreet return true; 55579203111SKent Overstreet return false; 55679203111SKent Overstreet } 55779203111SKent Overstreet 55879203111SKent Overstreet static inline bool bkey_extent_is_reservation(struct bkey_s_c k) 55979203111SKent Overstreet { 56079203111SKent Overstreet return k.k->type == KEY_TYPE_reservation || 56179203111SKent Overstreet bkey_extent_is_unwritten(k); 56279203111SKent Overstreet } 56379203111SKent Overstreet 56426609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_devs(struct bkey_s_c k) 56526609b61SKent Overstreet { 56626609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 56726609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 56826609b61SKent Overstreet 56926609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 570037a2d9fSKent Overstreet ret.data[ret.nr++] = ptr->dev; 57126609b61SKent Overstreet 57226609b61SKent Overstreet return ret; 57326609b61SKent Overstreet } 57426609b61SKent Overstreet 57526609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_dirty_devs(struct bkey_s_c k) 57626609b61SKent Overstreet { 57726609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 57826609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 57926609b61SKent Overstreet 58026609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 58126609b61SKent Overstreet if (!ptr->cached) 582037a2d9fSKent Overstreet ret.data[ret.nr++] = ptr->dev; 58326609b61SKent Overstreet 58426609b61SKent Overstreet return ret; 58526609b61SKent Overstreet } 58626609b61SKent Overstreet 58726609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k) 58826609b61SKent Overstreet { 58926609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 59026609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 59126609b61SKent Overstreet 59226609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 59326609b61SKent Overstreet if (ptr->cached) 594037a2d9fSKent Overstreet ret.data[ret.nr++] = ptr->dev; 59526609b61SKent Overstreet 59626609b61SKent Overstreet return ret; 59726609b61SKent Overstreet } 59826609b61SKent Overstreet 599e1036ce5SKent Overstreet static inline unsigned bch2_bkey_ptr_data_type(struct bkey_s_c k, const struct bch_extent_ptr *ptr) 600e1036ce5SKent Overstreet { 601e1036ce5SKent Overstreet switch (k.k->type) { 602e1036ce5SKent Overstreet case KEY_TYPE_btree_ptr: 603e1036ce5SKent Overstreet case KEY_TYPE_btree_ptr_v2: 604e1036ce5SKent Overstreet return BCH_DATA_btree; 605e1036ce5SKent Overstreet case KEY_TYPE_extent: 606e1036ce5SKent Overstreet case KEY_TYPE_reflink_v: 607e1036ce5SKent Overstreet return BCH_DATA_user; 608e1036ce5SKent Overstreet case KEY_TYPE_stripe: { 609e1036ce5SKent Overstreet struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); 610e1036ce5SKent Overstreet 611e1036ce5SKent Overstreet BUG_ON(ptr < s.v->ptrs || 612e1036ce5SKent Overstreet ptr >= s.v->ptrs + s.v->nr_blocks); 613e1036ce5SKent Overstreet 614e1036ce5SKent Overstreet return ptr >= s.v->ptrs + s.v->nr_blocks - s.v->nr_redundant 615e1036ce5SKent Overstreet ? BCH_DATA_parity 616e1036ce5SKent Overstreet : BCH_DATA_user; 617e1036ce5SKent Overstreet } 618e1036ce5SKent Overstreet default: 619e1036ce5SKent Overstreet BUG(); 620e1036ce5SKent Overstreet } 621e1036ce5SKent Overstreet } 622e1036ce5SKent Overstreet 62326609b61SKent Overstreet unsigned bch2_bkey_nr_ptrs(struct bkey_s_c); 6244de77495SKent Overstreet unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c); 6254de77495SKent Overstreet unsigned bch2_bkey_nr_ptrs_fully_allocated(struct bkey_s_c); 626ab05de4cSKent Overstreet bool bch2_bkey_is_incompressible(struct bkey_s_c); 6274de77495SKent Overstreet unsigned bch2_bkey_sectors_compressed(struct bkey_s_c); 62835a067b4SKent Overstreet 62935a067b4SKent Overstreet unsigned bch2_bkey_replicas(struct bch_fs *, struct bkey_s_c); 63091ecd41bSKent Overstreet unsigned bch2_extent_ptr_desired_durability(struct bch_fs *, struct extent_ptr_decoded *); 631a8b3a677SKent Overstreet unsigned bch2_extent_ptr_durability(struct bch_fs *, struct extent_ptr_decoded *); 63226609b61SKent Overstreet unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c); 63326609b61SKent Overstreet 634393a1f68SKent Overstreet void bch2_bkey_drop_device(struct bkey_s, unsigned); 635393a1f68SKent Overstreet void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned); 636702ffea2SKent Overstreet 637702ffea2SKent Overstreet const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned); 638702ffea2SKent Overstreet 639702ffea2SKent Overstreet static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsigned dev) 640702ffea2SKent Overstreet { 641702ffea2SKent Overstreet return (void *) bch2_bkey_has_device_c(k.s_c, dev); 642702ffea2SKent Overstreet } 643702ffea2SKent Overstreet 644393a1f68SKent Overstreet bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned); 645393a1f68SKent Overstreet 6460507962fSKent Overstreet void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *); 647393a1f68SKent Overstreet 648393a1f68SKent Overstreet static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr) 649393a1f68SKent Overstreet { 6507413ab70SKees Cook struct bch_extent_ptr *dest; 6517413ab70SKees Cook 652702ffea2SKent Overstreet EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev)); 653393a1f68SKent Overstreet 654393a1f68SKent Overstreet switch (k->k.type) { 655393a1f68SKent Overstreet case KEY_TYPE_btree_ptr: 656393a1f68SKent Overstreet case KEY_TYPE_btree_ptr_v2: 657393a1f68SKent Overstreet case KEY_TYPE_extent: 658393a1f68SKent Overstreet EBUG_ON(bkey_val_u64s(&k->k) >= BKEY_EXTENT_VAL_U64s_MAX); 659393a1f68SKent Overstreet 660393a1f68SKent Overstreet ptr.type = 1 << BCH_EXTENT_ENTRY_ptr; 6617413ab70SKees Cook dest = (struct bch_extent_ptr *)((void *) &k->v + bkey_val_bytes(&k->k)); 6627413ab70SKees Cook *dest = ptr; 663ac2ccddcSKent Overstreet k->k.u64s++; 664393a1f68SKent Overstreet break; 665393a1f68SKent Overstreet default: 666393a1f68SKent Overstreet BUG(); 667393a1f68SKent Overstreet } 668393a1f68SKent Overstreet } 669393a1f68SKent Overstreet 67099aaf570SKent Overstreet void bch2_extent_ptr_decoded_append(struct bkey_i *, 67171c9e0baSKent Overstreet struct extent_ptr_decoded *); 672702ffea2SKent Overstreet union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s, 673702ffea2SKent Overstreet struct bch_extent_ptr *); 67426609b61SKent Overstreet union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s, 675a2753581SKent Overstreet struct bch_extent_ptr *); 676a2753581SKent Overstreet 67726609b61SKent Overstreet #define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \ 678a2753581SKent Overstreet do { \ 67926609b61SKent Overstreet struct bkey_ptrs _ptrs = bch2_bkey_ptrs(_k); \ 680a2753581SKent Overstreet \ 68126609b61SKent Overstreet _ptr = &_ptrs.start->ptr; \ 68226609b61SKent Overstreet \ 68326609b61SKent Overstreet while ((_ptr = bkey_ptr_next(_ptrs, _ptr))) { \ 684a2753581SKent Overstreet if (_cond) { \ 68526609b61SKent Overstreet _ptr = (void *) bch2_bkey_drop_ptr(_k, _ptr); \ 68626609b61SKent Overstreet _ptrs = bch2_bkey_ptrs(_k); \ 687a2753581SKent Overstreet continue; \ 688a2753581SKent Overstreet } \ 689a2753581SKent Overstreet \ 690a2753581SKent Overstreet (_ptr)++; \ 691a2753581SKent Overstreet } \ 692a2753581SKent Overstreet } while (0) 6931c6fdbd8SKent Overstreet 6944de77495SKent Overstreet bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c, 6954de77495SKent Overstreet struct bch_extent_ptr, u64); 6967f5c5d20SKent Overstreet bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c); 697702ffea2SKent Overstreet struct bch_extent_ptr * 698702ffea2SKent Overstreet bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s); 6994de77495SKent Overstreet 700c9163bb0SKent Overstreet void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *); 701c9163bb0SKent Overstreet 7024de77495SKent Overstreet bool bch2_extent_normalize(struct bch_fs *, struct bkey_s); 7034de77495SKent Overstreet void bch2_bkey_ptrs_to_text(struct printbuf *, struct bch_fs *, 7044de77495SKent Overstreet struct bkey_s_c); 705b65db750SKent Overstreet int bch2_bkey_ptrs_invalid(struct bch_fs *, struct bkey_s_c, 7068726dc93SKent Overstreet enum bkey_invalid_flags, struct printbuf *); 7074de77495SKent Overstreet 7081f49dafcSKent Overstreet void bch2_ptr_swab(struct bkey_s); 7094de77495SKent Overstreet 710fb3f57bbSKent Overstreet const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c); 711fb3f57bbSKent Overstreet unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c, 712fb3f57bbSKent Overstreet unsigned, unsigned); 713fb3f57bbSKent Overstreet bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c); 714fb3f57bbSKent Overstreet 715fb3f57bbSKent Overstreet int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *, 716d7e77f53SKent Overstreet struct bch_io_opts *); 717fb3f57bbSKent Overstreet 7184de77495SKent Overstreet /* Generic extent code: */ 7194de77495SKent Overstreet 7204cf91b02SKent Overstreet enum bch_extent_overlap { 7214cf91b02SKent Overstreet BCH_EXTENT_OVERLAP_ALL = 0, 7224cf91b02SKent Overstreet BCH_EXTENT_OVERLAP_BACK = 1, 7234cf91b02SKent Overstreet BCH_EXTENT_OVERLAP_FRONT = 2, 7244cf91b02SKent Overstreet BCH_EXTENT_OVERLAP_MIDDLE = 3, 7254cf91b02SKent Overstreet }; 7264cf91b02SKent Overstreet 7274cf91b02SKent Overstreet /* Returns how k overlaps with m */ 7284cf91b02SKent Overstreet static inline enum bch_extent_overlap bch2_extent_overlap(const struct bkey *k, 7294cf91b02SKent Overstreet const struct bkey *m) 7304cf91b02SKent Overstreet { 731e88a75ebSKent Overstreet int cmp1 = bkey_lt(k->p, m->p); 732e88a75ebSKent Overstreet int cmp2 = bkey_gt(bkey_start_pos(k), bkey_start_pos(m)); 7334cf91b02SKent Overstreet 7344cf91b02SKent Overstreet return (cmp1 << 1) + cmp2; 7354cf91b02SKent Overstreet } 7364cf91b02SKent Overstreet 737085ab693SKent Overstreet int bch2_cut_front_s(struct bpos, struct bkey_s); 738085ab693SKent Overstreet int bch2_cut_back_s(struct bpos, struct bkey_s); 7395b8a9227SKent Overstreet 740b1c9358aSKent Overstreet static inline void bch2_cut_front(struct bpos where, struct bkey_i *k) 7415b8a9227SKent Overstreet { 742085ab693SKent Overstreet bch2_cut_front_s(where, bkey_i_to_s(k)); 7435b8a9227SKent Overstreet } 7445b8a9227SKent Overstreet 745085ab693SKent Overstreet static inline void bch2_cut_back(struct bpos where, struct bkey_i *k) 746085ab693SKent Overstreet { 747085ab693SKent Overstreet bch2_cut_back_s(where, bkey_i_to_s(k)); 748085ab693SKent Overstreet } 7493fb5ebcdSKent Overstreet 7503fb5ebcdSKent Overstreet /** 7513fb5ebcdSKent Overstreet * bch_key_resize - adjust size of @k 7523fb5ebcdSKent Overstreet * 7533fb5ebcdSKent Overstreet * bkey_start_offset(k) will be preserved, modifies where the extent ends 7543fb5ebcdSKent Overstreet */ 7553fb5ebcdSKent Overstreet static inline void bch2_key_resize(struct bkey *k, unsigned new_size) 7563fb5ebcdSKent Overstreet { 7573fb5ebcdSKent Overstreet k->p.offset -= k->size; 7583fb5ebcdSKent Overstreet k->p.offset += new_size; 7593fb5ebcdSKent Overstreet k->size = new_size; 7603fb5ebcdSKent Overstreet } 7611c6fdbd8SKent Overstreet 7621c6fdbd8SKent Overstreet #endif /* _BCACHEFS_EXTENTS_H */ 763