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