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