1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */ 2597b4affSMarek Behún /* 3597b4affSMarek Behún * Functions to convert BTRFS structures from disk to CPU endianness and back. 4597b4affSMarek Behún * 5597b4affSMarek Behún * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz 6597b4affSMarek Behún */ 7597b4affSMarek Behún 8597b4affSMarek Behún #ifndef __BTRFS_CONV_FUNCS_H__ 9597b4affSMarek Behún #define __BTRFS_CONV_FUNCS_H__ 10597b4affSMarek Behún 11597b4affSMarek Behún #include "ctree.h" 12597b4affSMarek Behún #include <u-boot/variadic-macro.h> 13597b4affSMarek Behún #include <asm/byteorder.h> 14597b4affSMarek Behún 15597b4affSMarek Behún /* We are using variadic macros and C11 _Generic to achieve compact code. 16597b4affSMarek Behún 17597b4affSMarek Behún We want to define macro DEFINE_CONV(x, ...), where the first argument is the 18597b4affSMarek Behún name of the structure for which it shall define conversion functions (the 19597b4affSMarek Behún names of the functions shall be x_to_cpu and x_to_disk), and the other 20597b4affSMarek Behún arguments are names of the members on which the functions shall do 21597b4affSMarek Behún endianness conversion. */ 22597b4affSMarek Behún 23597b4affSMarek Behún #if defined(__LITTLE_ENDIAN) 24597b4affSMarek Behún 25597b4affSMarek Behún /* If the target machine is little endian, the conversion functions do 26597b4affSMarek Behún nothing, since the on disk format is little endian. */ 27597b4affSMarek Behún 28597b4affSMarek Behún # define DEFINE_CONV(n,...) \ 29597b4affSMarek Behún static inline struct n *n##_to_disk(struct n * r) \ 30597b4affSMarek Behún { \ 31597b4affSMarek Behún return r; \ 32597b4affSMarek Behún } \ 33597b4affSMarek Behún static inline struct n *n##_to_cpu(struct n * r) \ 34597b4affSMarek Behún { \ 35597b4affSMarek Behún return r; \ 36597b4affSMarek Behún } 37597b4affSMarek Behún 38597b4affSMarek Behún # define DEFINE_CONV_ALT(n,a,...) \ 39597b4affSMarek Behún static inline struct n *n##_to_disk_##a(struct n * r) \ 40597b4affSMarek Behún { \ 41597b4affSMarek Behún return r; \ 42597b4affSMarek Behún } \ 43597b4affSMarek Behún static inline struct n *n##_to_cpu_##a(struct n * r) \ 44597b4affSMarek Behún { \ 45597b4affSMarek Behún return r; \ 46597b4affSMarek Behún } 47597b4affSMarek Behún 48597b4affSMarek Behún #else /* !defined(__LITTLE_ENDIAN) */ 49597b4affSMarek Behún 50597b4affSMarek Behún /* Some structures contain not only scalar members, but compound types as well 51597b4affSMarek Behún (for example, struct btrfs_inode_item contains members of type struct 52597b4affSMarek Behún btrfs_timespec. 53597b4affSMarek Behún 54597b4affSMarek Behún For these members we want to call the conversion function recursively, so 55597b4affSMarek Behún first we declare the functions taking pointers to this types (these function 56597b4affSMarek Behún will be defined later by the DEFINE_CONV macro) and then we define 57597b4affSMarek Behún correspond functions taking non-pointers, so that they can be used in the 58597b4affSMarek Behún expansion of the _Generic. */ 59597b4affSMarek Behún # define DEFINE_CONV_FOR_STRUCT(n) \ 60597b4affSMarek Behún static inline struct n * n##_to_disk(struct n *); \ 61597b4affSMarek Behún static inline struct n * n##_to_cpu(struct n *); \ 62597b4affSMarek Behún static inline struct n n##_to_disk_v(struct n x) { \ 63597b4affSMarek Behún return *n##_to_disk(&x); \ 64597b4affSMarek Behún } \ 65597b4affSMarek Behún static inline struct n n##_to_cpu_v(struct n x) { \ 66597b4affSMarek Behún return *n##_to_cpu(&x); \ 67597b4affSMarek Behún } 68597b4affSMarek Behún 69597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_key) 70597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_stripe) 71597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_timespec) 72597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_inode_item) 73597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_root_backup) 74597b4affSMarek Behún DEFINE_CONV_FOR_STRUCT(btrfs_dev_item) 75597b4affSMarek Behún 76597b4affSMarek Behún /* Now define the _Generic for both CPU to LE and LE to CPU */ 77597b4affSMarek Behún # define DEFINE_CONV_CPU_TO_LE(x) \ 78597b4affSMarek Behún (d->x) = _Generic((d->x), \ 79597b4affSMarek Behún __u16: cpu_to_le16, \ 80597b4affSMarek Behún __u32: cpu_to_le32, \ 81597b4affSMarek Behún __u64: cpu_to_le64, \ 82597b4affSMarek Behún struct btrfs_key: btrfs_key_to_disk_v, \ 83597b4affSMarek Behún struct btrfs_stripe: btrfs_stripe_to_disk_v, \ 84597b4affSMarek Behún struct btrfs_timespec: btrfs_timespec_to_disk_v, \ 85597b4affSMarek Behún struct btrfs_inode_item: btrfs_inode_item_to_disk_v, \ 86597b4affSMarek Behún struct btrfs_root_backup: btrfs_root_backup_to_disk_v, \ 87597b4affSMarek Behún struct btrfs_dev_item: btrfs_dev_item_to_disk_v \ 88597b4affSMarek Behún )((d->x)); 89597b4affSMarek Behún 90597b4affSMarek Behún # define DEFINE_CONV_LE_TO_CPU(x) \ 91597b4affSMarek Behún (d->x) = _Generic((d->x), \ 92597b4affSMarek Behún __u16: le16_to_cpu, \ 93597b4affSMarek Behún __u32: le32_to_cpu, \ 94597b4affSMarek Behún __u64: le64_to_cpu, \ 95597b4affSMarek Behún struct btrfs_key: btrfs_key_to_cpu_v, \ 96597b4affSMarek Behún struct btrfs_stripe: btrfs_stripe_to_cpu_v, \ 97597b4affSMarek Behún struct btrfs_timespec: btrfs_timespec_to_cpu_v, \ 98597b4affSMarek Behún struct btrfs_inode_item: btrfs_inode_item_to_cpu_v, \ 99597b4affSMarek Behún struct btrfs_root_backup: btrfs_root_backup_to_cpu_v, \ 100597b4affSMarek Behún struct btrfs_dev_item: btrfs_dev_item_to_cpu_v \ 101597b4affSMarek Behún )((d->x)); 102597b4affSMarek Behún 103597b4affSMarek Behún # define DEFINE_CONV_ONE(t,n,m,...) \ 104597b4affSMarek Behún static inline struct t * n(struct t * d) { \ 105597b4affSMarek Behún CALL_MACRO_FOR_EACH(m, ##__VA_ARGS__) \ 106597b4affSMarek Behún return d; \ 107597b4affSMarek Behún } 108597b4affSMarek Behún 109597b4affSMarek Behún /* Finally define the DEFINE_CONV macro */ 110597b4affSMarek Behún # define DEFINE_CONV(n,...) \ 111597b4affSMarek Behún DEFINE_CONV_ONE(n,n##_to_disk,DEFINE_CONV_CPU_TO_LE,##__VA_ARGS__) \ 112597b4affSMarek Behún DEFINE_CONV_ONE(n,n##_to_cpu,DEFINE_CONV_LE_TO_CPU,##__VA_ARGS__) 113597b4affSMarek Behún 114597b4affSMarek Behún # define DEFINE_CONV_ALT(n,a,...) \ 115597b4affSMarek Behún DEFINE_CONV_ONE(n,n##_to_disk_##a,DEFINE_CONV_CPU_TO_LE, \ 116597b4affSMarek Behún ##__VA_ARGS__) \ 117597b4affSMarek Behún DEFINE_CONV_ONE(n,n##_to_cpu_##a,DEFINE_CONV_LE_TO_CPU,##__VA_ARGS__) 118597b4affSMarek Behún 119597b4affSMarek Behún #endif /* !defined(__LITTLE_ENDIAN) */ 120597b4affSMarek Behún 121597b4affSMarek Behún DEFINE_CONV(btrfs_key, objectid, offset) 122597b4affSMarek Behún DEFINE_CONV(btrfs_dev_item, devid, total_bytes, bytes_used, io_align, io_width, 123597b4affSMarek Behún sector_size, type, generation, start_offset, dev_group) 124597b4affSMarek Behún DEFINE_CONV(btrfs_stripe, devid, offset) 125597b4affSMarek Behún DEFINE_CONV(btrfs_chunk, length, owner, stripe_len, type, io_align, io_width, 126597b4affSMarek Behún sector_size, num_stripes, sub_stripes) 127597b4affSMarek Behún DEFINE_CONV(btrfs_free_space_entry, offset, bytes) 128597b4affSMarek Behún DEFINE_CONV(btrfs_free_space_header, location, generation, num_entries, 129597b4affSMarek Behún num_bitmaps) 130597b4affSMarek Behún DEFINE_CONV(btrfs_extent_item, refs, generation, flags) 131597b4affSMarek Behún DEFINE_CONV(btrfs_tree_block_info, key) 132597b4affSMarek Behún DEFINE_CONV(btrfs_extent_data_ref, root, objectid, offset, count) 133597b4affSMarek Behún DEFINE_CONV(btrfs_shared_data_ref, count) 134597b4affSMarek Behún DEFINE_CONV(btrfs_extent_inline_ref, offset) 135597b4affSMarek Behún DEFINE_CONV(btrfs_dev_extent, chunk_tree, chunk_objectid, chunk_offset, length) 136597b4affSMarek Behún DEFINE_CONV(btrfs_inode_ref, index, name_len) 137597b4affSMarek Behún DEFINE_CONV(btrfs_inode_extref, parent_objectid, index, name_len) 138597b4affSMarek Behún DEFINE_CONV(btrfs_timespec, sec, nsec) 139597b4affSMarek Behún DEFINE_CONV(btrfs_inode_item, generation, transid, size, nbytes, block_group, 140597b4affSMarek Behún nlink, uid, gid, mode, rdev, flags, sequence, atime, ctime, mtime, 141597b4affSMarek Behún otime) 142597b4affSMarek Behún DEFINE_CONV(btrfs_dir_log_item, end) 143597b4affSMarek Behún DEFINE_CONV(btrfs_dir_item, location, transid, data_len, name_len) 144597b4affSMarek Behún DEFINE_CONV(btrfs_root_item, inode, generation, root_dirid, bytenr, byte_limit, 145597b4affSMarek Behún bytes_used, last_snapshot, flags, refs, drop_progress, 146597b4affSMarek Behún generation_v2, ctransid, otransid, stransid, rtransid, ctime, 147597b4affSMarek Behún otime, stime, rtime) 148597b4affSMarek Behún DEFINE_CONV(btrfs_root_ref, dirid, sequence, name_len) 149597b4affSMarek Behún DEFINE_CONV(btrfs_file_extent_item, generation, ram_bytes, other_encoding, 150597b4affSMarek Behún disk_bytenr, disk_num_bytes, offset, num_bytes) 151597b4affSMarek Behún DEFINE_CONV_ALT(btrfs_file_extent_item, inl, generation, ram_bytes, 152597b4affSMarek Behún other_encoding) 153597b4affSMarek Behún DEFINE_CONV(btrfs_dev_replace_item, src_devid, cursor_left, cursor_right, 154597b4affSMarek Behún cont_reading_from_srcdev_mode, replace_state, time_started, 155597b4affSMarek Behún time_stopped, num_write_errors, num_uncorrectable_read_errors) 156597b4affSMarek Behún DEFINE_CONV(btrfs_block_group_item, used, chunk_objectid, flags) 157597b4affSMarek Behún DEFINE_CONV(btrfs_free_space_info, extent_count, flags) 158597b4affSMarek Behún 159597b4affSMarek Behún DEFINE_CONV(btrfs_header, bytenr, flags, generation, owner, nritems) 160597b4affSMarek Behún DEFINE_CONV(btrfs_root_backup, tree_root, tree_root_gen, chunk_root, 161597b4affSMarek Behún chunk_root_gen, extent_root, extent_root_gen, fs_root, fs_root_gen, 162597b4affSMarek Behún dev_root, dev_root_gen, csum_root, csum_root_gen, total_bytes, 163597b4affSMarek Behún bytes_used, num_devices) 164597b4affSMarek Behún DEFINE_CONV(btrfs_super_block, bytenr, flags, magic, generation, root, 165597b4affSMarek Behún chunk_root, log_root, log_root_transid, total_bytes, bytes_used, 166597b4affSMarek Behún root_dir_objectid, num_devices, sectorsize, nodesize, 167597b4affSMarek Behún __unused_leafsize, stripesize, sys_chunk_array_size, 168597b4affSMarek Behún chunk_root_generation, compat_flags, compat_ro_flags, 169597b4affSMarek Behún incompat_flags, csum_type, dev_item, cache_generation, 170597b4affSMarek Behún uuid_tree_generation, super_roots[0], super_roots[1], 171597b4affSMarek Behún super_roots[2], super_roots[3]) 172597b4affSMarek Behún DEFINE_CONV(btrfs_item, key, offset, size) 173597b4affSMarek Behún DEFINE_CONV(btrfs_key_ptr, key, blockptr, generation) 174597b4affSMarek Behún 175597b4affSMarek Behún #endif /* __BTRFS_CONV_FUNCS_H__ */ 176