diff -uNr btrfs-progs-0.20-rc1.orig/btrfs-list.c btrfs-progs-0.20-rc1/btrfs-list.c --- btrfs-progs-0.20-rc1.orig/btrfs-list.c 2012-12-04 20:40:40.576142017 +0100 +++ btrfs-progs-0.20-rc1/btrfs-list.c 2012-12-04 20:46:53.544650126 +0100 @@ -324,7 +324,7 @@ int ret; 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; unsigned long off = 0; u64 max_found = 0; int i; @@ -375,22 +375,21 @@ off = 0; for (i = 0; i < sk->nr_items; i++) { struct btrfs_root_item *item; - sh = (struct btrfs_ioctl_search_header *)(args.buf + - off); - off += sizeof(*sh); + memcpy(&sh, args.buf + off, sizeof(sh)); + off += sizeof(sh); item = (struct btrfs_root_item *)(args.buf + off); - off += sh->len; + off += sh.len; - 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; - if (sh->objectid > ino_args.treeid) + if (sh.objectid > ino_args.treeid) break; - if (sh->objectid == ino_args.treeid && - sh->type == BTRFS_ROOT_ITEM_KEY) { + if (sh.objectid == ino_args.treeid && + sh.type == BTRFS_ROOT_ITEM_KEY) { max_found = max(max_found, btrfs_root_generation(item)); } @@ -519,9 +518,9 @@ off = 0; sh = (struct btrfs_ioctl_search_header *)(args.buf + off); - if (sh->type == BTRFS_INODE_REF_KEY) { + if (sh.type == BTRFS_INODE_REF_KEY) { struct btrfs_inode_ref *ref; - dirid = sh->offset; + dirid = sh.offset; ref = (struct btrfs_inode_ref *)(sh + 1); namelen = btrfs_stack_inode_ref_name_len(ref); @@ -590,7 +589,7 @@ sh = (struct btrfs_ioctl_search_header *)args.buf; - if (sh->type == BTRFS_DIR_ITEM_KEY) { + if (sh.type == BTRFS_DIR_ITEM_KEY) { struct btrfs_dir_item *di; int name_len; char *name; @@ -613,7 +612,7 @@ int ret; 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; unsigned long off = 0; int name_len; @@ -660,28 +659,27 @@ * read the root_ref item it contains */ for (i = 0; i < sk->nr_items; i++) { - sh = (struct btrfs_ioctl_search_header *)(args.buf + - off); - off += sizeof(*sh); - if (sh->type == BTRFS_ROOT_BACKREF_KEY) { + memcpy(&sh, args.buf + off, sizeof(sh)); + off += sizeof(sh); + if (sh.type == BTRFS_ROOT_BACKREF_KEY) { ref = (struct btrfs_root_ref *)(args.buf + off); name_len = btrfs_stack_root_ref_name_len(ref); name = (char *)(ref + 1); dir_id = btrfs_stack_root_ref_dirid(ref); - add_root(root_lookup, sh->objectid, sh->offset, + add_root(root_lookup, sh.objectid, sh.offset, dir_id, name, name_len); } - 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; /* this iteration is done, step forward one root for the next @@ -810,17 +808,17 @@ int flags = 0; char *name = NULL; - if (sh->objectid == *cache_ino) { + if (sh.objectid == *cache_ino) { name = *cache_full_name; } else if (*cache_full_name) { free(*cache_full_name); *cache_full_name = NULL; } if (!name) { - name = ino_resolve(fd, sh->objectid, cache_dirid, + name = ino_resolve(fd, sh.objectid, cache_dirid, cache_dir_name); *cache_full_name = name; - *cache_ino = sh->objectid; + *cache_ino = sh.objectid; } if (!name) return -EIO; @@ -841,16 +839,16 @@ printf("unhandled extent type %d for inode %llu " "file offset %llu gen %llu\n", type, - (unsigned long long)sh->objectid, - (unsigned long long)sh->offset, + (unsigned long long)sh.objectid, + (unsigned long long)sh.offset, (unsigned long long)found_gen); return -EIO; } printf("inode %llu file offset %llu len %llu disk start %llu " "offset %llu gen %llu flags ", - (unsigned long long)sh->objectid, - (unsigned long long)sh->offset, + (unsigned long long)sh.objectid, + (unsigned long long)sh.offset, (unsigned long long)len, (unsigned long long)disk_start, (unsigned long long)disk_offset, @@ -880,7 +878,7 @@ int ret; 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_file_extent_item *item; unsigned long off = 0; u64 found_gen; @@ -930,35 +928,34 @@ * read the root_ref item it contains */ 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); /* * just in case the item was too big, pass something other * than garbage */ - if (sh->len == 0) + if (sh.len == 0) item = &backup; else item = (struct btrfs_file_extent_item *)(args.buf + off); found_gen = btrfs_stack_file_extent_generation(item); - if (sh->type == BTRFS_EXTENT_DATA_KEY && + if (sh.type == BTRFS_EXTENT_DATA_KEY && found_gen >= oldest_gen) { - print_one_extent(fd, sh, item, found_gen, + print_one_extent(fd, &sh, item, found_gen, &cache_dirid, &cache_dir_name, &cache_ino, &cache_full_name); } - 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_offset = sh->offset; - sk->min_type = sh->type; + sk->min_objectid = sh.objectid; + sk->min_offset = sh.offset; + sk->min_type = sh.type; } sk->nr_items = 4096; if (sk->min_offset < (u64)-1) diff -uNr btrfs-progs-0.20-rc1.orig/ctree.h btrfs-progs-0.20-rc1/ctree.h --- btrfs-progs-0.20-rc1.orig/ctree.h 2012-12-04 20:40:40.579141982 +0100 +++ btrfs-progs-0.20-rc1/ctree.h 2012-12-04 20:40:49.051039793 +0100 @@ -1063,15 +1063,19 @@ type *s) \ { \ unsigned long offset = (unsigned long)s; \ + u##bits m; \ type *p = (type *) (eb->data + offset); \ - return le##bits##_to_cpu(p->member); \ + memcpy(&m, &p->member, sizeof(m)); \ + return le##bits##_to_cpu(m); \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ type *s, u##bits val) \ { \ unsigned long offset = (unsigned long)s; \ + u##bits m; \ type *p = (type *) (eb->data + offset); \ - p->member = cpu_to_le##bits(val); \ + m = cpu_to_le##bits(val); \ + memcpy(&p->member, &m, sizeof(m)); \ } #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ diff -uNr btrfs-progs-0.20-rc1.orig/volumes.c btrfs-progs-0.20-rc1/volumes.c --- btrfs-progs-0.20-rc1.orig/volumes.c 2012-12-04 20:40:40.575142029 +0100 +++ btrfs-progs-0.20-rc1/volumes.c 2012-12-04 20:40:49.052039781 +0100 @@ -652,6 +652,7 @@ int index; int stripe_len = 64 * 1024; struct btrfs_key key; + u64 offset; if (list_empty(dev_list)) { return -ENOSPC; @@ -757,12 +758,13 @@ } return -ENOSPC; } - key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; - key.type = BTRFS_CHUNK_ITEM_KEY; ret = find_next_chunk(chunk_root, BTRFS_FIRST_CHUNK_TREE_OBJECTID, - &key.offset); + &offset); if (ret) return ret; + key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; + key.type = BTRFS_CHUNK_ITEM_KEY; + key.offset = offset; chunk = kmalloc(btrfs_chunk_item_size(num_stripes), GFP_NOFS); if (!chunk)