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; 10*0dc17247SKent Overstreet struct btree_trans; 111c6fdbd8SKent Overstreet struct btree_insert_entry; 121c6fdbd8SKent Overstreet 1326609b61SKent Overstreet /* extent entries: */ 141c6fdbd8SKent Overstreet 1526609b61SKent Overstreet #define extent_entry_last(_e) 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 421c6fdbd8SKent Overstreet static inline unsigned 431c6fdbd8SKent Overstreet __extent_entry_type(const union bch_extent_entry *e) 441c6fdbd8SKent Overstreet { 451c6fdbd8SKent Overstreet return e->type ? __ffs(e->type) : BCH_EXTENT_ENTRY_MAX; 461c6fdbd8SKent Overstreet } 471c6fdbd8SKent Overstreet 481c6fdbd8SKent Overstreet static inline enum bch_extent_entry_type 491c6fdbd8SKent Overstreet extent_entry_type(const union bch_extent_entry *e) 501c6fdbd8SKent Overstreet { 511c6fdbd8SKent Overstreet int ret = __ffs(e->type); 521c6fdbd8SKent Overstreet 531c6fdbd8SKent Overstreet EBUG_ON(ret < 0 || ret >= BCH_EXTENT_ENTRY_MAX); 541c6fdbd8SKent Overstreet 551c6fdbd8SKent Overstreet return ret; 561c6fdbd8SKent Overstreet } 571c6fdbd8SKent Overstreet 581c6fdbd8SKent Overstreet static inline size_t extent_entry_bytes(const union bch_extent_entry *entry) 591c6fdbd8SKent Overstreet { 601c6fdbd8SKent Overstreet switch (extent_entry_type(entry)) { 61abce30b7SKent Overstreet #define x(f, n) \ 62abce30b7SKent Overstreet case BCH_EXTENT_ENTRY_##f: \ 63abce30b7SKent Overstreet return sizeof(struct bch_extent_##f); 64abce30b7SKent Overstreet BCH_EXTENT_ENTRY_TYPES() 65abce30b7SKent Overstreet #undef x 661c6fdbd8SKent Overstreet default: 671c6fdbd8SKent Overstreet BUG(); 681c6fdbd8SKent Overstreet } 691c6fdbd8SKent Overstreet } 701c6fdbd8SKent Overstreet 711c6fdbd8SKent Overstreet static inline size_t extent_entry_u64s(const union bch_extent_entry *entry) 721c6fdbd8SKent Overstreet { 731c6fdbd8SKent Overstreet return extent_entry_bytes(entry) / sizeof(u64); 741c6fdbd8SKent Overstreet } 751c6fdbd8SKent Overstreet 761c6fdbd8SKent Overstreet static inline bool extent_entry_is_ptr(const union bch_extent_entry *e) 771c6fdbd8SKent Overstreet { 781742237bSKent Overstreet switch (extent_entry_type(e)) { 791742237bSKent Overstreet case BCH_EXTENT_ENTRY_ptr: 801742237bSKent Overstreet return true; 811742237bSKent Overstreet default: 821742237bSKent Overstreet return false; 831742237bSKent Overstreet } 841c6fdbd8SKent Overstreet } 851c6fdbd8SKent Overstreet 861c6fdbd8SKent Overstreet static inline bool extent_entry_is_crc(const union bch_extent_entry *e) 871c6fdbd8SKent Overstreet { 881742237bSKent Overstreet switch (extent_entry_type(e)) { 891742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc32: 901742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc64: 911742237bSKent Overstreet case BCH_EXTENT_ENTRY_crc128: 921742237bSKent Overstreet return true; 931742237bSKent Overstreet default: 941742237bSKent Overstreet return false; 951742237bSKent Overstreet } 961c6fdbd8SKent Overstreet } 971c6fdbd8SKent Overstreet 981c6fdbd8SKent Overstreet union bch_extent_crc { 991c6fdbd8SKent Overstreet u8 type; 1001c6fdbd8SKent Overstreet struct bch_extent_crc32 crc32; 1011c6fdbd8SKent Overstreet struct bch_extent_crc64 crc64; 1021c6fdbd8SKent Overstreet struct bch_extent_crc128 crc128; 1031c6fdbd8SKent Overstreet }; 1041c6fdbd8SKent Overstreet 1051c6fdbd8SKent Overstreet #define __entry_to_crc(_entry) \ 1061c6fdbd8SKent Overstreet __builtin_choose_expr( \ 1071c6fdbd8SKent Overstreet type_is_exact(_entry, const union bch_extent_entry *), \ 1081c6fdbd8SKent Overstreet (const union bch_extent_crc *) (_entry), \ 1091c6fdbd8SKent Overstreet (union bch_extent_crc *) (_entry)) 1101c6fdbd8SKent Overstreet 1111c6fdbd8SKent Overstreet #define entry_to_crc(_entry) \ 1121c6fdbd8SKent Overstreet ({ \ 1131c6fdbd8SKent Overstreet EBUG_ON((_entry) && !extent_entry_is_crc(_entry)); \ 1141c6fdbd8SKent Overstreet \ 1151c6fdbd8SKent Overstreet __entry_to_crc(_entry); \ 1161c6fdbd8SKent Overstreet }) 1171c6fdbd8SKent Overstreet 1181c6fdbd8SKent Overstreet static inline struct bch_extent_crc_unpacked 1191c6fdbd8SKent Overstreet bch2_extent_crc_unpack(const struct bkey *k, const union bch_extent_crc *crc) 1201c6fdbd8SKent Overstreet { 1211c6fdbd8SKent Overstreet #define common_fields(_crc) \ 1221c6fdbd8SKent Overstreet .csum_type = _crc.csum_type, \ 1231c6fdbd8SKent Overstreet .compression_type = _crc.compression_type, \ 1241c6fdbd8SKent Overstreet .compressed_size = _crc._compressed_size + 1, \ 1251c6fdbd8SKent Overstreet .uncompressed_size = _crc._uncompressed_size + 1, \ 1261c6fdbd8SKent Overstreet .offset = _crc.offset, \ 1271c6fdbd8SKent Overstreet .live_size = k->size 1281c6fdbd8SKent Overstreet 129642d66d1SKent Overstreet if (!crc) 1301c6fdbd8SKent Overstreet return (struct bch_extent_crc_unpacked) { 1311c6fdbd8SKent Overstreet .compressed_size = k->size, 1321c6fdbd8SKent Overstreet .uncompressed_size = k->size, 1331c6fdbd8SKent Overstreet .live_size = k->size, 1341c6fdbd8SKent Overstreet }; 135642d66d1SKent Overstreet 136642d66d1SKent Overstreet switch (extent_entry_type(to_entry(crc))) { 137642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc32: { 1381c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1391c6fdbd8SKent Overstreet common_fields(crc->crc32), 1401c6fdbd8SKent Overstreet }; 1411c6fdbd8SKent Overstreet 1421c6fdbd8SKent Overstreet *((__le32 *) &ret.csum.lo) = crc->crc32.csum; 1431c6fdbd8SKent Overstreet 1441c6fdbd8SKent Overstreet memcpy(&ret.csum.lo, &crc->crc32.csum, 1451c6fdbd8SKent Overstreet sizeof(crc->crc32.csum)); 1461c6fdbd8SKent Overstreet 1471c6fdbd8SKent Overstreet return ret; 1481c6fdbd8SKent Overstreet } 149642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc64: { 1501c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1511c6fdbd8SKent Overstreet common_fields(crc->crc64), 1521c6fdbd8SKent Overstreet .nonce = crc->crc64.nonce, 1531c6fdbd8SKent Overstreet .csum.lo = (__force __le64) crc->crc64.csum_lo, 1541c6fdbd8SKent Overstreet }; 1551c6fdbd8SKent Overstreet 1561c6fdbd8SKent Overstreet *((__le16 *) &ret.csum.hi) = crc->crc64.csum_hi; 1571c6fdbd8SKent Overstreet 1581c6fdbd8SKent Overstreet return ret; 1591c6fdbd8SKent Overstreet } 160642d66d1SKent Overstreet case BCH_EXTENT_ENTRY_crc128: { 1611c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked ret = (struct bch_extent_crc_unpacked) { 1621c6fdbd8SKent Overstreet common_fields(crc->crc128), 1631c6fdbd8SKent Overstreet .nonce = crc->crc128.nonce, 1641c6fdbd8SKent Overstreet .csum = crc->crc128.csum, 1651c6fdbd8SKent Overstreet }; 1661c6fdbd8SKent Overstreet 1671c6fdbd8SKent Overstreet return ret; 1681c6fdbd8SKent Overstreet } 1691c6fdbd8SKent Overstreet default: 1701c6fdbd8SKent Overstreet BUG(); 1711c6fdbd8SKent Overstreet } 1721c6fdbd8SKent Overstreet #undef common_fields 1731c6fdbd8SKent Overstreet } 1741c6fdbd8SKent Overstreet 17526609b61SKent Overstreet /* bkey_ptrs: generically over any key type that has ptrs */ 17626609b61SKent Overstreet 17726609b61SKent Overstreet struct bkey_ptrs_c { 17826609b61SKent Overstreet const union bch_extent_entry *start; 17926609b61SKent Overstreet const union bch_extent_entry *end; 18026609b61SKent Overstreet }; 18126609b61SKent Overstreet 18226609b61SKent Overstreet struct bkey_ptrs { 18326609b61SKent Overstreet union bch_extent_entry *start; 18426609b61SKent Overstreet union bch_extent_entry *end; 18526609b61SKent Overstreet }; 18626609b61SKent Overstreet 18726609b61SKent Overstreet /* iterate over bkey ptrs */ 1881c6fdbd8SKent Overstreet 1891c6fdbd8SKent Overstreet #define extent_entry_next(_entry) \ 1901c6fdbd8SKent Overstreet ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry))) 1911c6fdbd8SKent Overstreet 19226609b61SKent Overstreet #define __bkey_extent_entry_for_each_from(_start, _end, _entry) \ 19326609b61SKent Overstreet for ((_entry) = (_start); \ 19426609b61SKent Overstreet (_entry) < (_end); \ 19526609b61SKent Overstreet (_entry) = extent_entry_next(_entry)) 1961c6fdbd8SKent Overstreet 19726609b61SKent Overstreet #define __bkey_ptr_next(_ptr, _end) \ 19826609b61SKent Overstreet ({ \ 19926609b61SKent Overstreet typeof(_end) _entry; \ 20026609b61SKent Overstreet \ 20126609b61SKent Overstreet __bkey_extent_entry_for_each_from(to_entry(_ptr), _end, _entry) \ 20226609b61SKent Overstreet if (extent_entry_is_ptr(_entry)) \ 20326609b61SKent Overstreet break; \ 20426609b61SKent Overstreet \ 20526609b61SKent Overstreet _entry < (_end) ? entry_to_ptr(_entry) : NULL; \ 20626609b61SKent Overstreet }) 20726609b61SKent Overstreet 20826609b61SKent Overstreet #define bkey_extent_entry_for_each_from(_p, _entry, _start) \ 20926609b61SKent Overstreet __bkey_extent_entry_for_each_from(_start, (_p).end, _entry) 21026609b61SKent Overstreet 21126609b61SKent Overstreet #define bkey_extent_entry_for_each(_p, _entry) \ 21226609b61SKent Overstreet bkey_extent_entry_for_each_from(_p, _entry, _p.start) 21326609b61SKent Overstreet 21426609b61SKent Overstreet #define __bkey_for_each_ptr(_start, _end, _ptr) \ 21526609b61SKent Overstreet for ((_ptr) = (_start); \ 21626609b61SKent Overstreet ((_ptr) = __bkey_ptr_next(_ptr, _end)); \ 21726609b61SKent Overstreet (_ptr)++) 21826609b61SKent Overstreet 21926609b61SKent Overstreet #define bkey_ptr_next(_p, _ptr) \ 22026609b61SKent Overstreet __bkey_ptr_next(_ptr, (_p).end) 22126609b61SKent Overstreet 22226609b61SKent Overstreet #define bkey_for_each_ptr(_p, _ptr) \ 22326609b61SKent Overstreet __bkey_for_each_ptr(&(_p).start->ptr, (_p).end, _ptr) 22426609b61SKent Overstreet 22526609b61SKent Overstreet #define __bkey_ptr_next_decode(_k, _end, _ptr, _entry) \ 22626609b61SKent Overstreet ({ \ 22726609b61SKent Overstreet __label__ out; \ 22826609b61SKent Overstreet \ 22926609b61SKent Overstreet (_ptr).idx = 0; \ 23026609b61SKent Overstreet (_ptr).ec_nr = 0; \ 23126609b61SKent Overstreet \ 23226609b61SKent Overstreet __bkey_extent_entry_for_each_from(_entry, _end, _entry) \ 23326609b61SKent Overstreet switch (extent_entry_type(_entry)) { \ 23426609b61SKent Overstreet case BCH_EXTENT_ENTRY_ptr: \ 23526609b61SKent Overstreet (_ptr).ptr = _entry->ptr; \ 23626609b61SKent Overstreet goto out; \ 23726609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc32: \ 23826609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc64: \ 23926609b61SKent Overstreet case BCH_EXTENT_ENTRY_crc128: \ 24026609b61SKent Overstreet (_ptr).crc = bch2_extent_crc_unpack(_k, \ 24126609b61SKent Overstreet entry_to_crc(_entry)); \ 24226609b61SKent Overstreet break; \ 24326609b61SKent Overstreet case BCH_EXTENT_ENTRY_stripe_ptr: \ 24426609b61SKent Overstreet (_ptr).ec[(_ptr).ec_nr++] = _entry->stripe_ptr; \ 24526609b61SKent Overstreet break; \ 24626609b61SKent Overstreet } \ 24726609b61SKent Overstreet out: \ 24826609b61SKent Overstreet _entry < (_end); \ 24926609b61SKent Overstreet }) 25026609b61SKent Overstreet 25126609b61SKent Overstreet #define __bkey_for_each_ptr_decode(_k, _start, _end, _ptr, _entry) \ 25226609b61SKent Overstreet for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL), \ 25326609b61SKent Overstreet (_entry) = _start; \ 25426609b61SKent Overstreet __bkey_ptr_next_decode(_k, _end, _ptr, _entry); \ 25526609b61SKent Overstreet (_entry) = extent_entry_next(_entry)) 25626609b61SKent Overstreet 25726609b61SKent Overstreet #define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry) \ 25826609b61SKent Overstreet __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end, \ 25926609b61SKent Overstreet _ptr, _entry) 26026609b61SKent Overstreet 26126609b61SKent Overstreet /* utility code common to all keys with pointers: */ 26226609b61SKent Overstreet 26326609b61SKent Overstreet static inline struct bkey_ptrs_c bch2_bkey_ptrs_c(struct bkey_s_c k) 26426609b61SKent Overstreet { 26526609b61SKent Overstreet switch (k.k->type) { 26626609b61SKent Overstreet case KEY_TYPE_btree_ptr: { 26726609b61SKent Overstreet struct bkey_s_c_btree_ptr e = bkey_s_c_to_btree_ptr(k); 26826609b61SKent Overstreet return (struct bkey_ptrs_c) { 26926609b61SKent Overstreet to_entry(&e.v->start[0]), 27026609b61SKent Overstreet to_entry(bkey_val_end(e)) 27126609b61SKent Overstreet }; 27226609b61SKent Overstreet } 27326609b61SKent Overstreet case KEY_TYPE_extent: { 27426609b61SKent Overstreet struct bkey_s_c_extent e = bkey_s_c_to_extent(k); 27526609b61SKent Overstreet return (struct bkey_ptrs_c) { 27626609b61SKent Overstreet e.v->start, 27726609b61SKent Overstreet extent_entry_last(e) 27826609b61SKent Overstreet }; 27926609b61SKent Overstreet } 28026609b61SKent Overstreet case KEY_TYPE_stripe: { 28126609b61SKent Overstreet struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k); 28226609b61SKent Overstreet return (struct bkey_ptrs_c) { 28326609b61SKent Overstreet to_entry(&s.v->ptrs[0]), 28426609b61SKent Overstreet to_entry(&s.v->ptrs[s.v->nr_blocks]), 28526609b61SKent Overstreet }; 28626609b61SKent Overstreet } 28726609b61SKent Overstreet default: 28826609b61SKent Overstreet return (struct bkey_ptrs_c) { NULL, NULL }; 28926609b61SKent Overstreet } 29026609b61SKent Overstreet } 29126609b61SKent Overstreet 29226609b61SKent Overstreet static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k) 29326609b61SKent Overstreet { 29426609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k.s_c); 29526609b61SKent Overstreet 29626609b61SKent Overstreet return (struct bkey_ptrs) { 29726609b61SKent Overstreet (void *) p.start, 29826609b61SKent Overstreet (void *) p.end 29926609b61SKent Overstreet }; 30026609b61SKent Overstreet } 30126609b61SKent Overstreet 30226609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_devs(struct bkey_s_c k) 30326609b61SKent Overstreet { 30426609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 30526609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 30626609b61SKent Overstreet const struct bch_extent_ptr *ptr; 30726609b61SKent Overstreet 30826609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 30926609b61SKent Overstreet ret.devs[ret.nr++] = ptr->dev; 31026609b61SKent Overstreet 31126609b61SKent Overstreet return ret; 31226609b61SKent Overstreet } 31326609b61SKent Overstreet 31426609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_dirty_devs(struct bkey_s_c k) 31526609b61SKent Overstreet { 31626609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 31726609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 31826609b61SKent Overstreet const struct bch_extent_ptr *ptr; 31926609b61SKent Overstreet 32026609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 32126609b61SKent Overstreet if (!ptr->cached) 32226609b61SKent Overstreet ret.devs[ret.nr++] = ptr->dev; 32326609b61SKent Overstreet 32426609b61SKent Overstreet return ret; 32526609b61SKent Overstreet } 32626609b61SKent Overstreet 32726609b61SKent Overstreet static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k) 32826609b61SKent Overstreet { 32926609b61SKent Overstreet struct bch_devs_list ret = (struct bch_devs_list) { 0 }; 33026609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 33126609b61SKent Overstreet const struct bch_extent_ptr *ptr; 33226609b61SKent Overstreet 33326609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 33426609b61SKent Overstreet if (ptr->cached) 33526609b61SKent Overstreet ret.devs[ret.nr++] = ptr->dev; 33626609b61SKent Overstreet 33726609b61SKent Overstreet return ret; 33826609b61SKent Overstreet } 33926609b61SKent Overstreet 34026609b61SKent Overstreet static inline bool bch2_bkey_has_device(struct bkey_s_c k, unsigned dev) 34126609b61SKent Overstreet { 34226609b61SKent Overstreet struct bkey_ptrs_c p = bch2_bkey_ptrs_c(k); 34326609b61SKent Overstreet const struct bch_extent_ptr *ptr; 34426609b61SKent Overstreet 34526609b61SKent Overstreet bkey_for_each_ptr(p, ptr) 34626609b61SKent Overstreet if (ptr->dev == dev) 34726609b61SKent Overstreet return ptr; 34826609b61SKent Overstreet 34926609b61SKent Overstreet return NULL; 35026609b61SKent Overstreet } 35126609b61SKent Overstreet 35226609b61SKent Overstreet unsigned bch2_bkey_nr_ptrs(struct bkey_s_c); 35326609b61SKent Overstreet unsigned bch2_bkey_nr_dirty_ptrs(struct bkey_s_c); 35426609b61SKent Overstreet unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c); 35526609b61SKent Overstreet 35626609b61SKent Overstreet void bch2_mark_io_failure(struct bch_io_failures *, 35726609b61SKent Overstreet struct extent_ptr_decoded *); 35826609b61SKent Overstreet int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, 35926609b61SKent Overstreet struct bch_io_failures *, 36026609b61SKent Overstreet struct extent_ptr_decoded *); 36126609b61SKent Overstreet 36226609b61SKent Overstreet /* bch_btree_ptr: */ 36326609b61SKent Overstreet 36426609b61SKent Overstreet const char *bch2_btree_ptr_invalid(const struct bch_fs *, struct bkey_s_c); 36526609b61SKent Overstreet void bch2_btree_ptr_debugcheck(struct bch_fs *, struct btree *, 36626609b61SKent Overstreet struct bkey_s_c); 36726609b61SKent Overstreet void bch2_btree_ptr_to_text(struct printbuf *, struct bch_fs *, 36826609b61SKent Overstreet struct bkey_s_c); 36926609b61SKent Overstreet void bch2_ptr_swab(const struct bkey_format *, struct bkey_packed *); 37026609b61SKent Overstreet 37126609b61SKent Overstreet #define bch2_bkey_ops_btree_ptr (struct bkey_ops) { \ 37226609b61SKent Overstreet .key_invalid = bch2_btree_ptr_invalid, \ 37326609b61SKent Overstreet .key_debugcheck = bch2_btree_ptr_debugcheck, \ 37426609b61SKent Overstreet .val_to_text = bch2_btree_ptr_to_text, \ 37526609b61SKent Overstreet .swab = bch2_ptr_swab, \ 37626609b61SKent Overstreet } 37726609b61SKent Overstreet 37826609b61SKent Overstreet /* bch_extent: */ 37926609b61SKent Overstreet 38026609b61SKent Overstreet const char *bch2_extent_invalid(const struct bch_fs *, struct bkey_s_c); 38126609b61SKent Overstreet void bch2_extent_debugcheck(struct bch_fs *, struct btree *, struct bkey_s_c); 38226609b61SKent Overstreet void bch2_extent_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 38326609b61SKent Overstreet bool bch2_extent_normalize(struct bch_fs *, struct bkey_s); 38426609b61SKent Overstreet enum merge_result bch2_extent_merge(struct bch_fs *, 38526609b61SKent Overstreet struct bkey_i *, struct bkey_i *); 38626609b61SKent Overstreet 38726609b61SKent Overstreet #define bch2_bkey_ops_extent (struct bkey_ops) { \ 38826609b61SKent Overstreet .key_invalid = bch2_extent_invalid, \ 38926609b61SKent Overstreet .key_debugcheck = bch2_extent_debugcheck, \ 39026609b61SKent Overstreet .val_to_text = bch2_extent_to_text, \ 39126609b61SKent Overstreet .swab = bch2_ptr_swab, \ 39226609b61SKent Overstreet .key_normalize = bch2_extent_normalize, \ 39326609b61SKent Overstreet .key_merge = bch2_extent_merge, \ 39426609b61SKent Overstreet } 39526609b61SKent Overstreet 39626609b61SKent Overstreet /* bch_reservation: */ 39726609b61SKent Overstreet 39826609b61SKent Overstreet const char *bch2_reservation_invalid(const struct bch_fs *, struct bkey_s_c); 39926609b61SKent Overstreet void bch2_reservation_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c); 40026609b61SKent Overstreet enum merge_result bch2_reservation_merge(struct bch_fs *, 40126609b61SKent Overstreet struct bkey_i *, struct bkey_i *); 40226609b61SKent Overstreet 40326609b61SKent Overstreet #define bch2_bkey_ops_reservation (struct bkey_ops) { \ 40426609b61SKent Overstreet .key_invalid = bch2_reservation_invalid, \ 40526609b61SKent Overstreet .val_to_text = bch2_reservation_to_text, \ 40626609b61SKent Overstreet .key_merge = bch2_reservation_merge, \ 40726609b61SKent Overstreet } 40826609b61SKent Overstreet 40926609b61SKent Overstreet void bch2_extent_trim_atomic(struct bkey_i *, struct btree_iter *); 410c93cead0SKent Overstreet bool bch2_extent_is_atomic(struct bkey_i *, struct btree_iter *); 41126609b61SKent Overstreet 41226609b61SKent Overstreet enum btree_insert_ret 413*0dc17247SKent Overstreet bch2_extent_can_insert(struct btree_trans *, struct btree_insert_entry *, 41426609b61SKent Overstreet unsigned *); 415*0dc17247SKent Overstreet void bch2_insert_fixup_extent(struct btree_trans *, 416c93cead0SKent Overstreet struct btree_insert_entry *); 41726609b61SKent Overstreet 41826609b61SKent Overstreet void bch2_extent_mark_replicas_cached(struct bch_fs *, struct bkey_s_extent, 41926609b61SKent Overstreet unsigned, unsigned); 42026609b61SKent Overstreet 42126609b61SKent Overstreet const struct bch_extent_ptr * 42226609b61SKent Overstreet bch2_extent_has_device(struct bkey_s_c_extent, unsigned); 42326609b61SKent Overstreet const struct bch_extent_ptr * 42426609b61SKent Overstreet bch2_extent_has_group(struct bch_fs *, struct bkey_s_c_extent, unsigned); 42526609b61SKent Overstreet const struct bch_extent_ptr * 42626609b61SKent Overstreet bch2_extent_has_target(struct bch_fs *, struct bkey_s_c_extent, unsigned); 42726609b61SKent Overstreet 42826609b61SKent Overstreet unsigned bch2_extent_is_compressed(struct bkey_s_c); 42926609b61SKent Overstreet 43026609b61SKent Overstreet bool bch2_extent_matches_ptr(struct bch_fs *, struct bkey_s_c_extent, 43126609b61SKent Overstreet struct bch_extent_ptr, u64); 43226609b61SKent Overstreet 43326609b61SKent Overstreet static inline bool bkey_extent_is_data(const struct bkey *k) 43426609b61SKent Overstreet { 43526609b61SKent Overstreet switch (k->type) { 43626609b61SKent Overstreet case KEY_TYPE_btree_ptr: 43726609b61SKent Overstreet case KEY_TYPE_extent: 43826609b61SKent Overstreet return true; 43926609b61SKent Overstreet default: 44026609b61SKent Overstreet return false; 44126609b61SKent Overstreet } 44226609b61SKent Overstreet } 44326609b61SKent Overstreet 44426609b61SKent Overstreet static inline bool bkey_extent_is_allocation(const struct bkey *k) 44526609b61SKent Overstreet { 44626609b61SKent Overstreet switch (k->type) { 44726609b61SKent Overstreet case KEY_TYPE_extent: 44826609b61SKent Overstreet case KEY_TYPE_reservation: 44926609b61SKent Overstreet return true; 45026609b61SKent Overstreet default: 45126609b61SKent Overstreet return false; 45226609b61SKent Overstreet } 45326609b61SKent Overstreet } 45426609b61SKent Overstreet 45526609b61SKent Overstreet static inline bool bch2_extent_is_fully_allocated(struct bkey_s_c k) 45626609b61SKent Overstreet { 45726609b61SKent Overstreet return bkey_extent_is_allocation(k.k) && 45826609b61SKent Overstreet !bch2_extent_is_compressed(k); 45926609b61SKent Overstreet } 46026609b61SKent Overstreet 46126609b61SKent Overstreet void bch2_bkey_append_ptr(struct bkey_i *, struct bch_extent_ptr); 46226609b61SKent Overstreet void bch2_bkey_drop_device(struct bkey_s, unsigned); 46326609b61SKent Overstreet 46426609b61SKent Overstreet /* Extent entry iteration: */ 4651c6fdbd8SKent Overstreet 4661c6fdbd8SKent Overstreet #define extent_for_each_entry_from(_e, _entry, _start) \ 46726609b61SKent Overstreet __bkey_extent_entry_for_each_from(_start, \ 46826609b61SKent Overstreet extent_entry_last(_e),_entry) 4691c6fdbd8SKent Overstreet 4701c6fdbd8SKent Overstreet #define extent_for_each_entry(_e, _entry) \ 4711c6fdbd8SKent Overstreet extent_for_each_entry_from(_e, _entry, (_e).v->start) 4721c6fdbd8SKent Overstreet 4731742237bSKent Overstreet #define extent_ptr_next(_e, _ptr) \ 47426609b61SKent Overstreet __bkey_ptr_next(_ptr, extent_entry_last(_e)) 4751c6fdbd8SKent Overstreet 4761742237bSKent Overstreet #define extent_for_each_ptr(_e, _ptr) \ 47726609b61SKent Overstreet __bkey_for_each_ptr(&(_e).v->start->ptr, extent_entry_last(_e), _ptr) 4781c6fdbd8SKent Overstreet 4791c6fdbd8SKent Overstreet #define extent_crc_next(_e, _crc, _iter) \ 4801c6fdbd8SKent Overstreet ({ \ 4811c6fdbd8SKent Overstreet extent_for_each_entry_from(_e, _iter, _iter) \ 4821c6fdbd8SKent Overstreet if (extent_entry_is_crc(_iter)) { \ 4831c6fdbd8SKent Overstreet (_crc) = bch2_extent_crc_unpack((_e).k, entry_to_crc(_iter));\ 4841c6fdbd8SKent Overstreet break; \ 4851c6fdbd8SKent Overstreet } \ 4861c6fdbd8SKent Overstreet \ 4871c6fdbd8SKent Overstreet (_iter) < extent_entry_last(_e); \ 4881c6fdbd8SKent Overstreet }) 4891c6fdbd8SKent Overstreet 4901c6fdbd8SKent Overstreet #define extent_for_each_crc(_e, _crc, _iter) \ 4911c6fdbd8SKent Overstreet for ((_crc) = bch2_extent_crc_unpack((_e).k, NULL), \ 4921c6fdbd8SKent Overstreet (_iter) = (_e).v->start; \ 4931c6fdbd8SKent Overstreet extent_crc_next(_e, _crc, _iter); \ 4941c6fdbd8SKent Overstreet (_iter) = extent_entry_next(_iter)) 4951c6fdbd8SKent Overstreet 4961742237bSKent Overstreet #define extent_for_each_ptr_decode(_e, _ptr, _entry) \ 49726609b61SKent Overstreet __bkey_for_each_ptr_decode((_e).k, (_e).v->start, \ 49826609b61SKent Overstreet extent_entry_last(_e), _ptr, _entry) 4991c6fdbd8SKent Overstreet 5001c6fdbd8SKent Overstreet void bch2_extent_crc_append(struct bkey_i_extent *, 5011c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked); 50271c9e0baSKent Overstreet void bch2_extent_ptr_decoded_append(struct bkey_i_extent *, 50371c9e0baSKent Overstreet struct extent_ptr_decoded *); 5041c6fdbd8SKent Overstreet 5051c6fdbd8SKent Overstreet static inline void __extent_entry_push(struct bkey_i_extent *e) 5061c6fdbd8SKent Overstreet { 5071c6fdbd8SKent Overstreet union bch_extent_entry *entry = extent_entry_last(extent_i_to_s(e)); 5081c6fdbd8SKent Overstreet 5091c6fdbd8SKent Overstreet EBUG_ON(bkey_val_u64s(&e->k) + extent_entry_u64s(entry) > 5101c6fdbd8SKent Overstreet BKEY_EXTENT_VAL_U64s_MAX); 5111c6fdbd8SKent Overstreet 5121c6fdbd8SKent Overstreet e->k.u64s += extent_entry_u64s(entry); 5131c6fdbd8SKent Overstreet } 5141c6fdbd8SKent Overstreet 5151c6fdbd8SKent Overstreet bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent, 5161c6fdbd8SKent Overstreet struct bch_extent_crc_unpacked); 5171c6fdbd8SKent Overstreet bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked); 5181c6fdbd8SKent Overstreet 51926609b61SKent Overstreet union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s, 520a2753581SKent Overstreet struct bch_extent_ptr *); 521a2753581SKent Overstreet 52226609b61SKent Overstreet #define bch2_bkey_drop_ptrs(_k, _ptr, _cond) \ 523a2753581SKent Overstreet do { \ 52426609b61SKent Overstreet struct bkey_ptrs _ptrs = bch2_bkey_ptrs(_k); \ 525a2753581SKent Overstreet \ 52626609b61SKent Overstreet _ptr = &_ptrs.start->ptr; \ 52726609b61SKent Overstreet \ 52826609b61SKent Overstreet while ((_ptr = bkey_ptr_next(_ptrs, _ptr))) { \ 529a2753581SKent Overstreet if (_cond) { \ 53026609b61SKent Overstreet _ptr = (void *) bch2_bkey_drop_ptr(_k, _ptr); \ 53126609b61SKent Overstreet _ptrs = bch2_bkey_ptrs(_k); \ 532a2753581SKent Overstreet continue; \ 533a2753581SKent Overstreet } \ 534a2753581SKent Overstreet \ 535a2753581SKent Overstreet (_ptr)++; \ 536a2753581SKent Overstreet } \ 537a2753581SKent Overstreet } while (0) 5381c6fdbd8SKent Overstreet 5395b8a9227SKent Overstreet bool __bch2_cut_front(struct bpos, struct bkey_s); 5405b8a9227SKent Overstreet 5415b8a9227SKent Overstreet static inline bool bch2_cut_front(struct bpos where, struct bkey_i *k) 5425b8a9227SKent Overstreet { 5435b8a9227SKent Overstreet return __bch2_cut_front(where, bkey_i_to_s(k)); 5445b8a9227SKent Overstreet } 5455b8a9227SKent Overstreet 5461c6fdbd8SKent Overstreet bool bch2_cut_back(struct bpos, struct bkey *); 5471c6fdbd8SKent Overstreet void bch2_key_resize(struct bkey *, unsigned); 5481c6fdbd8SKent Overstreet 5495b8a9227SKent Overstreet /* 5505b8a9227SKent Overstreet * In extent_sort_fix_overlapping(), insert_fixup_extent(), 5515b8a9227SKent Overstreet * extent_merge_inline() - we're modifying keys in place that are packed. To do 5525b8a9227SKent Overstreet * that we have to unpack the key, modify the unpacked key - then this 5535b8a9227SKent Overstreet * copies/repacks the unpacked to the original as necessary. 5545b8a9227SKent Overstreet */ 5555b8a9227SKent Overstreet static inline void extent_save(struct btree *b, struct bkey_packed *dst, 5565b8a9227SKent Overstreet struct bkey *src) 5575b8a9227SKent Overstreet { 5585b8a9227SKent Overstreet struct bkey_format *f = &b->format; 5595b8a9227SKent Overstreet struct bkey_i *dst_unpacked; 5605b8a9227SKent Overstreet 5615b8a9227SKent Overstreet if ((dst_unpacked = packed_to_bkey(dst))) 5625b8a9227SKent Overstreet dst_unpacked->k = *src; 5635b8a9227SKent Overstreet else 5645b8a9227SKent Overstreet BUG_ON(!bch2_bkey_pack_key(dst, src, f)); 5655b8a9227SKent Overstreet } 5665b8a9227SKent Overstreet 5677ef2a73aSKent Overstreet bool bch2_check_range_allocated(struct bch_fs *, struct bpos, u64, unsigned); 5687ef2a73aSKent Overstreet unsigned bch2_bkey_nr_ptrs_allocated(struct bkey_s_c); 5691c6fdbd8SKent Overstreet 5701c6fdbd8SKent Overstreet #endif /* _BCACHEFS_EXTENTS_H */ 571