1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _BCACHEFS_BKEY_TYPES_H 3 #define _BCACHEFS_BKEY_TYPES_H 4 5 #include "bcachefs_format.h" 6 7 /* 8 * bkey_i - bkey with inline value 9 * bkey_s - bkey with split value 10 * bkey_s_c - bkey with split value, const 11 */ 12 13 #define bkey_p_next(_k) vstruct_next(_k) 14 bkey_next(struct bkey_i * k)15 static inline struct bkey_i *bkey_next(struct bkey_i *k) 16 { 17 return (struct bkey_i *) ((u64 *) k->_data + k->k.u64s); 18 } 19 20 #define bkey_val_u64s(_k) ((_k)->u64s - BKEY_U64s) 21 bkey_val_bytes(const struct bkey * k)22 static inline size_t bkey_val_bytes(const struct bkey *k) 23 { 24 return bkey_val_u64s(k) * sizeof(u64); 25 } 26 set_bkey_val_u64s(struct bkey * k,unsigned val_u64s)27 static inline void set_bkey_val_u64s(struct bkey *k, unsigned val_u64s) 28 { 29 unsigned u64s = BKEY_U64s + val_u64s; 30 31 BUG_ON(u64s > U8_MAX); 32 k->u64s = u64s; 33 } 34 set_bkey_val_bytes(struct bkey * k,unsigned bytes)35 static inline void set_bkey_val_bytes(struct bkey *k, unsigned bytes) 36 { 37 set_bkey_val_u64s(k, DIV_ROUND_UP(bytes, sizeof(u64))); 38 } 39 40 #define bkey_val_end(_k) ((void *) (((u64 *) (_k).v) + bkey_val_u64s((_k).k))) 41 42 #define bkey_deleted(_k) ((_k)->type == KEY_TYPE_deleted) 43 44 #define bkey_whiteout(_k) \ 45 ((_k)->type == KEY_TYPE_deleted || (_k)->type == KEY_TYPE_whiteout) 46 47 /* bkey with split value, const */ 48 struct bkey_s_c { 49 const struct bkey *k; 50 const struct bch_val *v; 51 }; 52 53 /* bkey with split value */ 54 struct bkey_s { 55 union { 56 struct { 57 struct bkey *k; 58 struct bch_val *v; 59 }; 60 struct bkey_s_c s_c; 61 }; 62 }; 63 64 #define bkey_s_null ((struct bkey_s) { .k = NULL }) 65 #define bkey_s_c_null ((struct bkey_s_c) { .k = NULL }) 66 67 #define bkey_s_err(err) ((struct bkey_s) { .k = ERR_PTR(err) }) 68 #define bkey_s_c_err(err) ((struct bkey_s_c) { .k = ERR_PTR(err) }) 69 bkey_to_s(struct bkey * k)70 static inline struct bkey_s bkey_to_s(struct bkey *k) 71 { 72 return (struct bkey_s) { .k = k, .v = NULL }; 73 } 74 bkey_to_s_c(const struct bkey * k)75 static inline struct bkey_s_c bkey_to_s_c(const struct bkey *k) 76 { 77 return (struct bkey_s_c) { .k = k, .v = NULL }; 78 } 79 bkey_i_to_s(struct bkey_i * k)80 static inline struct bkey_s bkey_i_to_s(struct bkey_i *k) 81 { 82 return (struct bkey_s) { .k = &k->k, .v = &k->v }; 83 } 84 bkey_i_to_s_c(const struct bkey_i * k)85 static inline struct bkey_s_c bkey_i_to_s_c(const struct bkey_i *k) 86 { 87 return (struct bkey_s_c) { .k = &k->k, .v = &k->v }; 88 } 89 90 /* 91 * For a given type of value (e.g. struct bch_extent), generates the types for 92 * bkey + bch_extent - inline, split, split const - and also all the conversion 93 * functions, which also check that the value is of the correct type. 94 * 95 * We use anonymous unions for upcasting - e.g. converting from e.g. a 96 * bkey_i_extent to a bkey_i - since that's always safe, instead of conversion 97 * functions. 98 */ 99 #define x(name, ...) \ 100 struct bkey_i_##name { \ 101 union { \ 102 struct bkey k; \ 103 struct bkey_i k_i; \ 104 }; \ 105 struct bch_##name v; \ 106 }; \ 107 \ 108 struct bkey_s_c_##name { \ 109 union { \ 110 struct { \ 111 const struct bkey *k; \ 112 const struct bch_##name *v; \ 113 }; \ 114 struct bkey_s_c s_c; \ 115 }; \ 116 }; \ 117 \ 118 struct bkey_s_##name { \ 119 union { \ 120 struct { \ 121 struct bkey *k; \ 122 struct bch_##name *v; \ 123 }; \ 124 struct bkey_s_c_##name c; \ 125 struct bkey_s s; \ 126 struct bkey_s_c s_c; \ 127 }; \ 128 }; \ 129 \ 130 static inline struct bkey_i_##name *bkey_i_to_##name(struct bkey_i *k) \ 131 { \ 132 EBUG_ON(!IS_ERR_OR_NULL(k) && k->k.type != KEY_TYPE_##name); \ 133 return container_of(&k->k, struct bkey_i_##name, k); \ 134 } \ 135 \ 136 static inline const struct bkey_i_##name * \ 137 bkey_i_to_##name##_c(const struct bkey_i *k) \ 138 { \ 139 EBUG_ON(!IS_ERR_OR_NULL(k) && k->k.type != KEY_TYPE_##name); \ 140 return container_of(&k->k, struct bkey_i_##name, k); \ 141 } \ 142 \ 143 static inline struct bkey_s_##name bkey_s_to_##name(struct bkey_s k) \ 144 { \ 145 EBUG_ON(!IS_ERR_OR_NULL(k.k) && k.k->type != KEY_TYPE_##name); \ 146 return (struct bkey_s_##name) { \ 147 .k = k.k, \ 148 .v = container_of(k.v, struct bch_##name, v), \ 149 }; \ 150 } \ 151 \ 152 static inline struct bkey_s_c_##name bkey_s_c_to_##name(struct bkey_s_c k)\ 153 { \ 154 EBUG_ON(!IS_ERR_OR_NULL(k.k) && k.k->type != KEY_TYPE_##name); \ 155 return (struct bkey_s_c_##name) { \ 156 .k = k.k, \ 157 .v = container_of(k.v, struct bch_##name, v), \ 158 }; \ 159 } \ 160 \ 161 static inline struct bkey_s_##name name##_i_to_s(struct bkey_i_##name *k)\ 162 { \ 163 return (struct bkey_s_##name) { \ 164 .k = &k->k, \ 165 .v = &k->v, \ 166 }; \ 167 } \ 168 \ 169 static inline struct bkey_s_c_##name \ 170 name##_i_to_s_c(const struct bkey_i_##name *k) \ 171 { \ 172 return (struct bkey_s_c_##name) { \ 173 .k = &k->k, \ 174 .v = &k->v, \ 175 }; \ 176 } \ 177 \ 178 static inline struct bkey_s_##name bkey_i_to_s_##name(struct bkey_i *k) \ 179 { \ 180 EBUG_ON(!IS_ERR_OR_NULL(k) && k->k.type != KEY_TYPE_##name); \ 181 return (struct bkey_s_##name) { \ 182 .k = &k->k, \ 183 .v = container_of(&k->v, struct bch_##name, v), \ 184 }; \ 185 } \ 186 \ 187 static inline struct bkey_s_c_##name \ 188 bkey_i_to_s_c_##name(const struct bkey_i *k) \ 189 { \ 190 EBUG_ON(!IS_ERR_OR_NULL(k) && k->k.type != KEY_TYPE_##name); \ 191 return (struct bkey_s_c_##name) { \ 192 .k = &k->k, \ 193 .v = container_of(&k->v, struct bch_##name, v), \ 194 }; \ 195 } \ 196 \ 197 static inline struct bkey_i_##name *bkey_##name##_init(struct bkey_i *_k)\ 198 { \ 199 struct bkey_i_##name *k = \ 200 container_of(&_k->k, struct bkey_i_##name, k); \ 201 \ 202 bkey_init(&k->k); \ 203 memset(&k->v, 0, sizeof(k->v)); \ 204 k->k.type = KEY_TYPE_##name; \ 205 set_bkey_val_bytes(&k->k, sizeof(k->v)); \ 206 \ 207 return k; \ 208 } 209 210 BCH_BKEY_TYPES(); 211 #undef x 212 213 #endif /* _BCACHEFS_BKEY_TYPES_H */ 214