brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · c9ae9e4 Raw
214 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _BCACHEFS_BKEY_TYPES_H3#define _BCACHEFS_BKEY_TYPES_H4 5#include "bcachefs_format.h"6 7/*8 * bkey_i	- bkey with inline value9 * bkey_s	- bkey with split value10 * bkey_s_c	- bkey with split value, const11 */12 13#define bkey_p_next(_k)		vstruct_next(_k)14 15static 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 22static inline size_t bkey_val_bytes(const struct bkey *k)23{24	return bkey_val_u64s(k) * sizeof(u64);25}26 27static 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 35static 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 */48struct bkey_s_c {49	const struct bkey	*k;50	const struct bch_val	*v;51};52 53/* bkey with split value */54struct 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 70static inline struct bkey_s bkey_to_s(struct bkey *k)71{72	return (struct bkey_s) { .k = k, .v = NULL };73}74 75static 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 80static 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 85static 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 for92 * bkey + bch_extent - inline, split, split const - and also all the conversion93 * 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. a96 * bkey_i_extent to a bkey_i - since that's always safe, instead of conversion97 * functions.98 */99#define x(name, ...)					\100struct bkey_i_##name {							\101	union {								\102		struct bkey		k;				\103		struct bkey_i		k_i;				\104	};								\105	struct bch_##name		v;				\106};									\107									\108struct 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									\118struct 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									\130static 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									\136static inline const struct bkey_i_##name *				\137bkey_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									\143static 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									\152static 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									\161static 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									\169static inline struct bkey_s_c_##name					\170name##_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									\178static 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									\187static inline struct bkey_s_c_##name					\188bkey_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									\197static 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 210BCH_BKEY_TYPES();211#undef x212 213#endif /* _BCACHEFS_BKEY_TYPES_H */214