xref: /openbmc/u-boot/fs/btrfs/conv-funcs.h (revision 597b4aff7b5d85946d2028ab9498116f53357dbc)
1*597b4affSMarek Behún /*
2*597b4affSMarek Behún  * Functions to convert BTRFS structures from disk to CPU endianness and back.
3*597b4affSMarek Behún  *
4*597b4affSMarek Behún  * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
5*597b4affSMarek Behún  *
6*597b4affSMarek Behún  * SPDX-License-Identifier:	GPL-2.0+
7*597b4affSMarek Behún  */
8*597b4affSMarek Behún 
9*597b4affSMarek Behún #ifndef __BTRFS_CONV_FUNCS_H__
10*597b4affSMarek Behún #define __BTRFS_CONV_FUNCS_H__
11*597b4affSMarek Behún 
12*597b4affSMarek Behún #include "ctree.h"
13*597b4affSMarek Behún #include <u-boot/variadic-macro.h>
14*597b4affSMarek Behún #include <asm/byteorder.h>
15*597b4affSMarek Behún 
16*597b4affSMarek Behún /* We are using variadic macros and C11 _Generic to achieve compact code.
17*597b4affSMarek Behún 
18*597b4affSMarek Behún    We want to define macro DEFINE_CONV(x, ...), where the first argument is the
19*597b4affSMarek Behún    name of the structure for which it shall define conversion functions (the
20*597b4affSMarek Behún    names of the functions shall be x_to_cpu and x_to_disk), and the other
21*597b4affSMarek Behún    arguments are names of the members on which the functions shall do
22*597b4affSMarek Behún    endianness conversion. */
23*597b4affSMarek Behún 
24*597b4affSMarek Behún #if defined(__LITTLE_ENDIAN)
25*597b4affSMarek Behún 
26*597b4affSMarek Behún /* If the target machine is little endian, the conversion functions do
27*597b4affSMarek Behún    nothing, since the on disk format is little endian. */
28*597b4affSMarek Behún 
29*597b4affSMarek Behún # define DEFINE_CONV(n,...)					\
30*597b4affSMarek Behún 	static inline struct n *n##_to_disk(struct n * r)	\
31*597b4affSMarek Behún 	{							\
32*597b4affSMarek Behún 		return r;					\
33*597b4affSMarek Behún 	}							\
34*597b4affSMarek Behún 	static inline struct n *n##_to_cpu(struct n * r)	\
35*597b4affSMarek Behún 	{							\
36*597b4affSMarek Behún 		return r;					\
37*597b4affSMarek Behún 	}
38*597b4affSMarek Behún 
39*597b4affSMarek Behún # define DEFINE_CONV_ALT(n,a,...)				\
40*597b4affSMarek Behún 	static inline struct n *n##_to_disk_##a(struct n * r)	\
41*597b4affSMarek Behún 	{							\
42*597b4affSMarek Behún 		return r;					\
43*597b4affSMarek Behún 	}							\
44*597b4affSMarek Behún 	static inline struct n *n##_to_cpu_##a(struct n * r)	\
45*597b4affSMarek Behún 	{							\
46*597b4affSMarek Behún 		return r;					\
47*597b4affSMarek Behún 	}
48*597b4affSMarek Behún 
49*597b4affSMarek Behún #else /* !defined(__LITTLE_ENDIAN) */
50*597b4affSMarek Behún 
51*597b4affSMarek Behún /* Some structures contain not only scalar members, but compound types as well
52*597b4affSMarek Behún    (for example, struct btrfs_inode_item contains members of type struct
53*597b4affSMarek Behún    btrfs_timespec.
54*597b4affSMarek Behún 
55*597b4affSMarek Behún    For these members we want to call the conversion function recursively, so
56*597b4affSMarek Behún    first we declare the functions taking pointers to this types (these function
57*597b4affSMarek Behún    will be defined later by the DEFINE_CONV macro) and then we define
58*597b4affSMarek Behún    correspond functions taking non-pointers, so that they can be used in the
59*597b4affSMarek Behún    expansion of the _Generic. */
60*597b4affSMarek Behún # define DEFINE_CONV_FOR_STRUCT(n)				\
61*597b4affSMarek Behún 	static inline struct n * n##_to_disk(struct n *);	\
62*597b4affSMarek Behún 	static inline struct n * n##_to_cpu(struct n *);	\
63*597b4affSMarek Behún 	static inline struct n n##_to_disk_v(struct n x) {	\
64*597b4affSMarek Behún 		return *n##_to_disk(&x);			\
65*597b4affSMarek Behún 	}							\
66*597b4affSMarek Behún 	static inline struct n n##_to_cpu_v(struct n x) {	\
67*597b4affSMarek Behún 		return *n##_to_cpu(&x);				\
68*597b4affSMarek Behún 	}
69*597b4affSMarek Behún 
70*597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_key)
71*597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_stripe)
72*597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_timespec)
73*597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_inode_item)
74*597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_root_backup)
75*597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_dev_item)
76*597b4affSMarek Behún 
77*597b4affSMarek Behún /* Now define the _Generic for both CPU to LE and LE to CPU */
78*597b4affSMarek Behún # define DEFINE_CONV_CPU_TO_LE(x)					\
79*597b4affSMarek Behún 	(d->x) = _Generic((d->x),					\
80*597b4affSMarek Behún 		__u16: cpu_to_le16,					\
81*597b4affSMarek Behún 		__u32: cpu_to_le32,					\
82*597b4affSMarek Behún 		__u64: cpu_to_le64,					\
83*597b4affSMarek Behún 		struct btrfs_key: btrfs_key_to_disk_v,			\
84*597b4affSMarek Behún 		struct btrfs_stripe: btrfs_stripe_to_disk_v,		\
85*597b4affSMarek Behún 		struct btrfs_timespec: btrfs_timespec_to_disk_v,	\
86*597b4affSMarek Behún 		struct btrfs_inode_item: btrfs_inode_item_to_disk_v,	\
87*597b4affSMarek Behún 		struct btrfs_root_backup: btrfs_root_backup_to_disk_v,	\
88*597b4affSMarek Behún 		struct btrfs_dev_item: btrfs_dev_item_to_disk_v		\
89*597b4affSMarek Behún 		)((d->x));
90*597b4affSMarek Behún 
91*597b4affSMarek Behún # define DEFINE_CONV_LE_TO_CPU(x)					\
92*597b4affSMarek Behún 	(d->x) = _Generic((d->x),					\
93*597b4affSMarek Behún 		__u16: le16_to_cpu,					\
94*597b4affSMarek Behún 		__u32: le32_to_cpu,					\
95*597b4affSMarek Behún 		__u64: le64_to_cpu,					\
96*597b4affSMarek Behún 		struct btrfs_key: btrfs_key_to_cpu_v,			\
97*597b4affSMarek Behún 		struct btrfs_stripe: btrfs_stripe_to_cpu_v,		\
98*597b4affSMarek Behún 		struct btrfs_timespec: btrfs_timespec_to_cpu_v,		\
99*597b4affSMarek Behún 		struct btrfs_inode_item: btrfs_inode_item_to_cpu_v,	\
100*597b4affSMarek Behún 		struct btrfs_root_backup: btrfs_root_backup_to_cpu_v,	\
101*597b4affSMarek Behún 		struct btrfs_dev_item: btrfs_dev_item_to_cpu_v		\
102*597b4affSMarek Behún 		)((d->x));
103*597b4affSMarek Behún 
104*597b4affSMarek Behún # define DEFINE_CONV_ONE(t,n,m,...)			\
105*597b4affSMarek Behún 	static inline struct t * n(struct t * d) {	\
106*597b4affSMarek Behún 		CALL_MACRO_FOR_EACH(m, ##__VA_ARGS__)	\
107*597b4affSMarek Behún 		return d;				\
108*597b4affSMarek Behún 	}
109*597b4affSMarek Behún 
110*597b4affSMarek Behún /* Finally define the DEFINE_CONV macro */
111*597b4affSMarek Behún # define DEFINE_CONV(n,...) \
112*597b4affSMarek Behún 	DEFINE_CONV_ONE(n,n##_to_disk,DEFINE_CONV_CPU_TO_LE,##__VA_ARGS__) \
113*597b4affSMarek Behún 	DEFINE_CONV_ONE(n,n##_to_cpu,DEFINE_CONV_LE_TO_CPU,##__VA_ARGS__)
114*597b4affSMarek Behún 
115*597b4affSMarek Behún # define DEFINE_CONV_ALT(n,a,...) \
116*597b4affSMarek Behún 	DEFINE_CONV_ONE(n,n##_to_disk_##a,DEFINE_CONV_CPU_TO_LE, \
117*597b4affSMarek Behún 		##__VA_ARGS__) \
118*597b4affSMarek Behún 	DEFINE_CONV_ONE(n,n##_to_cpu_##a,DEFINE_CONV_LE_TO_CPU,##__VA_ARGS__)
119*597b4affSMarek Behún 
120*597b4affSMarek Behún #endif /* !defined(__LITTLE_ENDIAN) */
121*597b4affSMarek Behún 
122*597b4affSMarek Behún DEFINE_CONV(btrfs_key, objectid, offset)
123*597b4affSMarek Behún DEFINE_CONV(btrfs_dev_item, devid, total_bytes, bytes_used, io_align, io_width,
124*597b4affSMarek Behún 	    sector_size, type, generation, start_offset, dev_group)
125*597b4affSMarek Behún DEFINE_CONV(btrfs_stripe, devid, offset)
126*597b4affSMarek Behún DEFINE_CONV(btrfs_chunk, length, owner, stripe_len, type, io_align, io_width,
127*597b4affSMarek Behún 	    sector_size, num_stripes, sub_stripes)
128*597b4affSMarek Behún DEFINE_CONV(btrfs_free_space_entry, offset, bytes)
129*597b4affSMarek Behún DEFINE_CONV(btrfs_free_space_header, location, generation, num_entries,
130*597b4affSMarek Behún 	    num_bitmaps)
131*597b4affSMarek Behún DEFINE_CONV(btrfs_extent_item, refs, generation, flags)
132*597b4affSMarek Behún DEFINE_CONV(btrfs_tree_block_info, key)
133*597b4affSMarek Behún DEFINE_CONV(btrfs_extent_data_ref, root, objectid, offset, count)
134*597b4affSMarek Behún DEFINE_CONV(btrfs_shared_data_ref, count)
135*597b4affSMarek Behún DEFINE_CONV(btrfs_extent_inline_ref, offset)
136*597b4affSMarek Behún DEFINE_CONV(btrfs_dev_extent, chunk_tree, chunk_objectid, chunk_offset, length)
137*597b4affSMarek Behún DEFINE_CONV(btrfs_inode_ref, index, name_len)
138*597b4affSMarek Behún DEFINE_CONV(btrfs_inode_extref, parent_objectid, index, name_len)
139*597b4affSMarek Behún DEFINE_CONV(btrfs_timespec, sec, nsec)
140*597b4affSMarek Behún DEFINE_CONV(btrfs_inode_item, generation, transid, size, nbytes, block_group,
141*597b4affSMarek Behún 	    nlink, uid, gid, mode, rdev, flags, sequence, atime, ctime, mtime,
142*597b4affSMarek Behún 	    otime)
143*597b4affSMarek Behún DEFINE_CONV(btrfs_dir_log_item, end)
144*597b4affSMarek Behún DEFINE_CONV(btrfs_dir_item, location, transid, data_len, name_len)
145*597b4affSMarek Behún DEFINE_CONV(btrfs_root_item, inode, generation, root_dirid, bytenr, byte_limit,
146*597b4affSMarek Behún 	    bytes_used, last_snapshot, flags, refs, drop_progress,
147*597b4affSMarek Behún 	    generation_v2, ctransid, otransid, stransid, rtransid, ctime,
148*597b4affSMarek Behún 	    otime, stime, rtime)
149*597b4affSMarek Behún DEFINE_CONV(btrfs_root_ref, dirid, sequence, name_len)
150*597b4affSMarek Behún DEFINE_CONV(btrfs_file_extent_item, generation, ram_bytes, other_encoding,
151*597b4affSMarek Behún 	    disk_bytenr, disk_num_bytes, offset, num_bytes)
152*597b4affSMarek Behún DEFINE_CONV_ALT(btrfs_file_extent_item, inl, generation, ram_bytes,
153*597b4affSMarek Behún 		other_encoding)
154*597b4affSMarek Behún DEFINE_CONV(btrfs_dev_replace_item, src_devid, cursor_left, cursor_right,
155*597b4affSMarek Behún 	    cont_reading_from_srcdev_mode, replace_state, time_started,
156*597b4affSMarek Behún 	    time_stopped, num_write_errors, num_uncorrectable_read_errors)
157*597b4affSMarek Behún DEFINE_CONV(btrfs_block_group_item, used, chunk_objectid, flags)
158*597b4affSMarek Behún DEFINE_CONV(btrfs_free_space_info, extent_count, flags)
159*597b4affSMarek Behún 
160*597b4affSMarek Behún DEFINE_CONV(btrfs_header, bytenr, flags, generation, owner, nritems)
161*597b4affSMarek Behún DEFINE_CONV(btrfs_root_backup, tree_root, tree_root_gen, chunk_root,
162*597b4affSMarek Behún 	    chunk_root_gen, extent_root, extent_root_gen, fs_root, fs_root_gen,
163*597b4affSMarek Behún 	    dev_root, dev_root_gen, csum_root, csum_root_gen, total_bytes,
164*597b4affSMarek Behún 	    bytes_used, num_devices)
165*597b4affSMarek Behún DEFINE_CONV(btrfs_super_block, bytenr, flags, magic, generation, root,
166*597b4affSMarek Behún 	    chunk_root, log_root, log_root_transid, total_bytes, bytes_used,
167*597b4affSMarek Behún 	    root_dir_objectid, num_devices, sectorsize, nodesize,
168*597b4affSMarek Behún 	    __unused_leafsize, stripesize, sys_chunk_array_size,
169*597b4affSMarek Behún 	    chunk_root_generation, compat_flags, compat_ro_flags,
170*597b4affSMarek Behún 	    incompat_flags, csum_type, dev_item, cache_generation,
171*597b4affSMarek Behún 	    uuid_tree_generation, super_roots[0], super_roots[1],
172*597b4affSMarek Behún 	    super_roots[2], super_roots[3])
173*597b4affSMarek Behún DEFINE_CONV(btrfs_item, key, offset, size)
174*597b4affSMarek Behún DEFINE_CONV(btrfs_key_ptr, key, blockptr, generation)
175*597b4affSMarek Behún 
176*597b4affSMarek Behún #endif /* __BTRFS_CONV_FUNCS_H__ */
177