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 | |
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 | |
22 | static inline size_t bkey_val_bytes(const struct bkey *k) |
23 | { |
24 | return bkey_val_u64s(k) * sizeof(u64); |
25 | } |
26 | |
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 | |
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 | |
70 | static inline struct bkey_s bkey_to_s(struct bkey *k) |
71 | { |
72 | return (struct bkey_s) { .k = k, .v = NULL }; |
73 | } |
74 | |
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 | |
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 | |
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 | |