Commit e2fa7227 authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse

Btrfs: struct key endian fixes

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent bb492bb0
This diff is collapsed.
......@@ -2,6 +2,7 @@
#define __CTREE__
#include "list.h"
#include "kerncompat.h"
#define CTREE_BLOCKSIZE 1024
......@@ -14,8 +15,18 @@
* may point to extents.
*
* offset is the starting byte offset for this key in the stream.
*
* btrfs_disk_key is in disk byte order. struct btrfs_key is always
* in cpu native order. Otherwise they are identical and their sizes
* should be the same (ie both packed)
*/
struct key {
struct btrfs_disk_key {
__le64 objectid;
__le32 flags;
__le64 offset;
} __attribute__ ((__packed__));
struct btrfs_key {
u64 objectid;
u32 flags;
u64 offset;
......@@ -37,7 +48,7 @@ struct btrfs_header {
#define MAX_LEVEL 8
#define NODEPTRS_PER_BLOCK ((CTREE_BLOCKSIZE - sizeof(struct btrfs_header)) / \
(sizeof(struct key) + sizeof(u64)))
(sizeof(struct btrfs_disk_key) + sizeof(u64)))
struct tree_buffer;
......@@ -50,8 +61,8 @@ struct ctree_root {
struct tree_buffer *node;
struct tree_buffer *commit_root;
struct ctree_root *extent_root;
struct key current_insert;
struct key last_insert;
struct btrfs_key current_insert;
struct btrfs_key last_insert;
int fp;
struct radix_tree_root cache_radix;
struct radix_tree_root pinned_radix;
......@@ -88,7 +99,7 @@ struct ctree_super_block {
* the item in the leaf (relative to the start of the data area)
*/
struct item {
struct key key;
struct btrfs_disk_key key;
u16 offset;
u16 size;
} __attribute__ ((__packed__));
......@@ -115,7 +126,7 @@ struct leaf {
*/
struct node {
struct btrfs_header header;
struct key keys[NODEPTRS_PER_BLOCK];
struct btrfs_disk_key keys[NODEPTRS_PER_BLOCK];
u64 blockptrs[NODEPTRS_PER_BLOCK];
} __attribute__ ((__packed__));
......@@ -141,6 +152,55 @@ struct ctree_path {
int slots[MAX_LEVEL];
};
static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
struct btrfs_disk_key *disk)
{
cpu->offset = le64_to_cpu(disk->offset);
cpu->flags = le32_to_cpu(disk->flags);
cpu->objectid = le64_to_cpu(disk->objectid);
}
static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk,
struct btrfs_key *cpu)
{
disk->offset = cpu_to_le64(cpu->offset);
disk->flags = cpu_to_le32(cpu->flags);
disk->objectid = cpu_to_le64(cpu->objectid);
}
static inline u64 btrfs_key_objectid(struct btrfs_disk_key *disk)
{
return le64_to_cpu(disk->objectid);
}
static inline void btrfs_set_key_objectid(struct btrfs_disk_key *disk,
u64 val)
{
disk->objectid = cpu_to_le64(val);
}
static inline u64 btrfs_key_offset(struct btrfs_disk_key *disk)
{
return le64_to_cpu(disk->offset);
}
static inline void btrfs_set_key_offset(struct btrfs_disk_key *disk,
u64 val)
{
disk->offset = cpu_to_le64(val);
}
static inline u32 btrfs_key_flags(struct btrfs_disk_key *disk)
{
return le32_to_cpu(disk->flags);
}
static inline void btrfs_set_key_flags(struct btrfs_disk_key *disk,
u32 val)
{
disk->flags = cpu_to_le32(val);
}
static inline u64 btrfs_header_blocknr(struct btrfs_header *h)
{
return le64_to_cpu(h->blocknr);
......@@ -203,11 +263,13 @@ static inline int btrfs_is_leaf(struct node *n)
struct tree_buffer *alloc_free_block(struct ctree_root *root);
int btrfs_inc_ref(struct ctree_root *root, struct tree_buffer *buf);
int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks);
int search_slot(struct ctree_root *root, struct key *key, struct ctree_path *p, int ins_len, int cow);
int search_slot(struct ctree_root *root, struct btrfs_key *key,
struct ctree_path *p, int ins_len, int cow);
void release_path(struct ctree_root *root, struct ctree_path *p);
void init_path(struct ctree_path *p);
int del_item(struct ctree_root *root, struct ctree_path *path);
int insert_item(struct ctree_root *root, struct key *key, void *data, int data_size);
int insert_item(struct ctree_root *root, struct btrfs_key *key,
void *data, int data_size);
int next_leaf(struct ctree_root *root, struct ctree_path *path);
int leaf_free_space(struct leaf *leaf);
int btrfs_drop_snapshot(struct ctree_root *root, struct tree_buffer *snap);
......
......@@ -7,7 +7,8 @@
#include "print-tree.h"
static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
u64 search_start, u64 search_end, struct key *ins);
u64 search_start, u64 search_end,
struct btrfs_key *ins);
static int finish_current_insert(struct ctree_root *extent_root);
static int run_pending(struct ctree_root *extent_root);
......@@ -24,10 +25,10 @@ static int inc_block_ref(struct ctree_root *root, u64 blocknr)
{
struct ctree_path path;
int ret;
struct key key;
struct btrfs_key key;
struct leaf *l;
struct extent_item *item;
struct key ins;
struct btrfs_key ins;
find_free_extent(root->extent_root, 0, 0, (u64)-1, &ins);
init_path(&path);
......@@ -54,7 +55,7 @@ static int lookup_block_ref(struct ctree_root *root, u64 blocknr, u32 *refs)
{
struct ctree_path path;
int ret;
struct key key;
struct btrfs_key key;
struct leaf *l;
struct extent_item *item;
init_path(&path);
......@@ -113,7 +114,7 @@ int btrfs_finish_extent_commit(struct ctree_root *root)
static int finish_current_insert(struct ctree_root *extent_root)
{
struct key ins;
struct btrfs_key ins;
struct extent_item extent_item;
int i;
int ret;
......@@ -140,12 +141,12 @@ static int finish_current_insert(struct ctree_root *extent_root)
int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
struct ctree_root *extent_root = root->extent_root;
int ret;
struct item *item;
struct extent_item *ei;
struct key ins;
struct btrfs_key ins;
key.objectid = blocknr;
key.flags = 0;
......@@ -227,7 +228,7 @@ static int run_pending(struct ctree_root *extent_root)
*/
int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
{
struct key key;
struct btrfs_key key;
struct ctree_root *extent_root = root->extent_root;
struct tree_buffer *t;
int pending_ret;
......@@ -256,10 +257,11 @@ int free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
* Any available blocks before search_start are skipped.
*/
static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
u64 search_start, u64 search_end, struct key *ins)
u64 search_start, u64 search_end,
struct btrfs_key *ins)
{
struct ctree_path path;
struct key *key;
struct btrfs_key key;
int ret;
u64 hole_size = 0;
int slot = 0;
......@@ -306,12 +308,12 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
ins->offset = (u64)-1;
goto check_pending;
}
key = &l->items[slot].key;
if (key->objectid >= search_start) {
btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
if (key.objectid >= search_start) {
if (start_found) {
if (last_block < search_start)
last_block = search_start;
hole_size = key->objectid - last_block;
hole_size = key.objectid - last_block;
if (hole_size > total_needed) {
ins->objectid = last_block;
ins->offset = hole_size;
......@@ -320,7 +322,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
}
}
start_found = 1;
last_block = key->objectid + key->offset;
last_block = key.objectid + key.offset;
path.slots[0]++;
}
// FIXME -ENOSPC
......@@ -357,7 +359,7 @@ static int find_free_extent(struct ctree_root *orig_root, u64 num_blocks,
* returns 0 if everything worked, non-zero otherwise.
*/
int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
u64 search_end, u64 owner, struct key *ins)
u64 search_end, u64 owner, struct btrfs_key *ins)
{
int ret;
int pending_ret;
......@@ -400,7 +402,7 @@ int alloc_extent(struct ctree_root *root, u64 num_blocks, u64 search_start,
*/
struct tree_buffer *alloc_free_block(struct ctree_root *root)
{
struct key ins;
struct btrfs_key ins;
int ret;
struct tree_buffer *buf;
......
......@@ -69,8 +69,6 @@ static inline void __clear_bit(int bit, unsigned long *map) {
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - __builtin_offsetof(type,member) );})
#endif
#define ENOMEM 5
#define EEXIST 6
......@@ -94,3 +92,4 @@ typedef u64 __bitwise __be64;
#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
......@@ -45,9 +45,9 @@ int mkfs(int fd)
btrfs_set_header_nritems(&empty_leaf.header, 3);
/* item1, reserve blocks 0-16 */
item.key.objectid = 0;
item.key.offset = 17;
item.key.flags = 0;
item.key.objectid = cpu_to_le64(0);
item.key.offset = cpu_to_le64(17);
item.key.flags = cpu_to_le32(0);
item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item);
item.size = sizeof(struct extent_item);
extent_item.refs = 1;
......@@ -56,16 +56,16 @@ int mkfs(int fd)
memcpy(empty_leaf.data + item.offset, &extent_item, item.size);
/* item2, give block 17 to the root */
item.key.objectid = 17;
item.key.offset = 1;
item.key.objectid = cpu_to_le64(17);
item.key.offset = cpu_to_le64(1);
item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item) * 2;
extent_item.owner = 1;
memcpy(empty_leaf.items + 1, &item, sizeof(item));
memcpy(empty_leaf.data + item.offset, &extent_item, item.size);
/* item3, give block 18 for the extent root */
item.key.objectid = 18;
item.key.offset = 1;
item.key.objectid = cpu_to_le64(18);
item.key.offset = cpu_to_le64(1);
item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item) * 3;
extent_item.owner = 2;
memcpy(empty_leaf.items + 2, &item, sizeof(item));
......
......@@ -13,8 +13,8 @@ int next_key(int i, int max_key) {
}
int main(int ac, char **av) {
struct key ins;
struct key last = { (u64)-1, 0, 0};
struct btrfs_key ins;
struct btrfs_key last = { (u64)-1, 0, 0};
char *buf;
int i;
int num;
......@@ -146,7 +146,7 @@ int main(int ac, char **av) {
slot = path.slots[0];
leaf = &path.nodes[0]->leaf;
memcpy(&last, &leaf->items[slot].key, sizeof(last));
btrfs_disk_key_to_cpu(&last, &leaf->items[slot].key);
if (tree_size % 10000 == 0)
printf("big del %d:%d\n", tree_size, i);
ret = del_item(root, &path);
......
......@@ -10,7 +10,8 @@
int keep_running = 1;
struct ctree_super_block super;
static int setup_key(struct radix_tree_root *root, struct key *key, int exists)
static int setup_key(struct radix_tree_root *root, struct btrfs_key *key,
int exists)
{
int num = rand();
unsigned long res[2];
......@@ -38,7 +39,7 @@ static int setup_key(struct radix_tree_root *root, struct key *key, int exists)
static int ins_one(struct ctree_root *root, struct radix_tree_root *radix)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
int ret;
char buf[128];
unsigned long oid;
......@@ -63,7 +64,7 @@ static int ins_one(struct ctree_root *root, struct radix_tree_root *radix)
static int insert_dup(struct ctree_root *root, struct radix_tree_root *radix)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
int ret;
char buf[128];
init_path(&path);
......@@ -82,7 +83,7 @@ static int insert_dup(struct ctree_root *root, struct radix_tree_root *radix)
static int del_one(struct ctree_root *root, struct radix_tree_root *radix)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
int ret;
unsigned long *ptr;
init_path(&path);
......@@ -108,7 +109,7 @@ static int del_one(struct ctree_root *root, struct radix_tree_root *radix)
static int lookup_item(struct ctree_root *root, struct radix_tree_root *radix)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
int ret;
init_path(&path);
ret = setup_key(radix, &key, 1);
......@@ -127,7 +128,7 @@ static int lookup_item(struct ctree_root *root, struct radix_tree_root *radix)
static int lookup_enoent(struct ctree_root *root, struct radix_tree_root *radix)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
int ret;
init_path(&path);
ret = setup_key(radix, &key, 0);
......@@ -147,7 +148,7 @@ static int empty_tree(struct ctree_root *root, struct radix_tree_root *radix,
int nr)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
unsigned long found = 0;
int ret;
int slot;
......@@ -248,7 +249,7 @@ int (*ops[])(struct ctree_root *root, struct radix_tree_root *radix) =
static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix)
{
struct ctree_path path;
struct key key;
struct btrfs_key key;
unsigned long found;
int ret;
int slot;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment