|
@@ -83,16 +83,15 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
WARN_ON(root->ref_cows && trans->transid != root->last_trans);
|
|
WARN_ON(root->ref_cows && trans->transid != root->last_trans);
|
|
|
|
|
|
- cow = btrfs_alloc_free_block(trans, root, search_start, empty_size);
|
|
|
|
|
|
+ cow = btrfs_alloc_free_block(trans, root, buf->len,
|
|
|
|
+ search_start, empty_size);
|
|
if (IS_ERR(cow))
|
|
if (IS_ERR(cow))
|
|
return PTR_ERR(cow);
|
|
return PTR_ERR(cow);
|
|
|
|
|
|
cow->alloc_addr = (unsigned long)__builtin_return_address(0);
|
|
cow->alloc_addr = (unsigned long)__builtin_return_address(0);
|
|
- if (buf->len != root->sectorsize || cow->len != root->sectorsize)
|
|
|
|
- WARN_ON(1);
|
|
|
|
|
|
|
|
copy_extent_buffer(cow, buf, 0, 0, cow->len);
|
|
copy_extent_buffer(cow, buf, 0, 0, cow->len);
|
|
- btrfs_set_header_blocknr(cow, extent_buffer_blocknr(cow));
|
|
|
|
|
|
+ btrfs_set_header_bytenr(cow, cow->start);
|
|
btrfs_set_header_generation(cow, trans->transid);
|
|
btrfs_set_header_generation(cow, trans->transid);
|
|
btrfs_set_header_owner(cow, root->root_key.objectid);
|
|
btrfs_set_header_owner(cow, root->root_key.objectid);
|
|
|
|
|
|
@@ -110,16 +109,16 @@ static int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
|
root->node = cow;
|
|
root->node = cow;
|
|
extent_buffer_get(cow);
|
|
extent_buffer_get(cow);
|
|
if (buf != root->commit_root) {
|
|
if (buf != root->commit_root) {
|
|
- btrfs_free_extent(trans, root,
|
|
|
|
- extent_buffer_blocknr(buf), 1, 1);
|
|
|
|
|
|
+ btrfs_free_extent(trans, root, buf->start,
|
|
|
|
+ buf->len, 1);
|
|
}
|
|
}
|
|
free_extent_buffer(buf);
|
|
free_extent_buffer(buf);
|
|
} else {
|
|
} else {
|
|
btrfs_set_node_blockptr(parent, parent_slot,
|
|
btrfs_set_node_blockptr(parent, parent_slot,
|
|
- extent_buffer_blocknr(cow));
|
|
|
|
|
|
+ cow->start);
|
|
btrfs_mark_buffer_dirty(parent);
|
|
btrfs_mark_buffer_dirty(parent);
|
|
WARN_ON(btrfs_header_generation(parent) != trans->transid);
|
|
WARN_ON(btrfs_header_generation(parent) != trans->transid);
|
|
- btrfs_free_extent(trans, root, extent_buffer_blocknr(buf),1,1);
|
|
|
|
|
|
+ btrfs_free_extent(trans, root, buf->start, buf->len, 1);
|
|
}
|
|
}
|
|
free_extent_buffer(buf);
|
|
free_extent_buffer(buf);
|
|
btrfs_mark_buffer_dirty(cow);
|
|
btrfs_mark_buffer_dirty(cow);
|
|
@@ -149,13 +148,14 @@ int btrfs_cow_block(struct btrfs_trans_handle *trans,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- search_start = extent_buffer_blocknr(buf) & ~((u64)65535);
|
|
|
|
|
|
+ search_start = buf->start & ~((u64)BTRFS_BLOCK_GROUP_SIZE - 1);
|
|
ret = __btrfs_cow_block(trans, root, buf, parent,
|
|
ret = __btrfs_cow_block(trans, root, buf, parent,
|
|
parent_slot, cow_ret, search_start, 0);
|
|
parent_slot, cow_ret, search_start, 0);
|
|
(*cow_ret)->alloc_addr = (unsigned long)__builtin_return_address(0);
|
|
(*cow_ret)->alloc_addr = (unsigned long)__builtin_return_address(0);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if 0
|
|
static int close_blocks(u64 blocknr, u64 other)
|
|
static int close_blocks(u64 blocknr, u64 other)
|
|
{
|
|
{
|
|
if (blocknr < other && other - blocknr < 8)
|
|
if (blocknr < other && other - blocknr < 8)
|
|
@@ -165,7 +165,6 @@ static int close_blocks(u64 blocknr, u64 other)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-#if 0
|
|
|
|
static int should_defrag_leaf(struct extent_buffer *eb)
|
|
static int should_defrag_leaf(struct extent_buffer *eb)
|
|
{
|
|
{
|
|
return 0;
|
|
return 0;
|
|
@@ -355,7 +354,7 @@ static int check_node(struct btrfs_root *root, struct btrfs_path *path,
|
|
BUG_ON(memcmp(&parent_key, &node_key,
|
|
BUG_ON(memcmp(&parent_key, &node_key,
|
|
sizeof(struct btrfs_disk_key)));
|
|
sizeof(struct btrfs_disk_key)));
|
|
BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
|
|
BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
|
|
- btrfs_header_blocknr(node));
|
|
|
|
|
|
+ btrfs_header_bytenr(node));
|
|
}
|
|
}
|
|
BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
|
|
BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
|
|
if (slot != 0) {
|
|
if (slot != 0) {
|
|
@@ -398,7 +397,7 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
|
|
BUG_ON(memcmp(&parent_key, &leaf_key,
|
|
BUG_ON(memcmp(&parent_key, &leaf_key,
|
|
sizeof(struct btrfs_disk_key)));
|
|
sizeof(struct btrfs_disk_key)));
|
|
BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
|
|
BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
|
|
- btrfs_header_blocknr(leaf));
|
|
|
|
|
|
+ btrfs_header_bytenr(leaf));
|
|
}
|
|
}
|
|
#if 0
|
|
#if 0
|
|
for (i = 0; nritems > 1 && i < nritems - 2; i++) {
|
|
for (i = 0; nritems > 1 && i < nritems - 2; i++) {
|
|
@@ -467,14 +466,16 @@ static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
|
|
static int check_block(struct btrfs_root *root, struct btrfs_path *path,
|
|
static int check_block(struct btrfs_root *root, struct btrfs_path *path,
|
|
int level)
|
|
int level)
|
|
{
|
|
{
|
|
|
|
+#if 0
|
|
struct extent_buffer *buf = path->nodes[level];
|
|
struct extent_buffer *buf = path->nodes[level];
|
|
|
|
|
|
if (memcmp_extent_buffer(buf, root->fs_info->fsid,
|
|
if (memcmp_extent_buffer(buf, root->fs_info->fsid,
|
|
(unsigned long)btrfs_header_fsid(buf),
|
|
(unsigned long)btrfs_header_fsid(buf),
|
|
BTRFS_FSID_SIZE)) {
|
|
BTRFS_FSID_SIZE)) {
|
|
printk("warning bad block %Lu\n", buf->start);
|
|
printk("warning bad block %Lu\n", buf->start);
|
|
- BUG();
|
|
|
|
|
|
+ return 1;
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
if (level == 0)
|
|
if (level == 0)
|
|
return check_leaf(root, path, level);
|
|
return check_leaf(root, path, level);
|
|
return check_node(root, path, level);
|
|
return check_node(root, path, level);
|
|
@@ -585,7 +586,8 @@ static struct extent_buffer *read_node_slot(struct btrfs_root *root,
|
|
return NULL;
|
|
return NULL;
|
|
if (slot >= btrfs_header_nritems(parent))
|
|
if (slot >= btrfs_header_nritems(parent))
|
|
return NULL;
|
|
return NULL;
|
|
- return read_tree_block(root, btrfs_node_blockptr(parent, slot));
|
|
|
|
|
|
+ return read_tree_block(root, btrfs_node_blockptr(parent, slot),
|
|
|
|
+ btrfs_level_size(root, btrfs_header_level(parent) - 1));
|
|
}
|
|
}
|
|
|
|
|
|
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
@@ -618,7 +620,6 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
*/
|
|
*/
|
|
if (!parent) {
|
|
if (!parent) {
|
|
struct extent_buffer *child;
|
|
struct extent_buffer *child;
|
|
- u64 blocknr = extent_buffer_blocknr(mid);
|
|
|
|
|
|
|
|
if (btrfs_header_nritems(mid) != 1)
|
|
if (btrfs_header_nritems(mid) != 1)
|
|
return 0;
|
|
return 0;
|
|
@@ -632,9 +633,10 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
wait_on_tree_block_writeback(root, mid);
|
|
wait_on_tree_block_writeback(root, mid);
|
|
/* once for the path */
|
|
/* once for the path */
|
|
free_extent_buffer(mid);
|
|
free_extent_buffer(mid);
|
|
|
|
+ ret = btrfs_free_extent(trans, root, mid->start, mid->len, 1);
|
|
/* once for the root ptr */
|
|
/* once for the root ptr */
|
|
free_extent_buffer(mid);
|
|
free_extent_buffer(mid);
|
|
- return btrfs_free_extent(trans, root, blocknr, 1, 1);
|
|
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
if (btrfs_header_nritems(mid) >
|
|
if (btrfs_header_nritems(mid) >
|
|
BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
|
|
BTRFS_NODEPTRS_PER_BLOCK(root) / 4)
|
|
@@ -680,7 +682,9 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
if (wret < 0 && wret != -ENOSPC)
|
|
if (wret < 0 && wret != -ENOSPC)
|
|
ret = wret;
|
|
ret = wret;
|
|
if (btrfs_header_nritems(right) == 0) {
|
|
if (btrfs_header_nritems(right) == 0) {
|
|
- u64 blocknr = extent_buffer_blocknr(right);
|
|
|
|
|
|
+ u64 bytenr = right->start;
|
|
|
|
+ u32 blocksize = right->len;
|
|
|
|
+
|
|
clean_tree_block(trans, root, right);
|
|
clean_tree_block(trans, root, right);
|
|
wait_on_tree_block_writeback(root, right);
|
|
wait_on_tree_block_writeback(root, right);
|
|
free_extent_buffer(right);
|
|
free_extent_buffer(right);
|
|
@@ -689,7 +693,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
1);
|
|
1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
- wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
|
|
|
|
|
|
+ wret = btrfs_free_extent(trans, root, bytenr,
|
|
|
|
+ blocksize, 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
} else {
|
|
} else {
|
|
@@ -719,7 +724,8 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
}
|
|
}
|
|
if (btrfs_header_nritems(mid) == 0) {
|
|
if (btrfs_header_nritems(mid) == 0) {
|
|
/* we've managed to empty the middle node, drop it */
|
|
/* we've managed to empty the middle node, drop it */
|
|
- u64 blocknr = extent_buffer_blocknr(mid);
|
|
|
|
|
|
+ u64 bytenr = mid->start;
|
|
|
|
+ u32 blocksize = mid->len;
|
|
clean_tree_block(trans, root, mid);
|
|
clean_tree_block(trans, root, mid);
|
|
wait_on_tree_block_writeback(root, mid);
|
|
wait_on_tree_block_writeback(root, mid);
|
|
free_extent_buffer(mid);
|
|
free_extent_buffer(mid);
|
|
@@ -727,7 +733,7 @@ static int balance_level(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
wret = del_ptr(trans, root, path, level + 1, pslot);
|
|
wret = del_ptr(trans, root, path, level + 1, pslot);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
- wret = btrfs_free_extent(trans, root, blocknr, 1, 1);
|
|
|
|
|
|
+ wret = btrfs_free_extent(trans, root, bytenr, blocksize, 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
} else {
|
|
} else {
|
|
@@ -830,7 +836,6 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
|
|
path->slots[level] = orig_slot;
|
|
path->slots[level] = orig_slot;
|
|
free_extent_buffer(left);
|
|
free_extent_buffer(left);
|
|
}
|
|
}
|
|
- check_node(root, path, level);
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
free_extent_buffer(left);
|
|
free_extent_buffer(left);
|
|
@@ -874,12 +879,10 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
|
|
} else {
|
|
} else {
|
|
free_extent_buffer(right);
|
|
free_extent_buffer(right);
|
|
}
|
|
}
|
|
- check_node(root, path, level);
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
free_extent_buffer(right);
|
|
free_extent_buffer(right);
|
|
}
|
|
}
|
|
- check_node(root, path, level);
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -889,19 +892,23 @@ static int push_nodes_for_insert(struct btrfs_trans_handle *trans,
|
|
static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
|
|
static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
|
|
int level, int slot)
|
|
int level, int slot)
|
|
{
|
|
{
|
|
|
|
+ return;
|
|
|
|
+#if 0
|
|
struct extent_buffer *node;
|
|
struct extent_buffer *node;
|
|
int i;
|
|
int i;
|
|
u32 nritems;
|
|
u32 nritems;
|
|
- u64 blocknr;
|
|
|
|
|
|
+ u64 bytenr;
|
|
u64 search;
|
|
u64 search;
|
|
u64 cluster_start;
|
|
u64 cluster_start;
|
|
int ret;
|
|
int ret;
|
|
int nread = 0;
|
|
int nread = 0;
|
|
int direction = path->reada;
|
|
int direction = path->reada;
|
|
|
|
+ int level;
|
|
struct radix_tree_root found;
|
|
struct radix_tree_root found;
|
|
unsigned long gang[8];
|
|
unsigned long gang[8];
|
|
struct extent_buffer *eb;
|
|
struct extent_buffer *eb;
|
|
|
|
|
|
|
|
+
|
|
if (level == 0)
|
|
if (level == 0)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -918,8 +925,9 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
|
|
init_bit_radix(&found);
|
|
init_bit_radix(&found);
|
|
nritems = btrfs_header_nritems(node);
|
|
nritems = btrfs_header_nritems(node);
|
|
|
|
+ level = btrfs_header_level(node) - 1;
|
|
for (i = slot; i < nritems; i++) {
|
|
for (i = slot; i < nritems; i++) {
|
|
- blocknr = btrfs_node_blockptr(node, i);
|
|
|
|
|
|
+ bytenr = btrfs_node_blockptr(node, i);
|
|
set_radix_bit(&found, blocknr);
|
|
set_radix_bit(&found, blocknr);
|
|
}
|
|
}
|
|
if (direction > 0) {
|
|
if (direction > 0) {
|
|
@@ -944,6 +952,7 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
* look for key in the tree. path is filled in with nodes along the way
|
|
* look for key in the tree. path is filled in with nodes along the way
|
|
@@ -963,7 +972,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
ins_len, int cow)
|
|
ins_len, int cow)
|
|
{
|
|
{
|
|
struct extent_buffer *b;
|
|
struct extent_buffer *b;
|
|
- u64 blocknr;
|
|
|
|
|
|
+ u64 bytenr;
|
|
int slot;
|
|
int slot;
|
|
int ret;
|
|
int ret;
|
|
int level;
|
|
int level;
|
|
@@ -1027,10 +1036,11 @@ again:
|
|
/* this is only true while dropping a snapshot */
|
|
/* this is only true while dropping a snapshot */
|
|
if (level == lowest_level)
|
|
if (level == lowest_level)
|
|
break;
|
|
break;
|
|
- blocknr = btrfs_node_blockptr(b, slot);
|
|
|
|
|
|
+ bytenr = btrfs_node_blockptr(b, slot);
|
|
if (should_reada)
|
|
if (should_reada)
|
|
reada_for_search(root, p, level, slot);
|
|
reada_for_search(root, p, level, slot);
|
|
- b = read_tree_block(root, btrfs_node_blockptr(b, slot));
|
|
|
|
|
|
+ b = read_tree_block(root, bytenr,
|
|
|
|
+ btrfs_level_size(root, level - 1));
|
|
} else {
|
|
} else {
|
|
p->slots[level] = slot;
|
|
p->slots[level] = slot;
|
|
if (ins_len > 0 && btrfs_leaf_free_space(root, b) <
|
|
if (ins_len > 0 && btrfs_leaf_free_space(root, b) <
|
|
@@ -1193,14 +1203,14 @@ static int insert_new_root(struct btrfs_trans_handle *trans,
|
|
BUG_ON(path->nodes[level]);
|
|
BUG_ON(path->nodes[level]);
|
|
BUG_ON(path->nodes[level-1] != root->node);
|
|
BUG_ON(path->nodes[level-1] != root->node);
|
|
|
|
|
|
- c = btrfs_alloc_free_block(trans, root,
|
|
|
|
- extent_buffer_blocknr(root->node), 0);
|
|
|
|
|
|
+ c = btrfs_alloc_free_block(trans, root, root->nodesize,
|
|
|
|
+ root->node->start, 0);
|
|
if (IS_ERR(c))
|
|
if (IS_ERR(c))
|
|
return PTR_ERR(c);
|
|
return PTR_ERR(c);
|
|
memset_extent_buffer(c, 0, 0, root->nodesize);
|
|
memset_extent_buffer(c, 0, 0, root->nodesize);
|
|
btrfs_set_header_nritems(c, 1);
|
|
btrfs_set_header_nritems(c, 1);
|
|
btrfs_set_header_level(c, level);
|
|
btrfs_set_header_level(c, level);
|
|
- btrfs_set_header_blocknr(c, extent_buffer_blocknr(c));
|
|
|
|
|
|
+ btrfs_set_header_bytenr(c, c->start);
|
|
btrfs_set_header_generation(c, trans->transid);
|
|
btrfs_set_header_generation(c, trans->transid);
|
|
btrfs_set_header_owner(c, root->root_key.objectid);
|
|
btrfs_set_header_owner(c, root->root_key.objectid);
|
|
lower = path->nodes[level-1];
|
|
lower = path->nodes[level-1];
|
|
@@ -1213,7 +1223,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans,
|
|
else
|
|
else
|
|
btrfs_node_key(lower, &lower_key, 0);
|
|
btrfs_node_key(lower, &lower_key, 0);
|
|
btrfs_set_node_key(c, &lower_key, 0);
|
|
btrfs_set_node_key(c, &lower_key, 0);
|
|
- btrfs_set_node_blockptr(c, 0, extent_buffer_blocknr(lower));
|
|
|
|
|
|
+ btrfs_set_node_blockptr(c, 0, lower->start);
|
|
|
|
|
|
btrfs_mark_buffer_dirty(c);
|
|
btrfs_mark_buffer_dirty(c);
|
|
|
|
|
|
@@ -1237,7 +1247,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans,
|
|
*/
|
|
*/
|
|
static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
*root, struct btrfs_path *path, struct btrfs_disk_key
|
|
*root, struct btrfs_path *path, struct btrfs_disk_key
|
|
- *key, u64 blocknr, int slot, int level)
|
|
|
|
|
|
+ *key, u64 bytenr, int slot, int level)
|
|
{
|
|
{
|
|
struct extent_buffer *lower;
|
|
struct extent_buffer *lower;
|
|
int nritems;
|
|
int nritems;
|
|
@@ -1256,10 +1266,9 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
(nritems - slot) * sizeof(struct btrfs_key_ptr));
|
|
(nritems - slot) * sizeof(struct btrfs_key_ptr));
|
|
}
|
|
}
|
|
btrfs_set_node_key(lower, key, slot);
|
|
btrfs_set_node_key(lower, key, slot);
|
|
- btrfs_set_node_blockptr(lower, slot, blocknr);
|
|
|
|
|
|
+ btrfs_set_node_blockptr(lower, slot, bytenr);
|
|
btrfs_set_header_nritems(lower, nritems + 1);
|
|
btrfs_set_header_nritems(lower, nritems + 1);
|
|
btrfs_mark_buffer_dirty(lower);
|
|
btrfs_mark_buffer_dirty(lower);
|
|
- check_node(root, path, level);
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1300,14 +1309,14 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
}
|
|
}
|
|
|
|
|
|
c_nritems = btrfs_header_nritems(c);
|
|
c_nritems = btrfs_header_nritems(c);
|
|
- split = btrfs_alloc_free_block(trans, root,
|
|
|
|
- extent_buffer_blocknr(c), 0);
|
|
|
|
|
|
+ split = btrfs_alloc_free_block(trans, root, root->nodesize,
|
|
|
|
+ c->start, 0);
|
|
if (IS_ERR(split))
|
|
if (IS_ERR(split))
|
|
return PTR_ERR(split);
|
|
return PTR_ERR(split);
|
|
|
|
|
|
btrfs_set_header_flags(split, btrfs_header_flags(c));
|
|
btrfs_set_header_flags(split, btrfs_header_flags(c));
|
|
btrfs_set_header_level(split, btrfs_header_level(c));
|
|
btrfs_set_header_level(split, btrfs_header_level(c));
|
|
- btrfs_set_header_blocknr(split, extent_buffer_blocknr(split));
|
|
|
|
|
|
+ btrfs_set_header_bytenr(split, split->start);
|
|
btrfs_set_header_generation(split, trans->transid);
|
|
btrfs_set_header_generation(split, trans->transid);
|
|
btrfs_set_header_owner(split, root->root_key.objectid);
|
|
btrfs_set_header_owner(split, root->root_key.objectid);
|
|
write_extent_buffer(split, root->fs_info->fsid,
|
|
write_extent_buffer(split, root->fs_info->fsid,
|
|
@@ -1328,8 +1337,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
btrfs_mark_buffer_dirty(split);
|
|
btrfs_mark_buffer_dirty(split);
|
|
|
|
|
|
btrfs_node_key(split, &disk_key, 0);
|
|
btrfs_node_key(split, &disk_key, 0);
|
|
- wret = insert_ptr(trans, root, path, &disk_key,
|
|
|
|
- extent_buffer_blocknr(split),
|
|
|
|
|
|
+ wret = insert_ptr(trans, root, path, &disk_key, split->start,
|
|
path->slots[level + 1] + 1,
|
|
path->slots[level + 1] + 1,
|
|
level + 1);
|
|
level + 1);
|
|
if (wret)
|
|
if (wret)
|
|
@@ -1407,6 +1415,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
u32 left_nritems;
|
|
u32 left_nritems;
|
|
u32 right_nritems;
|
|
u32 right_nritems;
|
|
u32 data_end;
|
|
u32 data_end;
|
|
|
|
+ u32 this_item_size;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
slot = path->slots[1];
|
|
slot = path->slots[1];
|
|
@@ -1417,7 +1426,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
if (slot >= btrfs_header_nritems(upper) - 1)
|
|
if (slot >= btrfs_header_nritems(upper) - 1)
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
- right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1));
|
|
|
|
|
|
+ right = read_tree_block(root, btrfs_node_blockptr(upper, slot + 1),
|
|
|
|
+ root->leafsize);
|
|
free_space = btrfs_leaf_free_space(root, right);
|
|
free_space = btrfs_leaf_free_space(root, right);
|
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
|
free_extent_buffer(right);
|
|
free_extent_buffer(right);
|
|
@@ -1445,13 +1455,27 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
|
|
|
for (i = left_nritems - 1; i >= 1; i--) {
|
|
for (i = left_nritems - 1; i >= 1; i--) {
|
|
item = btrfs_item_nr(left, i);
|
|
item = btrfs_item_nr(left, i);
|
|
|
|
+
|
|
if (path->slots[0] == i)
|
|
if (path->slots[0] == i)
|
|
push_space += data_size + sizeof(*item);
|
|
push_space += data_size + sizeof(*item);
|
|
- if (btrfs_item_size(left, item) + sizeof(*item) + push_space >
|
|
|
|
- free_space)
|
|
|
|
|
|
+
|
|
|
|
+ if (!left->map_token) {
|
|
|
|
+ map_extent_buffer(left, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &left->map_token, &left->kaddr,
|
|
|
|
+ &left->map_start, &left->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this_item_size = btrfs_item_size(left, item);
|
|
|
|
+ if (this_item_size + sizeof(*item) + push_space > free_space)
|
|
break;
|
|
break;
|
|
push_items++;
|
|
push_items++;
|
|
- push_space += btrfs_item_size(left, item) + sizeof(*item);
|
|
|
|
|
|
+ push_space += this_item_size + sizeof(*item);
|
|
|
|
+ }
|
|
|
|
+ if (left->map_token) {
|
|
|
|
+ unmap_extent_buffer(left, left->map_token, KM_USER1);
|
|
|
|
+ left->map_token = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
if (push_items == 0) {
|
|
if (push_items == 0) {
|
|
@@ -1493,11 +1517,23 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
right_nritems += push_items;
|
|
right_nritems += push_items;
|
|
btrfs_set_header_nritems(right, right_nritems);
|
|
btrfs_set_header_nritems(right, right_nritems);
|
|
push_space = BTRFS_LEAF_DATA_SIZE(root);
|
|
push_space = BTRFS_LEAF_DATA_SIZE(root);
|
|
|
|
+
|
|
for (i = 0; i < right_nritems; i++) {
|
|
for (i = 0; i < right_nritems; i++) {
|
|
item = btrfs_item_nr(right, i);
|
|
item = btrfs_item_nr(right, i);
|
|
- btrfs_set_item_offset(right, item, push_space -
|
|
|
|
- btrfs_item_size(right, item));
|
|
|
|
- push_space = btrfs_item_offset(right, item);
|
|
|
|
|
|
+ if (!right->map_token) {
|
|
|
|
+ map_extent_buffer(right, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &right->map_token, &right->kaddr,
|
|
|
|
+ &right->map_start, &right->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+ push_space -= btrfs_item_size(right, item);
|
|
|
|
+ btrfs_set_item_offset(right, item, push_space);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (right->map_token) {
|
|
|
|
+ unmap_extent_buffer(right, right->map_token, KM_USER1);
|
|
|
|
+ right->map_token = NULL;
|
|
}
|
|
}
|
|
left_nritems -= push_items;
|
|
left_nritems -= push_items;
|
|
btrfs_set_header_nritems(left, left_nritems);
|
|
btrfs_set_header_nritems(left, left_nritems);
|
|
@@ -1518,8 +1554,6 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
} else {
|
|
} else {
|
|
free_extent_buffer(right);
|
|
free_extent_buffer(right);
|
|
}
|
|
}
|
|
- if (path->nodes[1])
|
|
|
|
- check_node(root, path, 1);
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
@@ -1542,6 +1576,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
u32 right_nritems;
|
|
u32 right_nritems;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
int wret;
|
|
int wret;
|
|
|
|
+ u32 this_item_size;
|
|
|
|
+ u32 old_left_item_size;
|
|
|
|
|
|
slot = path->slots[1];
|
|
slot = path->slots[1];
|
|
if (slot == 0)
|
|
if (slot == 0)
|
|
@@ -1550,7 +1586,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
return 1;
|
|
return 1;
|
|
|
|
|
|
left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1],
|
|
left = read_tree_block(root, btrfs_node_blockptr(path->nodes[1],
|
|
- slot - 1));
|
|
|
|
|
|
+ slot - 1), root->leafsize);
|
|
free_space = btrfs_leaf_free_space(root, left);
|
|
free_space = btrfs_leaf_free_space(root, left);
|
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
|
if (free_space < data_size + sizeof(struct btrfs_item)) {
|
|
free_extent_buffer(left);
|
|
free_extent_buffer(left);
|
|
@@ -1579,14 +1615,30 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
|
|
|
for (i = 0; i < right_nritems - 1; i++) {
|
|
for (i = 0; i < right_nritems - 1; i++) {
|
|
item = btrfs_item_nr(right, i);
|
|
item = btrfs_item_nr(right, i);
|
|
|
|
+ if (!right->map_token) {
|
|
|
|
+ map_extent_buffer(right, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &right->map_token, &right->kaddr,
|
|
|
|
+ &right->map_start, &right->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (path->slots[0] == i)
|
|
if (path->slots[0] == i)
|
|
push_space += data_size + sizeof(*item);
|
|
push_space += data_size + sizeof(*item);
|
|
- if (btrfs_item_size(right, item) + sizeof(*item) + push_space >
|
|
|
|
- free_space)
|
|
|
|
|
|
+
|
|
|
|
+ this_item_size = btrfs_item_size(right, item);
|
|
|
|
+ if (this_item_size + sizeof(*item) + push_space > free_space)
|
|
break;
|
|
break;
|
|
|
|
+
|
|
push_items++;
|
|
push_items++;
|
|
- push_space += btrfs_item_size(right, item) + sizeof(*item);
|
|
|
|
|
|
+ push_space += this_item_size + sizeof(*item);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (right->map_token) {
|
|
|
|
+ unmap_extent_buffer(right, right->map_token, KM_USER1);
|
|
|
|
+ right->map_token = NULL;
|
|
}
|
|
}
|
|
|
|
+
|
|
if (push_items == 0) {
|
|
if (push_items == 0) {
|
|
free_extent_buffer(left);
|
|
free_extent_buffer(left);
|
|
return 1;
|
|
return 1;
|
|
@@ -1611,15 +1663,28 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
old_left_nritems = btrfs_header_nritems(left);
|
|
old_left_nritems = btrfs_header_nritems(left);
|
|
BUG_ON(old_left_nritems < 0);
|
|
BUG_ON(old_left_nritems < 0);
|
|
|
|
|
|
|
|
+ old_left_item_size = btrfs_item_offset_nr(left, old_left_nritems - 1);
|
|
for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
|
|
for (i = old_left_nritems; i < old_left_nritems + push_items; i++) {
|
|
u32 ioff;
|
|
u32 ioff;
|
|
|
|
+
|
|
item = btrfs_item_nr(left, i);
|
|
item = btrfs_item_nr(left, i);
|
|
|
|
+ if (!left->map_token) {
|
|
|
|
+ map_extent_buffer(left, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &left->map_token, &left->kaddr,
|
|
|
|
+ &left->map_start, &left->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
ioff = btrfs_item_offset(left, item);
|
|
ioff = btrfs_item_offset(left, item);
|
|
btrfs_set_item_offset(left, item,
|
|
btrfs_set_item_offset(left, item,
|
|
- ioff - (BTRFS_LEAF_DATA_SIZE(root) -
|
|
|
|
- btrfs_item_offset_nr(left, old_left_nritems - 1)));
|
|
|
|
|
|
+ ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size));
|
|
}
|
|
}
|
|
btrfs_set_header_nritems(left, old_left_nritems + push_items);
|
|
btrfs_set_header_nritems(left, old_left_nritems + push_items);
|
|
|
|
+ if (left->map_token) {
|
|
|
|
+ unmap_extent_buffer(left, left->map_token, KM_USER1);
|
|
|
|
+ left->map_token = NULL;
|
|
|
|
+ }
|
|
|
|
|
|
/* fixup right node */
|
|
/* fixup right node */
|
|
push_space = btrfs_item_offset_nr(right, push_items - 1) -
|
|
push_space = btrfs_item_offset_nr(right, push_items - 1) -
|
|
@@ -1640,9 +1705,21 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
|
|
|
for (i = 0; i < right_nritems; i++) {
|
|
for (i = 0; i < right_nritems; i++) {
|
|
item = btrfs_item_nr(right, i);
|
|
item = btrfs_item_nr(right, i);
|
|
- btrfs_set_item_offset(right, item, push_space -
|
|
|
|
- btrfs_item_size(right, item));
|
|
|
|
- push_space = btrfs_item_offset(right, item);
|
|
|
|
|
|
+
|
|
|
|
+ if (!right->map_token) {
|
|
|
|
+ map_extent_buffer(right, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &right->map_token, &right->kaddr,
|
|
|
|
+ &right->map_start, &right->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ push_space = push_space - btrfs_item_size(right, item);
|
|
|
|
+ btrfs_set_item_offset(right, item, push_space);
|
|
|
|
+ }
|
|
|
|
+ if (right->map_token) {
|
|
|
|
+ unmap_extent_buffer(right, right->map_token, KM_USER1);
|
|
|
|
+ right->map_token = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
btrfs_mark_buffer_dirty(left);
|
|
btrfs_mark_buffer_dirty(left);
|
|
@@ -1664,8 +1741,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
path->slots[0] -= push_items;
|
|
path->slots[0] -= push_items;
|
|
}
|
|
}
|
|
BUG_ON(path->slots[0] < 0);
|
|
BUG_ON(path->slots[0] < 0);
|
|
- if (path->nodes[1])
|
|
|
|
- check_node(root, path, 1);
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1718,13 +1793,13 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
nritems = btrfs_header_nritems(l);
|
|
nritems = btrfs_header_nritems(l);
|
|
mid = (nritems + 1)/ 2;
|
|
mid = (nritems + 1)/ 2;
|
|
|
|
|
|
- right = btrfs_alloc_free_block(trans, root,
|
|
|
|
- extent_buffer_blocknr(l), 0);
|
|
|
|
|
|
+ right = btrfs_alloc_free_block(trans, root, root->leafsize,
|
|
|
|
+ l->start, 0);
|
|
if (IS_ERR(right))
|
|
if (IS_ERR(right))
|
|
return PTR_ERR(right);
|
|
return PTR_ERR(right);
|
|
|
|
|
|
memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
|
|
memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
|
|
- btrfs_set_header_blocknr(right, extent_buffer_blocknr(right));
|
|
|
|
|
|
+ btrfs_set_header_bytenr(right, right->start);
|
|
btrfs_set_header_generation(right, trans->transid);
|
|
btrfs_set_header_generation(right, trans->transid);
|
|
btrfs_set_header_owner(right, root->root_key.objectid);
|
|
btrfs_set_header_owner(right, root->root_key.objectid);
|
|
btrfs_set_header_level(right, 0);
|
|
btrfs_set_header_level(right, 0);
|
|
@@ -1740,8 +1815,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
btrfs_cpu_key_to_disk(&disk_key, ins_key);
|
|
btrfs_cpu_key_to_disk(&disk_key, ins_key);
|
|
btrfs_set_header_nritems(right, 0);
|
|
btrfs_set_header_nritems(right, 0);
|
|
wret = insert_ptr(trans, root, path,
|
|
wret = insert_ptr(trans, root, path,
|
|
- &disk_key,
|
|
|
|
- extent_buffer_blocknr(right),
|
|
|
|
|
|
+ &disk_key, right->start,
|
|
path->slots[1] + 1, 1);
|
|
path->slots[1] + 1, 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
@@ -1762,7 +1836,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
btrfs_set_header_nritems(right, 0);
|
|
btrfs_set_header_nritems(right, 0);
|
|
wret = insert_ptr(trans, root, path,
|
|
wret = insert_ptr(trans, root, path,
|
|
&disk_key,
|
|
&disk_key,
|
|
- extent_buffer_blocknr(right),
|
|
|
|
|
|
+ right->start,
|
|
path->slots[1], 1);
|
|
path->slots[1], 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
@@ -1799,15 +1873,30 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
|
|
|
for (i = 0; i < nritems; i++) {
|
|
for (i = 0; i < nritems; i++) {
|
|
struct btrfs_item *item = btrfs_item_nr(right, i);
|
|
struct btrfs_item *item = btrfs_item_nr(right, i);
|
|
- u32 ioff = btrfs_item_offset(right, item);
|
|
|
|
|
|
+ u32 ioff;
|
|
|
|
+
|
|
|
|
+ if (!right->map_token) {
|
|
|
|
+ map_extent_buffer(right, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &right->map_token, &right->kaddr,
|
|
|
|
+ &right->map_start, &right->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ioff = btrfs_item_offset(right, item);
|
|
btrfs_set_item_offset(right, item, ioff + rt_data_off);
|
|
btrfs_set_item_offset(right, item, ioff + rt_data_off);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (right->map_token) {
|
|
|
|
+ unmap_extent_buffer(right, right->map_token, KM_USER1);
|
|
|
|
+ right->map_token = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
btrfs_set_header_nritems(l, mid);
|
|
btrfs_set_header_nritems(l, mid);
|
|
ret = 0;
|
|
ret = 0;
|
|
btrfs_item_key(right, &disk_key, 0);
|
|
btrfs_item_key(right, &disk_key, 0);
|
|
- wret = insert_ptr(trans, root, path, &disk_key,
|
|
|
|
- extent_buffer_blocknr(right), path->slots[1] + 1, 1);
|
|
|
|
|
|
+ wret = insert_ptr(trans, root, path, &disk_key, right->start,
|
|
|
|
+ path->slots[1] + 1, 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
|
|
|
|
@@ -1824,19 +1913,17 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
free_extent_buffer(right);
|
|
free_extent_buffer(right);
|
|
|
|
|
|
BUG_ON(path->slots[0] < 0);
|
|
BUG_ON(path->slots[0] < 0);
|
|
- check_node(root, path, 1);
|
|
|
|
- check_leaf(root, path, 0);
|
|
|
|
|
|
|
|
if (!double_split)
|
|
if (!double_split)
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
- right = btrfs_alloc_free_block(trans, root,
|
|
|
|
- extent_buffer_blocknr(l), 0);
|
|
|
|
|
|
+ right = btrfs_alloc_free_block(trans, root, root->leafsize,
|
|
|
|
+ l->start, 0);
|
|
if (IS_ERR(right))
|
|
if (IS_ERR(right))
|
|
return PTR_ERR(right);
|
|
return PTR_ERR(right);
|
|
|
|
|
|
memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
|
|
memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
|
|
- btrfs_set_header_blocknr(right, extent_buffer_blocknr(right));
|
|
|
|
|
|
+ btrfs_set_header_bytenr(right, right->start);
|
|
btrfs_set_header_generation(right, trans->transid);
|
|
btrfs_set_header_generation(right, trans->transid);
|
|
btrfs_set_header_owner(right, root->root_key.objectid);
|
|
btrfs_set_header_owner(right, root->root_key.objectid);
|
|
btrfs_set_header_level(right, 0);
|
|
btrfs_set_header_level(right, 0);
|
|
@@ -1847,8 +1934,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
btrfs_cpu_key_to_disk(&disk_key, ins_key);
|
|
btrfs_cpu_key_to_disk(&disk_key, ins_key);
|
|
btrfs_set_header_nritems(right, 0);
|
|
btrfs_set_header_nritems(right, 0);
|
|
wret = insert_ptr(trans, root, path,
|
|
wret = insert_ptr(trans, root, path,
|
|
- &disk_key,
|
|
|
|
- extent_buffer_blocknr(right),
|
|
|
|
|
|
+ &disk_key, right->start,
|
|
path->slots[1], 1);
|
|
path->slots[1], 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
@@ -1860,8 +1946,6 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
free_extent_buffer(path->nodes[0]);
|
|
free_extent_buffer(path->nodes[0]);
|
|
path->nodes[0] = right;
|
|
path->nodes[0] = right;
|
|
path->slots[0] = 0;
|
|
path->slots[0] = 0;
|
|
- check_node(root, path, 1);
|
|
|
|
- check_leaf(root, path, 0);
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1904,9 +1988,24 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
|
|
for (i = slot; i < nritems; i++) {
|
|
for (i = slot; i < nritems; i++) {
|
|
u32 ioff;
|
|
u32 ioff;
|
|
item = btrfs_item_nr(leaf, i);
|
|
item = btrfs_item_nr(leaf, i);
|
|
|
|
+
|
|
|
|
+ if (!leaf->map_token) {
|
|
|
|
+ map_extent_buffer(leaf, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &leaf->map_token, &leaf->kaddr,
|
|
|
|
+ &leaf->map_start, &leaf->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
btrfs_set_item_offset(leaf, item, ioff + size_diff);
|
|
btrfs_set_item_offset(leaf, item, ioff + size_diff);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (leaf->map_token) {
|
|
|
|
+ unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
|
|
|
|
+ leaf->map_token = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* shift the data */
|
|
/* shift the data */
|
|
memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
|
|
memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
|
|
data_end + size_diff, btrfs_leaf_data(leaf) +
|
|
data_end + size_diff, btrfs_leaf_data(leaf) +
|
|
@@ -1921,7 +2020,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
|
|
btrfs_print_leaf(root, leaf);
|
|
btrfs_print_leaf(root, leaf);
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
- check_leaf(root, path, 0);
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1963,10 +2061,23 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
|
|
for (i = slot; i < nritems; i++) {
|
|
for (i = slot; i < nritems; i++) {
|
|
u32 ioff;
|
|
u32 ioff;
|
|
item = btrfs_item_nr(leaf, i);
|
|
item = btrfs_item_nr(leaf, i);
|
|
|
|
+
|
|
|
|
+ if (!leaf->map_token) {
|
|
|
|
+ map_extent_buffer(leaf, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &leaf->map_token, &leaf->kaddr,
|
|
|
|
+ &leaf->map_start, &leaf->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
btrfs_set_item_offset(leaf, item, ioff - data_size);
|
|
btrfs_set_item_offset(leaf, item, ioff - data_size);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (leaf->map_token) {
|
|
|
|
+ unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
|
|
|
|
+ leaf->map_token = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* shift the data */
|
|
/* shift the data */
|
|
memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
|
|
memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
|
|
data_end - data_size, btrfs_leaf_data(leaf) +
|
|
data_end - data_size, btrfs_leaf_data(leaf) +
|
|
@@ -1983,7 +2094,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
|
|
btrfs_print_leaf(root, leaf);
|
|
btrfs_print_leaf(root, leaf);
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
- check_leaf(root, path, 0);
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2046,12 +2156,26 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
|
|
* 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 */
|
|
|
|
+ WARN_ON(leaf->map_token);
|
|
for (i = slot; i < nritems; i++) {
|
|
for (i = slot; i < nritems; i++) {
|
|
u32 ioff;
|
|
u32 ioff;
|
|
|
|
+
|
|
item = btrfs_item_nr(leaf, i);
|
|
item = btrfs_item_nr(leaf, i);
|
|
|
|
+ if (!leaf->map_token) {
|
|
|
|
+ map_extent_buffer(leaf, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &leaf->map_token, &leaf->kaddr,
|
|
|
|
+ &leaf->map_start, &leaf->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
|
|
+
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
btrfs_set_item_offset(leaf, item, ioff - data_size);
|
|
btrfs_set_item_offset(leaf, item, ioff - data_size);
|
|
}
|
|
}
|
|
|
|
+ if (leaf->map_token) {
|
|
|
|
+ unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
|
|
|
|
+ leaf->map_token = NULL;
|
|
|
|
+ }
|
|
|
|
|
|
/* shift the items */
|
|
/* shift the items */
|
|
memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1),
|
|
memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1),
|
|
@@ -2081,7 +2205,6 @@ int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
|
|
btrfs_print_leaf(root, leaf);
|
|
btrfs_print_leaf(root, leaf);
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
- check_leaf(root, path, 0);
|
|
|
|
out:
|
|
out:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -2186,10 +2309,24 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
|
|
|
|
for (i = slot + 1; i < nritems; i++) {
|
|
for (i = slot + 1; i < nritems; i++) {
|
|
u32 ioff;
|
|
u32 ioff;
|
|
|
|
+
|
|
item = btrfs_item_nr(leaf, i);
|
|
item = btrfs_item_nr(leaf, i);
|
|
|
|
+ if (!leaf->map_token) {
|
|
|
|
+ map_extent_buffer(leaf, (unsigned long)item,
|
|
|
|
+ sizeof(struct btrfs_item),
|
|
|
|
+ &leaf->map_token, &leaf->kaddr,
|
|
|
|
+ &leaf->map_start, &leaf->map_len,
|
|
|
|
+ KM_USER1);
|
|
|
|
+ }
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
ioff = btrfs_item_offset(leaf, item);
|
|
btrfs_set_item_offset(leaf, item, ioff + dsize);
|
|
btrfs_set_item_offset(leaf, item, ioff + dsize);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (leaf->map_token) {
|
|
|
|
+ unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
|
|
|
|
+ leaf->map_token = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot),
|
|
memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot),
|
|
btrfs_item_nr_offset(slot + 1),
|
|
btrfs_item_nr_offset(slot + 1),
|
|
sizeof(struct btrfs_item) *
|
|
sizeof(struct btrfs_item) *
|
|
@@ -2209,8 +2346,7 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
wret = btrfs_free_extent(trans, root,
|
|
wret = btrfs_free_extent(trans, root,
|
|
- extent_buffer_blocknr(leaf),
|
|
|
|
- 1, 1);
|
|
|
|
|
|
+ leaf->start, leaf->len, 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
}
|
|
}
|
|
@@ -2247,7 +2383,8 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
}
|
|
}
|
|
|
|
|
|
if (btrfs_header_nritems(leaf) == 0) {
|
|
if (btrfs_header_nritems(leaf) == 0) {
|
|
- u64 blocknr = extent_buffer_blocknr(leaf);
|
|
|
|
|
|
+ u64 bytenr = leaf->start;
|
|
|
|
+ u32 blocksize = leaf->len;
|
|
|
|
|
|
clean_tree_block(trans, root, leaf);
|
|
clean_tree_block(trans, root, leaf);
|
|
wait_on_tree_block_writeback(root, leaf);
|
|
wait_on_tree_block_writeback(root, leaf);
|
|
@@ -2257,8 +2394,8 @@ int btrfs_del_item(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
ret = wret;
|
|
ret = wret;
|
|
|
|
|
|
free_extent_buffer(leaf);
|
|
free_extent_buffer(leaf);
|
|
- wret = btrfs_free_extent(trans, root, blocknr,
|
|
|
|
- 1, 1);
|
|
|
|
|
|
+ wret = btrfs_free_extent(trans, root, bytenr,
|
|
|
|
+ blocksize, 1);
|
|
if (wret)
|
|
if (wret)
|
|
ret = wret;
|
|
ret = wret;
|
|
} else {
|
|
} else {
|
|
@@ -2281,7 +2418,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
|
|
{
|
|
{
|
|
int slot;
|
|
int slot;
|
|
int level = 1;
|
|
int level = 1;
|
|
- u64 blocknr;
|
|
|
|
|
|
+ u64 bytenr;
|
|
struct extent_buffer *c;
|
|
struct extent_buffer *c;
|
|
struct extent_buffer *next = NULL;
|
|
struct extent_buffer *next = NULL;
|
|
|
|
|
|
@@ -2296,14 +2433,15 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- blocknr = btrfs_node_blockptr(c, slot);
|
|
|
|
|
|
+ bytenr = btrfs_node_blockptr(c, slot);
|
|
if (next)
|
|
if (next)
|
|
free_extent_buffer(next);
|
|
free_extent_buffer(next);
|
|
|
|
|
|
if (path->reada)
|
|
if (path->reada)
|
|
reada_for_search(root, path, level, slot);
|
|
reada_for_search(root, path, level, slot);
|
|
|
|
|
|
- next = read_tree_block(root, blocknr);
|
|
|
|
|
|
+ next = read_tree_block(root, bytenr,
|
|
|
|
+ btrfs_level_size(root, level -1));
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
path->slots[level] = slot;
|
|
path->slots[level] = slot;
|
|
@@ -2317,7 +2455,8 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
|
|
break;
|
|
break;
|
|
if (path->reada)
|
|
if (path->reada)
|
|
reada_for_search(root, path, level, 0);
|
|
reada_for_search(root, path, level, 0);
|
|
- next = read_tree_block(root, btrfs_node_blockptr(next, 0));
|
|
|
|
|
|
+ next = read_tree_block(root, btrfs_node_blockptr(next, 0),
|
|
|
|
+ btrfs_level_size(root, level - 1));
|
|
}
|
|
}
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|