mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-22 05:16:38 +00:00
Btrfs: struct item endian fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
e2fa7227cd
commit
0783fcfc4d
129
fs/btrfs/ctree.c
129
fs/btrfs/ctree.c
@ -76,7 +76,7 @@ static inline unsigned int leaf_data_end(struct leaf *leaf)
|
|||||||
u32 nr = btrfs_header_nritems(&leaf->header);
|
u32 nr = btrfs_header_nritems(&leaf->header);
|
||||||
if (nr == 0)
|
if (nr == 0)
|
||||||
return sizeof(leaf->data);
|
return sizeof(leaf->data);
|
||||||
return leaf->items[nr-1].offset;
|
return btrfs_item_offset(leaf->items + nr - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -174,11 +174,12 @@ int check_leaf(struct ctree_path *path, int level)
|
|||||||
btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key);
|
btrfs_disk_key_to_cpu(&cpukey, &leaf->items[i + 1].key);
|
||||||
BUG_ON(comp_keys(&leaf->items[i].key,
|
BUG_ON(comp_keys(&leaf->items[i].key,
|
||||||
&cpukey) >= 0);
|
&cpukey) >= 0);
|
||||||
BUG_ON(leaf->items[i].offset != leaf->items[i + 1].offset +
|
BUG_ON(btrfs_item_offset(leaf->items + i) !=
|
||||||
leaf->items[i + 1].size);
|
btrfs_item_end(leaf->items + i + 1));
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
BUG_ON(leaf->items[i].offset + leaf->items[i].size !=
|
BUG_ON(btrfs_item_offset(leaf->items + i) +
|
||||||
LEAF_DATA_SIZE);
|
btrfs_item_size(leaf->items + i) !=
|
||||||
|
LEAF_DATA_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -235,7 +236,8 @@ int bin_search(struct node *c, struct btrfs_key *key, int *slot)
|
|||||||
{
|
{
|
||||||
if (btrfs_is_leaf(c)) {
|
if (btrfs_is_leaf(c)) {
|
||||||
struct leaf *l = (struct leaf *)c;
|
struct leaf *l = (struct leaf *)c;
|
||||||
return generic_bin_search((void *)l->items, sizeof(struct item),
|
return generic_bin_search((void *)l->items,
|
||||||
|
sizeof(struct btrfs_item),
|
||||||
key, btrfs_header_nritems(&c->header),
|
key, btrfs_header_nritems(&c->header),
|
||||||
slot);
|
slot);
|
||||||
} else {
|
} else {
|
||||||
@ -485,7 +487,7 @@ again:
|
|||||||
struct leaf *l = (struct leaf *)c;
|
struct leaf *l = (struct leaf *)c;
|
||||||
p->slots[level] = slot;
|
p->slots[level] = slot;
|
||||||
if (ins_len > 0 && leaf_free_space(l) <
|
if (ins_len > 0 && leaf_free_space(l) <
|
||||||
sizeof(struct item) + ins_len) {
|
sizeof(struct btrfs_item) + ins_len) {
|
||||||
int sret = split_leaf(root, p, ins_len);
|
int sret = split_leaf(root, p, ins_len);
|
||||||
BUG_ON(sret > 0);
|
BUG_ON(sret > 0);
|
||||||
if (sret)
|
if (sret)
|
||||||
@ -780,9 +782,9 @@ static int leaf_space_used(struct leaf *l, int start, int nr)
|
|||||||
|
|
||||||
if (!nr)
|
if (!nr)
|
||||||
return 0;
|
return 0;
|
||||||
data_len = l->items[start].offset + l->items[start].size;
|
data_len = btrfs_item_end(l->items + start);
|
||||||
data_len = data_len - l->items[end].offset;
|
data_len = data_len - btrfs_item_offset(l->items + end);
|
||||||
data_len += sizeof(struct item) * nr;
|
data_len += sizeof(struct btrfs_item) * nr;
|
||||||
return data_len;
|
return data_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,7 +808,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
|
|||||||
int free_space;
|
int free_space;
|
||||||
int push_space = 0;
|
int push_space = 0;
|
||||||
int push_items = 0;
|
int push_items = 0;
|
||||||
struct item *item;
|
struct btrfs_item *item;
|
||||||
u32 left_nritems;
|
u32 left_nritems;
|
||||||
u32 right_nritems;
|
u32 right_nritems;
|
||||||
|
|
||||||
@ -821,7 +823,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
|
|||||||
right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]);
|
right_buf = read_tree_block(root, upper->node.blockptrs[slot + 1]);
|
||||||
right = &right_buf->leaf;
|
right = &right_buf->leaf;
|
||||||
free_space = leaf_free_space(right);
|
free_space = leaf_free_space(right);
|
||||||
if (free_space < data_size + sizeof(struct item)) {
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
||||||
tree_block_release(root, right_buf);
|
tree_block_release(root, right_buf);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -829,7 +831,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
|
|||||||
btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf);
|
btrfs_cow_block(root, right_buf, upper, slot + 1, &right_buf);
|
||||||
right = &right_buf->leaf;
|
right = &right_buf->leaf;
|
||||||
free_space = leaf_free_space(right);
|
free_space = leaf_free_space(right);
|
||||||
if (free_space < data_size + sizeof(struct item)) {
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
||||||
tree_block_release(root, right_buf);
|
tree_block_release(root, right_buf);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -839,10 +841,11 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
|
|||||||
item = left->items + i;
|
item = left->items + i;
|
||||||
if (path->slots[0] == i)
|
if (path->slots[0] == i)
|
||||||
push_space += data_size + sizeof(*item);
|
push_space += data_size + sizeof(*item);
|
||||||
if (item->size + sizeof(*item) + push_space > free_space)
|
if (btrfs_item_size(item) + sizeof(*item) + push_space >
|
||||||
|
free_space)
|
||||||
break;
|
break;
|
||||||
push_items++;
|
push_items++;
|
||||||
push_space += item->size + sizeof(*item);
|
push_space += btrfs_item_size(item) + sizeof(*item);
|
||||||
}
|
}
|
||||||
if (push_items == 0) {
|
if (push_items == 0) {
|
||||||
tree_block_release(root, right_buf);
|
tree_block_release(root, right_buf);
|
||||||
@ -850,8 +853,7 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
|
|||||||
}
|
}
|
||||||
right_nritems = btrfs_header_nritems(&right->header);
|
right_nritems = btrfs_header_nritems(&right->header);
|
||||||
/* push left to right */
|
/* push left to right */
|
||||||
push_space = left->items[left_nritems - push_items].offset +
|
push_space = btrfs_item_end(left->items + left_nritems - push_items);
|
||||||
left->items[left_nritems - push_items].size;
|
|
||||||
push_space -= leaf_data_end(left);
|
push_space -= leaf_data_end(left);
|
||||||
/* make room in the right data area */
|
/* make room in the right data area */
|
||||||
memmove(right->data + leaf_data_end(right) - push_space,
|
memmove(right->data + leaf_data_end(right) - push_space,
|
||||||
@ -862,18 +864,19 @@ static int push_leaf_right(struct ctree_root *root, struct ctree_path *path,
|
|||||||
left->data + leaf_data_end(left),
|
left->data + leaf_data_end(left),
|
||||||
push_space);
|
push_space);
|
||||||
memmove(right->items + push_items, right->items,
|
memmove(right->items + push_items, right->items,
|
||||||
right_nritems * sizeof(struct item));
|
right_nritems * sizeof(struct btrfs_item));
|
||||||
/* copy the items from left to right */
|
/* copy the items from left to right */
|
||||||
memcpy(right->items, left->items + left_nritems - push_items,
|
memcpy(right->items, left->items + left_nritems - push_items,
|
||||||
push_items * sizeof(struct item));
|
push_items * sizeof(struct btrfs_item));
|
||||||
|
|
||||||
/* update the item pointers */
|
/* update the item pointers */
|
||||||
right_nritems += push_items;
|
right_nritems += push_items;
|
||||||
btrfs_set_header_nritems(&right->header, right_nritems);
|
btrfs_set_header_nritems(&right->header, right_nritems);
|
||||||
push_space = LEAF_DATA_SIZE;
|
push_space = LEAF_DATA_SIZE;
|
||||||
for (i = 0; i < right_nritems; i++) {
|
for (i = 0; i < right_nritems; i++) {
|
||||||
right->items[i].offset = push_space - right->items[i].size;
|
btrfs_set_item_offset(right->items + i, push_space -
|
||||||
push_space = right->items[i].offset;
|
btrfs_item_size(right->items + i));
|
||||||
|
push_space = btrfs_item_offset(right->items + i);
|
||||||
}
|
}
|
||||||
left_nritems -= push_items;
|
left_nritems -= push_items;
|
||||||
btrfs_set_header_nritems(&left->header, left_nritems);
|
btrfs_set_header_nritems(&left->header, left_nritems);
|
||||||
@ -911,7 +914,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
|
|||||||
int free_space;
|
int free_space;
|
||||||
int push_space = 0;
|
int push_space = 0;
|
||||||
int push_items = 0;
|
int push_items = 0;
|
||||||
struct item *item;
|
struct btrfs_item *item;
|
||||||
u32 old_left_nritems;
|
u32 old_left_nritems;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int wret;
|
int wret;
|
||||||
@ -926,7 +929,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
|
|||||||
t = read_tree_block(root, path->nodes[1]->node.blockptrs[slot - 1]);
|
t = read_tree_block(root, path->nodes[1]->node.blockptrs[slot - 1]);
|
||||||
left = &t->leaf;
|
left = &t->leaf;
|
||||||
free_space = leaf_free_space(left);
|
free_space = leaf_free_space(left);
|
||||||
if (free_space < data_size + sizeof(struct item)) {
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
||||||
tree_block_release(root, t);
|
tree_block_release(root, t);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -935,7 +938,7 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
|
|||||||
btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t);
|
btrfs_cow_block(root, t, path->nodes[1], slot - 1, &t);
|
||||||
left = &t->leaf;
|
left = &t->leaf;
|
||||||
free_space = leaf_free_space(left);
|
free_space = leaf_free_space(left);
|
||||||
if (free_space < data_size + sizeof(struct item)) {
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
||||||
tree_block_release(root, t);
|
tree_block_release(root, t);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -944,10 +947,11 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
|
|||||||
item = right->items + i;
|
item = right->items + i;
|
||||||
if (path->slots[0] == i)
|
if (path->slots[0] == i)
|
||||||
push_space += data_size + sizeof(*item);
|
push_space += data_size + sizeof(*item);
|
||||||
if (item->size + sizeof(*item) + push_space > free_space)
|
if (btrfs_item_size(item) + sizeof(*item) + push_space >
|
||||||
|
free_space)
|
||||||
break;
|
break;
|
||||||
push_items++;
|
push_items++;
|
||||||
push_space += item->size + sizeof(*item);
|
push_space += btrfs_item_size(item) + sizeof(*item);
|
||||||
}
|
}
|
||||||
if (push_items == 0) {
|
if (push_items == 0) {
|
||||||
tree_block_release(root, t);
|
tree_block_release(root, t);
|
||||||
@ -955,35 +959,40 @@ static int push_leaf_left(struct ctree_root *root, struct ctree_path *path,
|
|||||||
}
|
}
|
||||||
/* push data from right to left */
|
/* push data from right to left */
|
||||||
memcpy(left->items + btrfs_header_nritems(&left->header),
|
memcpy(left->items + btrfs_header_nritems(&left->header),
|
||||||
right->items, push_items * sizeof(struct item));
|
right->items, push_items * sizeof(struct btrfs_item));
|
||||||
push_space = LEAF_DATA_SIZE - right->items[push_items -1].offset;
|
push_space = LEAF_DATA_SIZE -
|
||||||
|
btrfs_item_offset(right->items + push_items -1);
|
||||||
memcpy(left->data + leaf_data_end(left) - push_space,
|
memcpy(left->data + leaf_data_end(left) - push_space,
|
||||||
right->data + right->items[push_items - 1].offset,
|
right->data + btrfs_item_offset(right->items + push_items - 1),
|
||||||
push_space);
|
push_space);
|
||||||
old_left_nritems = btrfs_header_nritems(&left->header);
|
old_left_nritems = btrfs_header_nritems(&left->header);
|
||||||
BUG_ON(old_left_nritems < 0);
|
BUG_ON(old_left_nritems < 0);
|
||||||
|
|
||||||
for(i = old_left_nritems; i < old_left_nritems + push_items; i++) {
|
for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
|
||||||
left->items[i].offset -= LEAF_DATA_SIZE -
|
u16 ioff = btrfs_item_offset(left->items + i);
|
||||||
left->items[old_left_nritems -1].offset;
|
btrfs_set_item_offset(left->items + i, ioff - (LEAF_DATA_SIZE -
|
||||||
|
btrfs_item_offset(left->items +
|
||||||
|
old_left_nritems - 1)));
|
||||||
}
|
}
|
||||||
btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
|
btrfs_set_header_nritems(&left->header, old_left_nritems + push_items);
|
||||||
|
|
||||||
/* fixup right node */
|
/* fixup right node */
|
||||||
push_space = right->items[push_items-1].offset - leaf_data_end(right);
|
push_space = btrfs_item_offset(right->items + push_items - 1) -
|
||||||
|
leaf_data_end(right);
|
||||||
memmove(right->data + LEAF_DATA_SIZE - push_space, right->data +
|
memmove(right->data + LEAF_DATA_SIZE - push_space, right->data +
|
||||||
leaf_data_end(right), push_space);
|
leaf_data_end(right), push_space);
|
||||||
memmove(right->items, right->items + push_items,
|
memmove(right->items, right->items + push_items,
|
||||||
(btrfs_header_nritems(&right->header) - push_items) *
|
(btrfs_header_nritems(&right->header) - push_items) *
|
||||||
sizeof(struct item));
|
sizeof(struct btrfs_item));
|
||||||
btrfs_set_header_nritems(&right->header,
|
btrfs_set_header_nritems(&right->header,
|
||||||
btrfs_header_nritems(&right->header) -
|
btrfs_header_nritems(&right->header) -
|
||||||
push_items);
|
push_items);
|
||||||
push_space = LEAF_DATA_SIZE;
|
push_space = LEAF_DATA_SIZE;
|
||||||
|
|
||||||
for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
|
for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
|
||||||
right->items[i].offset = push_space - right->items[i].size;
|
btrfs_set_item_offset(right->items + i, push_space -
|
||||||
push_space = right->items[i].offset;
|
btrfs_item_size(right->items + i));
|
||||||
|
push_space = btrfs_item_offset(right->items + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
BUG_ON(list_empty(&t->dirty));
|
BUG_ON(list_empty(&t->dirty));
|
||||||
@ -1023,7 +1032,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
|
|||||||
int slot;
|
int slot;
|
||||||
struct leaf *right;
|
struct leaf *right;
|
||||||
struct tree_buffer *right_buffer;
|
struct tree_buffer *right_buffer;
|
||||||
int space_needed = data_size + sizeof(struct item);
|
int space_needed = data_size + sizeof(struct btrfs_item);
|
||||||
int data_copy_size;
|
int data_copy_size;
|
||||||
int rt_data_off;
|
int rt_data_off;
|
||||||
int i;
|
int i;
|
||||||
@ -1034,7 +1043,7 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
|
|||||||
l = &l_buf->leaf;
|
l = &l_buf->leaf;
|
||||||
|
|
||||||
/* did the pushes work? */
|
/* did the pushes work? */
|
||||||
if (leaf_free_space(l) >= sizeof(struct item) + data_size)
|
if (leaf_free_space(l) >= sizeof(struct btrfs_item) + data_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!path->nodes[1]) {
|
if (!path->nodes[1]) {
|
||||||
@ -1066,17 +1075,17 @@ static int split_leaf(struct ctree_root *root, struct ctree_path *path,
|
|||||||
btrfs_set_header_level(&right->header, 0);
|
btrfs_set_header_level(&right->header, 0);
|
||||||
btrfs_set_header_parentid(&right->header,
|
btrfs_set_header_parentid(&right->header,
|
||||||
btrfs_header_parentid(&root->node->node.header));
|
btrfs_header_parentid(&root->node->node.header));
|
||||||
data_copy_size = l->items[mid].offset + l->items[mid].size -
|
data_copy_size = btrfs_item_end(l->items + mid) - leaf_data_end(l);
|
||||||
leaf_data_end(l);
|
|
||||||
memcpy(right->items, l->items + mid,
|
memcpy(right->items, l->items + mid,
|
||||||
(nritems - mid) * sizeof(struct item));
|
(nritems - mid) * sizeof(struct btrfs_item));
|
||||||
memcpy(right->data + LEAF_DATA_SIZE - data_copy_size,
|
memcpy(right->data + LEAF_DATA_SIZE - data_copy_size,
|
||||||
l->data + leaf_data_end(l), data_copy_size);
|
l->data + leaf_data_end(l), data_copy_size);
|
||||||
rt_data_off = LEAF_DATA_SIZE -
|
rt_data_off = LEAF_DATA_SIZE - btrfs_item_end(l->items + mid);
|
||||||
(l->items[mid].offset + l->items[mid].size);
|
|
||||||
|
|
||||||
for (i = 0; i < btrfs_header_nritems(&right->header); i++)
|
for (i = 0; i < btrfs_header_nritems(&right->header); i++) {
|
||||||
right->items[i].offset += rt_data_off;
|
u16 ioff = btrfs_item_offset(right->items + i);
|
||||||
|
btrfs_set_item_offset(right->items + i, ioff + rt_data_off);
|
||||||
|
}
|
||||||
|
|
||||||
btrfs_set_header_nritems(&l->header, mid);
|
btrfs_set_header_nritems(&l->header, mid);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1136,26 +1145,28 @@ int insert_item(struct ctree_root *root, struct btrfs_key *cpu_key,
|
|||||||
nritems = btrfs_header_nritems(&leaf->header);
|
nritems = btrfs_header_nritems(&leaf->header);
|
||||||
data_end = leaf_data_end(leaf);
|
data_end = leaf_data_end(leaf);
|
||||||
|
|
||||||
if (leaf_free_space(leaf) < sizeof(struct item) + data_size)
|
if (leaf_free_space(leaf) < sizeof(struct btrfs_item) + data_size)
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
slot = path.slots[0];
|
slot = path.slots[0];
|
||||||
BUG_ON(slot < 0);
|
BUG_ON(slot < 0);
|
||||||
if (slot != nritems) {
|
if (slot != nritems) {
|
||||||
int i;
|
int i;
|
||||||
unsigned int old_data = leaf->items[slot].offset +
|
unsigned int old_data = btrfs_item_end(leaf->items + slot);
|
||||||
leaf->items[slot].size;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* item0..itemN ... dataN.offset..dataN.size .. data0.size
|
* item0..itemN ... dataN.offset..dataN.size .. data0.size
|
||||||
*/
|
*/
|
||||||
/* first correct the data pointers */
|
/* first correct the data pointers */
|
||||||
for (i = slot; i < nritems; i++)
|
for (i = slot; i < nritems; i++) {
|
||||||
leaf->items[i].offset -= data_size;
|
u16 ioff = btrfs_item_offset(leaf->items + i);
|
||||||
|
btrfs_set_item_offset(leaf->items + i,
|
||||||
|
ioff - data_size);
|
||||||
|
}
|
||||||
|
|
||||||
/* shift the items */
|
/* shift the items */
|
||||||
memmove(leaf->items + slot + 1, leaf->items + slot,
|
memmove(leaf->items + slot + 1, leaf->items + slot,
|
||||||
(nritems - slot) * sizeof(struct item));
|
(nritems - slot) * sizeof(struct btrfs_item));
|
||||||
|
|
||||||
/* shift the data */
|
/* shift the data */
|
||||||
memmove(leaf->data + data_end - data_size, leaf->data +
|
memmove(leaf->data + data_end - data_size, leaf->data +
|
||||||
@ -1165,8 +1176,8 @@ int insert_item(struct ctree_root *root, struct btrfs_key *cpu_key,
|
|||||||
/* copy the new data in */
|
/* copy the new data in */
|
||||||
memcpy(&leaf->items[slot].key, &disk_key,
|
memcpy(&leaf->items[slot].key, &disk_key,
|
||||||
sizeof(struct btrfs_disk_key));
|
sizeof(struct btrfs_disk_key));
|
||||||
leaf->items[slot].offset = data_end - data_size;
|
btrfs_set_item_offset(leaf->items + slot, data_end - data_size);
|
||||||
leaf->items[slot].size = data_size;
|
btrfs_set_item_size(leaf->items + slot, data_size);
|
||||||
memcpy(leaf->data + data_end - data_size, data, data_size);
|
memcpy(leaf->data + data_end - data_size, data, data_size);
|
||||||
btrfs_set_header_nritems(&leaf->header, nritems + 1);
|
btrfs_set_header_nritems(&leaf->header, nritems + 1);
|
||||||
|
|
||||||
@ -1241,8 +1252,8 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
|
|||||||
leaf_buf = path->nodes[0];
|
leaf_buf = path->nodes[0];
|
||||||
leaf = &leaf_buf->leaf;
|
leaf = &leaf_buf->leaf;
|
||||||
slot = path->slots[0];
|
slot = path->slots[0];
|
||||||
doff = leaf->items[slot].offset;
|
doff = btrfs_item_offset(leaf->items + slot);
|
||||||
dsize = leaf->items[slot].size;
|
dsize = btrfs_item_size(leaf->items + slot);
|
||||||
nritems = btrfs_header_nritems(&leaf->header);
|
nritems = btrfs_header_nritems(&leaf->header);
|
||||||
|
|
||||||
if (slot != nritems - 1) {
|
if (slot != nritems - 1) {
|
||||||
@ -1251,10 +1262,12 @@ int del_item(struct ctree_root *root, struct ctree_path *path)
|
|||||||
memmove(leaf->data + data_end + dsize,
|
memmove(leaf->data + data_end + dsize,
|
||||||
leaf->data + data_end,
|
leaf->data + data_end,
|
||||||
doff - data_end);
|
doff - data_end);
|
||||||
for (i = slot + 1; i < nritems; i++)
|
for (i = slot + 1; i < nritems; i++) {
|
||||||
leaf->items[i].offset += dsize;
|
u16 ioff = btrfs_item_offset(leaf->items + i);
|
||||||
|
btrfs_set_item_offset(leaf->items + i, ioff + dsize);
|
||||||
|
}
|
||||||
memmove(leaf->items + slot, leaf->items + slot + 1,
|
memmove(leaf->items + slot, leaf->items + slot + 1,
|
||||||
sizeof(struct item) *
|
sizeof(struct btrfs_item) *
|
||||||
(nritems - slot - 1));
|
(nritems - slot - 1));
|
||||||
}
|
}
|
||||||
btrfs_set_header_nritems(&leaf->header, nritems - 1);
|
btrfs_set_header_nritems(&leaf->header, nritems - 1);
|
||||||
|
@ -98,10 +98,10 @@ struct ctree_super_block {
|
|||||||
* the key flags parameter. offset and size tell us where to find
|
* the key flags parameter. offset and size tell us where to find
|
||||||
* the item in the leaf (relative to the start of the data area)
|
* the item in the leaf (relative to the start of the data area)
|
||||||
*/
|
*/
|
||||||
struct item {
|
struct btrfs_item {
|
||||||
struct btrfs_disk_key key;
|
struct btrfs_disk_key key;
|
||||||
u16 offset;
|
__le16 offset;
|
||||||
u16 size;
|
__le16 size;
|
||||||
} __attribute__ ((__packed__));
|
} __attribute__ ((__packed__));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,7 +115,8 @@ struct item {
|
|||||||
struct leaf {
|
struct leaf {
|
||||||
struct btrfs_header header;
|
struct btrfs_header header;
|
||||||
union {
|
union {
|
||||||
struct item items[LEAF_DATA_SIZE/sizeof(struct item)];
|
struct btrfs_item items[LEAF_DATA_SIZE/
|
||||||
|
sizeof(struct btrfs_item)];
|
||||||
u8 data[CTREE_BLOCKSIZE-sizeof(struct btrfs_header)];
|
u8 data[CTREE_BLOCKSIZE-sizeof(struct btrfs_header)];
|
||||||
};
|
};
|
||||||
} __attribute__ ((__packed__));
|
} __attribute__ ((__packed__));
|
||||||
@ -152,6 +153,31 @@ struct ctree_path {
|
|||||||
int slots[MAX_LEVEL];
|
int slots[MAX_LEVEL];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline u16 btrfs_item_offset(struct btrfs_item *item)
|
||||||
|
{
|
||||||
|
return le16_to_cpu(item->offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void btrfs_set_item_offset(struct btrfs_item *item, u16 val)
|
||||||
|
{
|
||||||
|
item->offset = cpu_to_le16(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 btrfs_item_end(struct btrfs_item *item)
|
||||||
|
{
|
||||||
|
return le16_to_cpu(item->offset) + le16_to_cpu(item->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 btrfs_item_size(struct btrfs_item *item)
|
||||||
|
{
|
||||||
|
return le16_to_cpu(item->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void btrfs_set_item_size(struct btrfs_item *item, u16 val)
|
||||||
|
{
|
||||||
|
item->size = cpu_to_le16(val);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
|
static inline void btrfs_disk_key_to_cpu(struct btrfs_key *cpu,
|
||||||
struct btrfs_disk_key *disk)
|
struct btrfs_disk_key *disk)
|
||||||
{
|
{
|
||||||
|
@ -40,8 +40,8 @@ static int inc_block_ref(struct ctree_root *root, u64 blocknr)
|
|||||||
BUG();
|
BUG();
|
||||||
BUG_ON(ret != 0);
|
BUG_ON(ret != 0);
|
||||||
l = &path.nodes[0]->leaf;
|
l = &path.nodes[0]->leaf;
|
||||||
item = (struct extent_item *)(l->data +
|
item = (struct extent_item *)(l->data + btrfs_item_offset(l->items +
|
||||||
l->items[path.slots[0]].offset);
|
path.slots[0]));
|
||||||
item->refs++;
|
item->refs++;
|
||||||
|
|
||||||
BUG_ON(list_empty(&path.nodes[0]->dirty));
|
BUG_ON(list_empty(&path.nodes[0]->dirty));
|
||||||
@ -67,7 +67,8 @@ static int lookup_block_ref(struct ctree_root *root, u64 blocknr, u32 *refs)
|
|||||||
BUG();
|
BUG();
|
||||||
l = &path.nodes[0]->leaf;
|
l = &path.nodes[0]->leaf;
|
||||||
item = (struct extent_item *)(l->data +
|
item = (struct extent_item *)(l->data +
|
||||||
l->items[path.slots[0]].offset);
|
btrfs_item_offset(l->items +
|
||||||
|
path.slots[0]));
|
||||||
*refs = item->refs;
|
*refs = item->refs;
|
||||||
release_path(root->extent_root, &path);
|
release_path(root->extent_root, &path);
|
||||||
return 0;
|
return 0;
|
||||||
@ -144,7 +145,7 @@ int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
|
|||||||
struct btrfs_key key;
|
struct btrfs_key key;
|
||||||
struct ctree_root *extent_root = root->extent_root;
|
struct ctree_root *extent_root = root->extent_root;
|
||||||
int ret;
|
int ret;
|
||||||
struct item *item;
|
struct btrfs_item *item;
|
||||||
struct extent_item *ei;
|
struct extent_item *ei;
|
||||||
struct btrfs_key ins;
|
struct btrfs_key ins;
|
||||||
|
|
||||||
@ -162,7 +163,8 @@ int __free_extent(struct ctree_root *root, u64 blocknr, u64 num_blocks)
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
item = path.nodes[0]->leaf.items + path.slots[0];
|
item = path.nodes[0]->leaf.items + path.slots[0];
|
||||||
ei = (struct extent_item *)(path.nodes[0]->leaf.data + item->offset);
|
ei = (struct extent_item *)(path.nodes[0]->leaf.data +
|
||||||
|
btrfs_item_offset(item));
|
||||||
BUG_ON(ei->refs == 0);
|
BUG_ON(ei->refs == 0);
|
||||||
ei->refs--;
|
ei->refs--;
|
||||||
if (ei->refs == 0) {
|
if (ei->refs == 0) {
|
||||||
|
@ -14,7 +14,7 @@ int mkfs(int fd)
|
|||||||
{
|
{
|
||||||
struct ctree_root_info info[2];
|
struct ctree_root_info info[2];
|
||||||
struct leaf empty_leaf;
|
struct leaf empty_leaf;
|
||||||
struct item item;
|
struct btrfs_item item;
|
||||||
struct extent_item extent_item;
|
struct extent_item extent_item;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -45,31 +45,37 @@ int mkfs(int fd)
|
|||||||
btrfs_set_header_nritems(&empty_leaf.header, 3);
|
btrfs_set_header_nritems(&empty_leaf.header, 3);
|
||||||
|
|
||||||
/* item1, reserve blocks 0-16 */
|
/* item1, reserve blocks 0-16 */
|
||||||
item.key.objectid = cpu_to_le64(0);
|
btrfs_set_key_objectid(&item.key, 0);
|
||||||
item.key.offset = cpu_to_le64(17);
|
btrfs_set_key_offset(&item.key, 17);
|
||||||
item.key.flags = cpu_to_le32(0);
|
btrfs_set_key_flags(&item.key, 0);
|
||||||
item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item);
|
btrfs_set_item_offset(&item,
|
||||||
item.size = sizeof(struct extent_item);
|
LEAF_DATA_SIZE - sizeof(struct extent_item));
|
||||||
|
btrfs_set_item_size(&item, sizeof(struct extent_item));
|
||||||
extent_item.refs = 1;
|
extent_item.refs = 1;
|
||||||
extent_item.owner = 0;
|
extent_item.owner = 0;
|
||||||
memcpy(empty_leaf.items, &item, sizeof(item));
|
memcpy(empty_leaf.items, &item, sizeof(item));
|
||||||
memcpy(empty_leaf.data + item.offset, &extent_item, item.size);
|
memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
|
||||||
|
btrfs_item_size(&item));
|
||||||
|
|
||||||
/* item2, give block 17 to the root */
|
/* item2, give block 17 to the root */
|
||||||
item.key.objectid = cpu_to_le64(17);
|
btrfs_set_key_objectid(&item.key, 17);
|
||||||
item.key.offset = cpu_to_le64(1);
|
btrfs_set_key_offset(&item.key, 1);
|
||||||
item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item) * 2;
|
btrfs_set_item_offset(&item,
|
||||||
|
LEAF_DATA_SIZE - sizeof(struct extent_item) * 2);
|
||||||
extent_item.owner = 1;
|
extent_item.owner = 1;
|
||||||
memcpy(empty_leaf.items + 1, &item, sizeof(item));
|
memcpy(empty_leaf.items + 1, &item, sizeof(item));
|
||||||
memcpy(empty_leaf.data + item.offset, &extent_item, item.size);
|
memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
|
||||||
|
btrfs_item_size(&item));
|
||||||
|
|
||||||
/* item3, give block 18 for the extent root */
|
/* item3, give block 18 for the extent root */
|
||||||
item.key.objectid = cpu_to_le64(18);
|
btrfs_set_key_objectid(&item.key, 18);
|
||||||
item.key.offset = cpu_to_le64(1);
|
btrfs_set_key_offset(&item.key, 1);
|
||||||
item.offset = LEAF_DATA_SIZE - sizeof(struct extent_item) * 3;
|
btrfs_set_item_offset(&item,
|
||||||
|
LEAF_DATA_SIZE - sizeof(struct extent_item) * 3);
|
||||||
extent_item.owner = 2;
|
extent_item.owner = 2;
|
||||||
memcpy(empty_leaf.items + 2, &item, sizeof(item));
|
memcpy(empty_leaf.items + 2, &item, sizeof(item));
|
||||||
memcpy(empty_leaf.data + item.offset, &extent_item, item.size);
|
memcpy(empty_leaf.data + btrfs_item_offset(&item), &extent_item,
|
||||||
|
btrfs_item_size(&item));
|
||||||
ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * CTREE_BLOCKSIZE);
|
ret = pwrite(fd, &empty_leaf, sizeof(empty_leaf), 18 * CTREE_BLOCKSIZE);
|
||||||
if (ret != sizeof(empty_leaf))
|
if (ret != sizeof(empty_leaf))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -9,7 +9,7 @@ void print_leaf(struct leaf *l)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 nr = btrfs_header_nritems(&l->header);
|
u32 nr = btrfs_header_nritems(&l->header);
|
||||||
struct item *item;
|
struct btrfs_item *item;
|
||||||
struct extent_item *ei;
|
struct extent_item *ei;
|
||||||
printf("leaf %Lu total ptrs %d free space %d\n",
|
printf("leaf %Lu total ptrs %d free space %d\n",
|
||||||
btrfs_header_blocknr(&l->header), nr, leaf_free_space(l));
|
btrfs_header_blocknr(&l->header), nr, leaf_free_space(l));
|
||||||
@ -18,12 +18,15 @@ void print_leaf(struct leaf *l)
|
|||||||
item = l->items + i;
|
item = l->items + i;
|
||||||
printf("\titem %d key (%Lu %u %Lu) itemoff %d itemsize %d\n",
|
printf("\titem %d key (%Lu %u %Lu) itemoff %d itemsize %d\n",
|
||||||
i,
|
i,
|
||||||
item->key.objectid, item->key.flags, item->key.offset,
|
btrfs_key_objectid(&item->key),
|
||||||
item->offset, item->size);
|
btrfs_key_flags(&item->key),
|
||||||
|
btrfs_key_offset(&item->key),
|
||||||
|
btrfs_item_offset(item),
|
||||||
|
btrfs_item_size(item));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
printf("\t\titem data %.*s\n", item->size,
|
printf("\t\titem data %.*s\n", btrfs_item_size(item),
|
||||||
l->data+item->offset);
|
l->data + btrfs_item_offset(item));
|
||||||
ei = (struct extent_item *)(l->data + item->offset);
|
ei = (struct extent_item *)(l->data + btrfs_item_offset(item));
|
||||||
printf("\t\textent data refs %u owner %Lu\n", ei->refs,
|
printf("\t\textent data refs %u owner %Lu\n", ei->refs,
|
||||||
ei->owner);
|
ei->owner);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -173,7 +173,7 @@ static int empty_tree(struct ctree_root *root, struct radix_tree_root *radix,
|
|||||||
path.slots[0] -= 1;
|
path.slots[0] -= 1;
|
||||||
}
|
}
|
||||||
slot = path.slots[0];
|
slot = path.slots[0];
|
||||||
found = path.nodes[0]->leaf.items[slot].key.objectid;
|
found=btrfs_key_objectid(&path.nodes[0]->leaf.items[slot].key);
|
||||||
ret = del_item(root, &path);
|
ret = del_item(root, &path);
|
||||||
count++;
|
count++;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -274,7 +274,8 @@ static int fill_radix(struct ctree_root *root, struct radix_tree_root *radix)
|
|||||||
slot -= 1;
|
slot -= 1;
|
||||||
}
|
}
|
||||||
for (i = slot; i >= 0; i--) {
|
for (i = slot; i >= 0; i--) {
|
||||||
found = path.nodes[0]->leaf.items[i].key.objectid;
|
found = btrfs_key_objectid(&path.nodes[0]->
|
||||||
|
leaf.items[i].key);
|
||||||
radix_tree_preload(GFP_KERNEL);
|
radix_tree_preload(GFP_KERNEL);
|
||||||
ret = radix_tree_insert(radix, found, (void *)found);
|
ret = radix_tree_insert(radix, found, (void *)found);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user