xref: /linux/fs/bcachefs/bkey_types.h (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
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