uboot/fs/btrfs/conv-funcs.h
<<
>>
Prefs
   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
  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__ */
 176