]> git.sur5r.net Git - u-boot/blob - fs/btrfs/conv-funcs.h
lib: Add hexdump
[u-boot] / fs / btrfs / conv-funcs.h
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Functions to convert BTRFS structures from disk to CPU endianness and back.
4  *
5  * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
6  */
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
69 DEFINE_CONV_FOR_STRUCT(btrfs_key)
70 DEFINE_CONV_FOR_STRUCT(btrfs_stripe)
71 DEFINE_CONV_FOR_STRUCT(btrfs_timespec)
72 DEFINE_CONV_FOR_STRUCT(btrfs_inode_item)
73 DEFINE_CONV_FOR_STRUCT(btrfs_root_backup)
74 DEFINE_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
121 DEFINE_CONV(btrfs_key, objectid, offset)
122 DEFINE_CONV(btrfs_dev_item, devid, total_bytes, bytes_used, io_align, io_width,
123             sector_size, type, generation, start_offset, dev_group)
124 DEFINE_CONV(btrfs_stripe, devid, offset)
125 DEFINE_CONV(btrfs_chunk, length, owner, stripe_len, type, io_align, io_width,
126             sector_size, num_stripes, sub_stripes)
127 DEFINE_CONV(btrfs_free_space_entry, offset, bytes)
128 DEFINE_CONV(btrfs_free_space_header, location, generation, num_entries,
129             num_bitmaps)
130 DEFINE_CONV(btrfs_extent_item, refs, generation, flags)
131 DEFINE_CONV(btrfs_tree_block_info, key)
132 DEFINE_CONV(btrfs_extent_data_ref, root, objectid, offset, count)
133 DEFINE_CONV(btrfs_shared_data_ref, count)
134 DEFINE_CONV(btrfs_extent_inline_ref, offset)
135 DEFINE_CONV(btrfs_dev_extent, chunk_tree, chunk_objectid, chunk_offset, length)
136 DEFINE_CONV(btrfs_inode_ref, index, name_len)
137 DEFINE_CONV(btrfs_inode_extref, parent_objectid, index, name_len)
138 DEFINE_CONV(btrfs_timespec, sec, nsec)
139 DEFINE_CONV(btrfs_inode_item, generation, transid, size, nbytes, block_group,
140             nlink, uid, gid, mode, rdev, flags, sequence, atime, ctime, mtime,
141             otime)
142 DEFINE_CONV(btrfs_dir_log_item, end)
143 DEFINE_CONV(btrfs_dir_item, location, transid, data_len, name_len)
144 DEFINE_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)
148 DEFINE_CONV(btrfs_root_ref, dirid, sequence, name_len)
149 DEFINE_CONV(btrfs_file_extent_item, generation, ram_bytes, other_encoding,
150             disk_bytenr, disk_num_bytes, offset, num_bytes)
151 DEFINE_CONV_ALT(btrfs_file_extent_item, inl, generation, ram_bytes,
152                 other_encoding)
153 DEFINE_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)
156 DEFINE_CONV(btrfs_block_group_item, used, chunk_objectid, flags)
157 DEFINE_CONV(btrfs_free_space_info, extent_count, flags)
158
159 DEFINE_CONV(btrfs_header, bytenr, flags, generation, owner, nritems)
160 DEFINE_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)
164 DEFINE_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])
172 DEFINE_CONV(btrfs_item, key, offset, size)
173 DEFINE_CONV(btrfs_key_ptr, key, blockptr, generation)
174
175 #endif /* __BTRFS_CONV_FUNCS_H__ */