Quoting Thomas Tanaka (thomas.tan...@oracle.com): > The following patch fixes memory alignment and endianness > issue while doing a snapshot deletion with btrfs as a > backing store on platform such as sparc. > > The implementation is taken from btrfs-progs. > > Changes since v1: > - include <byteswap.h> for bswap definition > - include defined function name as a comment above BTRFS_SETGET_STACK_FUNCS > > Signed-off-by: Thomas Tanaka <thomas.tan...@oracle.com>
Thanks! Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com> > --- > src/lxc/bdev/lxcbtrfs.c | 28 +++++++++++++++------------- > src/lxc/bdev/lxcbtrfs.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 60 insertions(+), 13 deletions(-) > > diff --git a/src/lxc/bdev/lxcbtrfs.c b/src/lxc/bdev/lxcbtrfs.c > index 2db7c87..0f8c1fc 100644 > --- a/src/lxc/bdev/lxcbtrfs.c > +++ b/src/lxc/bdev/lxcbtrfs.c > @@ -565,7 +565,7 @@ static int btrfs_recursive_destroy(const char *path) > int fd; > struct btrfs_ioctl_search_args args; > struct btrfs_ioctl_search_key *sk = &args.key; > - struct btrfs_ioctl_search_header *sh; > + struct btrfs_ioctl_search_header sh; > struct btrfs_root_ref *ref; > struct my_btrfs_tree *tree; > int ret, i; > @@ -573,6 +573,7 @@ static int btrfs_recursive_destroy(const char *path) > int name_len; > char *name; > char *tmppath; > + u64 dir_id; > > fd = open(path, O_RDONLY); > if (fd < 0) { > @@ -624,21 +625,22 @@ static int btrfs_recursive_destroy(const char *path) > > off = 0; > for (i = 0; i < sk->nr_items; i++) { > - sh = (struct btrfs_ioctl_search_header *)(args.buf + > off); > - off += sizeof(*sh); > + memcpy(&sh, args.buf + off, sizeof(sh)); > + off += sizeof(sh); > /* > * A backref key with the name and dirid of the parent > * comes followed by the reoot ref key which has the > * name of the child subvol in question. > */ > - if (sh->objectid != root_id && sh->type == > BTRFS_ROOT_BACKREF_KEY) { > + if (sh.objectid != root_id && sh.type == > BTRFS_ROOT_BACKREF_KEY) { > ref = (struct btrfs_root_ref *)(args.buf + off); > - name_len = ref->name_len; > + name_len = btrfs_stack_root_ref_name_len(ref); > name = (char *)(ref + 1); > - tmppath = get_btrfs_subvol_path(fd, sh->offset, > - ref->dirid, name, name_len); > - if (!add_btrfs_tree_node(tree, sh->objectid, > - sh->offset, name, > + dir_id = btrfs_stack_root_ref_dirid(ref); > + tmppath = get_btrfs_subvol_path(fd, sh.offset, > + dir_id, name, name_len); > + if (!add_btrfs_tree_node(tree, sh.objectid, > + sh.offset, name, > name_len, tmppath)) { > ERROR("Out of memory"); > free_btrfs_tree(tree); > @@ -648,15 +650,15 @@ static int btrfs_recursive_destroy(const char *path) > } > free(tmppath); > } > - off += sh->len; > + off += sh.len; > > /* > * record the mins in sk so we can make sure the > * next search doesn't repeat this root > */ > - sk->min_objectid = sh->objectid; > - sk->min_type = sh->type; > - sk->min_offset = sh->offset; > + sk->min_objectid = sh.objectid; > + sk->min_type = sh.type; > + sk->min_offset = sh.offset; > } > sk->nr_items = 4096; > sk->min_offset++; > diff --git a/src/lxc/bdev/lxcbtrfs.h b/src/lxc/bdev/lxcbtrfs.h > index e0adb7a..3b2742f 100644 > --- a/src/lxc/bdev/lxcbtrfs.h > +++ b/src/lxc/bdev/lxcbtrfs.h > @@ -28,6 +28,7 @@ > #include <linux/types.h> /* __le64, __l32 ... */ > #include <stdbool.h> > #include <stdint.h> > +#include <byteswap.h> > > typedef uint8_t u8; > typedef uint16_t u16; > @@ -317,6 +318,50 @@ struct btrfs_ioctl_ino_lookup_args { > #define BTRFS_LAST_FREE_OBJECTID -256ULL > #define BTRFS_FIRST_CHUNK_TREE_OBJECTID 256ULL > > +/* > + * The followings are macro for correctly getting member of > + * structures in both low and big endian platforms as per > + * btrfs-progs > + */ > +#ifdef __CHECKER__ > +#define __force __attribute__((force)) > +#else > +#define __force > +#endif > + > +#if __BYTE_ORDER == __BIG_ENDIAN > +#define cpu_to_le64(x) ((__force __le64)(u64)(bswap_64(x))) > +#define le64_to_cpu(x) ((__force u64)(__le64)(bswap_64(x))) > +#define cpu_to_le32(x) ((__force __le32)(u32)(bswap_32(x))) > +#define le32_to_cpu(x) ((__force u32)(__le32)(bswap_32(x))) > +#define cpu_to_le16(x) ((__force __le16)(u16)(bswap_16(x))) > +#define le16_to_cpu(x) ((__force u16)(__le16)(bswap_16(x))) > +#else > +#define cpu_to_le64(x) ((__force __le64)(u64)(x)) > +#define le64_to_cpu(x) ((__force u64)(__le64)(x)) > +#define cpu_to_le32(x) ((__force __le32)(u32)(x)) > +#define le32_to_cpu(x) ((__force u32)(__le32)(x)) > +#define cpu_to_le16(x) ((__force __le16)(u16)(x)) > +#define le16_to_cpu(x) ((__force u16)(__le16)(x)) > +#endif > + > +#define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ > +static inline u##bits btrfs_##name(type *s) \ > +{ \ > + return le##bits##_to_cpu(s->member); \ > +} \ > +static inline void btrfs_set_##name(type *s, u##bits val) \ > +{ \ > + s->member = cpu_to_le##bits(val); \ > +} > + > +/* defined as btrfs_stack_root_ref_dirid */ > +BTRFS_SETGET_STACK_FUNCS(stack_root_ref_dirid, struct btrfs_root_ref, dirid, > 64); > +/* defined as btrfs_stack_root_ref_sequence */ > +BTRFS_SETGET_STACK_FUNCS(stack_root_ref_sequence, struct btrfs_root_ref, > sequence, 64); > +/* defined as btrfs_stack_root_ref_name_len */ > +BTRFS_SETGET_STACK_FUNCS(stack_root_ref_name_len, struct btrfs_root_ref, > name_len, 16); > + > /* defined in bdev.h */ > struct bdev; > > -- > 1.7.1 > > _______________________________________________ > lxc-devel mailing list > lxc-devel@lists.linuxcontainers.org > http://lists.linuxcontainers.org/listinfo/lxc-devel _______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel