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