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