|
@@ -36,7 +36,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
|
|
struct btrfs_root *root,
|
|
struct btrfs_root *root,
|
|
struct extent_buffer *dst_buf,
|
|
struct extent_buffer *dst_buf,
|
|
struct extent_buffer *src_buf);
|
|
struct extent_buffer *src_buf);
|
|
-static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
|
|
|
|
+static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
struct btrfs_path *path, int level, int slot);
|
|
struct btrfs_path *path, int level, int slot);
|
|
|
|
|
|
struct btrfs_path *btrfs_alloc_path(void)
|
|
struct btrfs_path *btrfs_alloc_path(void)
|
|
@@ -344,8 +344,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
|
if (btrfs_block_can_be_shared(root, buf)) {
|
|
if (btrfs_block_can_be_shared(root, buf)) {
|
|
ret = btrfs_lookup_extent_info(trans, root, buf->start,
|
|
ret = btrfs_lookup_extent_info(trans, root, buf->start,
|
|
buf->len, &refs, &flags);
|
|
buf->len, &refs, &flags);
|
|
- BUG_ON(ret);
|
|
|
|
- BUG_ON(refs == 0);
|
|
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
|
|
+ if (refs == 0) {
|
|
|
|
+ ret = -EROFS;
|
|
|
|
+ btrfs_std_error(root->fs_info, ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
refs = 1;
|
|
refs = 1;
|
|
if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID ||
|
|
if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID ||
|
|
@@ -364,14 +369,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
|
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) &&
|
|
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) &&
|
|
!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) {
|
|
!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) {
|
|
ret = btrfs_inc_ref(trans, root, buf, 1, 1);
|
|
ret = btrfs_inc_ref(trans, root, buf, 1, 1);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ BUG_ON(ret); /* -ENOMEM */
|
|
|
|
|
|
if (root->root_key.objectid ==
|
|
if (root->root_key.objectid ==
|
|
BTRFS_TREE_RELOC_OBJECTID) {
|
|
BTRFS_TREE_RELOC_OBJECTID) {
|
|
ret = btrfs_dec_ref(trans, root, buf, 0, 1);
|
|
ret = btrfs_dec_ref(trans, root, buf, 0, 1);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ BUG_ON(ret); /* -ENOMEM */
|
|
ret = btrfs_inc_ref(trans, root, cow, 1, 1);
|
|
ret = btrfs_inc_ref(trans, root, cow, 1, 1);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ BUG_ON(ret); /* -ENOMEM */
|
|
}
|
|
}
|
|
new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
|
|
new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
|
|
} else {
|
|
} else {
|
|
@@ -381,14 +386,15 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
|
ret = btrfs_inc_ref(trans, root, cow, 1, 1);
|
|
ret = btrfs_inc_ref(trans, root, cow, 1, 1);
|
|
else
|
|
else
|
|
ret = btrfs_inc_ref(trans, root, cow, 0, 1);
|
|
ret = btrfs_inc_ref(trans, root, cow, 0, 1);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ BUG_ON(ret); /* -ENOMEM */
|
|
}
|
|
}
|
|
if (new_flags != 0) {
|
|
if (new_flags != 0) {
|
|
ret = btrfs_set_disk_extent_flags(trans, root,
|
|
ret = btrfs_set_disk_extent_flags(trans, root,
|
|
buf->start,
|
|
buf->start,
|
|
buf->len,
|
|
buf->len,
|
|
new_flags, 0);
|
|
new_flags, 0);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ if (ret)
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
|
|
if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
|
|
@@ -397,9 +403,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
|
|
ret = btrfs_inc_ref(trans, root, cow, 1, 1);
|
|
ret = btrfs_inc_ref(trans, root, cow, 1, 1);
|
|
else
|
|
else
|
|
ret = btrfs_inc_ref(trans, root, cow, 0, 1);
|
|
ret = btrfs_inc_ref(trans, root, cow, 0, 1);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ BUG_ON(ret); /* -ENOMEM */
|
|
ret = btrfs_dec_ref(trans, root, buf, 1, 1);
|
|
ret = btrfs_dec_ref(trans, root, buf, 1, 1);
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ BUG_ON(ret); /* -ENOMEM */
|
|
}
|
|
}
|
|
clean_tree_block(trans, root, buf);
|
|
clean_tree_block(trans, root, buf);
|
|
*last_ref = 1;
|
|
*last_ref = 1;
|
|
@@ -428,7 +434,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
|
{
|
|
{
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
struct extent_buffer *cow;
|
|
struct extent_buffer *cow;
|
|
- int level;
|
|
|
|
|
|
+ int level, ret;
|
|
int last_ref = 0;
|
|
int last_ref = 0;
|
|
int unlock_orig = 0;
|
|
int unlock_orig = 0;
|
|
u64 parent_start;
|
|
u64 parent_start;
|
|
@@ -480,7 +486,11 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
|
(unsigned long)btrfs_header_fsid(cow),
|
|
(unsigned long)btrfs_header_fsid(cow),
|
|
BTRFS_FSID_SIZE);
|
|
BTRFS_FSID_SIZE);
|
|
|
|
|
|
- update_ref_for_cow(trans, root, buf, cow, &last_ref);
|
|
|
|
|
|
+ ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
|
|
|
|
+ if (ret) {
|
|
|
|
+ btrfs_abort_transaction(trans, root, ret);
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
|
|
if (root->ref_cows)
|
|
if (root->ref_cows)
|
|
btrfs_reloc_cow_block(trans, root, buf, cow);
|
|
btrfs_reloc_cow_block(trans, root, buf, cow);
|
|
@@ -947,7 +957,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
/* promote the child to a root */
|
|
/* promote the child to a root */
|
|
child = read_node_slot(root, mid, 0);
|
|
child = read_node_slot(root, mid, 0);
|
|
- BUG_ON(!child);
|
|
|
|
|
|
+ if (!child) {
|
|
|
|
+ ret = -EROFS;
|
|
|
|
+ btrfs_std_error(root->fs_info, ret);
|
|
|
|
+ goto enospc;
|
|
|
|
+ }
|
|
|
|
+
|
|
btrfs_tree_lock(child);
|
|
btrfs_tree_lock(child);
|
|
btrfs_set_lock_blocking(child);
|
|
btrfs_set_lock_blocking(child);
|
|
ret = btrfs_cow_block(trans, root, child, mid, 0, &child);
|
|
ret = btrfs_cow_block(trans, root, child, mid, 0, &child);
|
|
@@ -1023,10 +1038,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
|
if (btrfs_header_nritems(right) == 0) {
|
|
if (btrfs_header_nritems(right) == 0) {
|
|
clean_tree_block(trans, root, right);
|
|
clean_tree_block(trans, root, right);
|
|
btrfs_tree_unlock(right);
|
|
btrfs_tree_unlock(right);
|
|
- wret = del_ptr(trans, root, path, level + 1, pslot +
|
|
|
|
- 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ del_ptr(trans, root, path, level + 1, pslot + 1);
|
|
root_sub_used(root, right->len);
|
|
root_sub_used(root, right->len);
|
|
btrfs_free_tree_block(trans, root, right, 0, 1, 0);
|
|
btrfs_free_tree_block(trans, root, right, 0, 1, 0);
|
|
free_extent_buffer_stale(right);
|
|
free_extent_buffer_stale(right);
|
|
@@ -1048,7 +1060,11 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
|
* otherwise we would have pulled some pointers from the
|
|
* otherwise we would have pulled some pointers from the
|
|
* right
|
|
* right
|
|
*/
|
|
*/
|
|
- BUG_ON(!left);
|
|
|
|
|
|
+ if (!left) {
|
|
|
|
+ ret = -EROFS;
|
|
|
|
+ btrfs_std_error(root->fs_info, ret);
|
|
|
|
+ goto enospc;
|
|
|
|
+ }
|
|
wret = balance_node_right(trans, root, mid, left);
|
|
wret = balance_node_right(trans, root, mid, left);
|
|
if (wret < 0) {
|
|
if (wret < 0) {
|
|
ret = wret;
|
|
ret = wret;
|
|
@@ -1064,9 +1080,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
|
if (btrfs_header_nritems(mid) == 0) {
|
|
if (btrfs_header_nritems(mid) == 0) {
|
|
clean_tree_block(trans, root, mid);
|
|
clean_tree_block(trans, root, mid);
|
|
btrfs_tree_unlock(mid);
|
|
btrfs_tree_unlock(mid);
|
|
- wret = del_ptr(trans, root, path, level + 1, pslot);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ del_ptr(trans, root, path, level + 1, pslot);
|
|
root_sub_used(root, mid->len);
|
|
root_sub_used(root, mid->len);
|
|
btrfs_free_tree_block(trans, root, mid, 0, 1, 0);
|
|
btrfs_free_tree_block(trans, root, mid, 0, 1, 0);
|
|
free_extent_buffer_stale(mid);
|
|
free_extent_buffer_stale(mid);
|
|
@@ -1905,15 +1919,12 @@ done:
|
|
* fixing up pointers when a given leaf/node is not in slot 0 of the
|
|
* fixing up pointers when a given leaf/node is not in slot 0 of the
|
|
* higher levels
|
|
* higher levels
|
|
*
|
|
*
|
|
- * If this fails to write a tree block, it returns -1, but continues
|
|
|
|
- * fixing up the blocks in ram so the tree is consistent.
|
|
|
|
*/
|
|
*/
|
|
-static int fixup_low_keys(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
- struct btrfs_disk_key *key, int level)
|
|
|
|
|
|
+static void fixup_low_keys(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
+ struct btrfs_disk_key *key, int level)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
- int ret = 0;
|
|
|
|
struct extent_buffer *t;
|
|
struct extent_buffer *t;
|
|
|
|
|
|
for (i = level; i < BTRFS_MAX_LEVEL; i++) {
|
|
for (i = level; i < BTRFS_MAX_LEVEL; i++) {
|
|
@@ -1926,7 +1937,6 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans,
|
|
if (tslot != 0)
|
|
if (tslot != 0)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1935,9 +1945,9 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans,
|
|
* This function isn't completely safe. It's the caller's responsibility
|
|
* This function isn't completely safe. It's the caller's responsibility
|
|
* that the new key won't break the order
|
|
* that the new key won't break the order
|
|
*/
|
|
*/
|
|
-int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
- struct btrfs_key *new_key)
|
|
|
|
|
|
+void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
+ struct btrfs_key *new_key)
|
|
{
|
|
{
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
struct extent_buffer *eb;
|
|
struct extent_buffer *eb;
|
|
@@ -1947,13 +1957,11 @@ int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans,
|
|
slot = path->slots[0];
|
|
slot = path->slots[0];
|
|
if (slot > 0) {
|
|
if (slot > 0) {
|
|
btrfs_item_key(eb, &disk_key, slot - 1);
|
|
btrfs_item_key(eb, &disk_key, slot - 1);
|
|
- if (comp_keys(&disk_key, new_key) >= 0)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ BUG_ON(comp_keys(&disk_key, new_key) >= 0);
|
|
}
|
|
}
|
|
if (slot < btrfs_header_nritems(eb) - 1) {
|
|
if (slot < btrfs_header_nritems(eb) - 1) {
|
|
btrfs_item_key(eb, &disk_key, slot + 1);
|
|
btrfs_item_key(eb, &disk_key, slot + 1);
|
|
- if (comp_keys(&disk_key, new_key) <= 0)
|
|
|
|
- return -1;
|
|
|
|
|
|
+ BUG_ON(comp_keys(&disk_key, new_key) <= 0);
|
|
}
|
|
}
|
|
|
|
|
|
btrfs_cpu_key_to_disk(&disk_key, new_key);
|
|
btrfs_cpu_key_to_disk(&disk_key, new_key);
|
|
@@ -1961,7 +1969,6 @@ int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans,
|
|
btrfs_mark_buffer_dirty(eb);
|
|
btrfs_mark_buffer_dirty(eb);
|
|
if (slot == 0)
|
|
if (slot == 0)
|
|
fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
- return 0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2164,12 +2171,11 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
|
|
*
|
|
*
|
|
* slot and level indicate where you want the key to go, and
|
|
* slot and level indicate where you want the key to go, and
|
|
* blocknr is the block the key points to.
|
|
* blocknr is the block the key points to.
|
|
- *
|
|
|
|
- * returns zero on success and < 0 on any error
|
|
|
|
*/
|
|
*/
|
|
-static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
|
|
- *root, struct btrfs_path *path, struct btrfs_disk_key
|
|
|
|
- *key, u64 bytenr, int slot, int level)
|
|
|
|
|
|
+static void insert_ptr(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
+ struct btrfs_disk_key *key, u64 bytenr,
|
|
|
|
+ int slot, int level)
|
|
{
|
|
{
|
|
struct extent_buffer *lower;
|
|
struct extent_buffer *lower;
|
|
int nritems;
|
|
int nritems;
|
|
@@ -2179,8 +2185,7 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
lower = path->nodes[level];
|
|
lower = path->nodes[level];
|
|
nritems = btrfs_header_nritems(lower);
|
|
nritems = btrfs_header_nritems(lower);
|
|
BUG_ON(slot > nritems);
|
|
BUG_ON(slot > nritems);
|
|
- if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
|
|
|
|
- BUG();
|
|
|
|
|
|
+ BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root));
|
|
if (slot != nritems) {
|
|
if (slot != nritems) {
|
|
memmove_extent_buffer(lower,
|
|
memmove_extent_buffer(lower,
|
|
btrfs_node_key_ptr_offset(slot + 1),
|
|
btrfs_node_key_ptr_offset(slot + 1),
|
|
@@ -2193,7 +2198,6 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
btrfs_set_node_ptr_generation(lower, slot, trans->transid);
|
|
btrfs_set_node_ptr_generation(lower, slot, trans->transid);
|
|
btrfs_set_header_nritems(lower, nritems + 1);
|
|
btrfs_set_header_nritems(lower, nritems + 1);
|
|
btrfs_mark_buffer_dirty(lower);
|
|
btrfs_mark_buffer_dirty(lower);
|
|
- return 0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2214,7 +2218,6 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
int mid;
|
|
int mid;
|
|
int ret;
|
|
int ret;
|
|
- int wret;
|
|
|
|
u32 c_nritems;
|
|
u32 c_nritems;
|
|
|
|
|
|
c = path->nodes[level];
|
|
c = path->nodes[level];
|
|
@@ -2271,11 +2274,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
|
|
btrfs_mark_buffer_dirty(c);
|
|
btrfs_mark_buffer_dirty(c);
|
|
btrfs_mark_buffer_dirty(split);
|
|
btrfs_mark_buffer_dirty(split);
|
|
|
|
|
|
- wret = insert_ptr(trans, root, path, &disk_key, split->start,
|
|
|
|
- path->slots[level + 1] + 1,
|
|
|
|
- level + 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ insert_ptr(trans, root, path, &disk_key, split->start,
|
|
|
|
+ path->slots[level + 1] + 1, level + 1);
|
|
|
|
|
|
if (path->slots[level] >= mid) {
|
|
if (path->slots[level] >= mid) {
|
|
path->slots[level] -= mid;
|
|
path->slots[level] -= mid;
|
|
@@ -2564,7 +2564,6 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
|
|
u32 old_left_nritems;
|
|
u32 old_left_nritems;
|
|
u32 nr;
|
|
u32 nr;
|
|
int ret = 0;
|
|
int ret = 0;
|
|
- int wret;
|
|
|
|
u32 this_item_size;
|
|
u32 this_item_size;
|
|
u32 old_left_item_size;
|
|
u32 old_left_item_size;
|
|
struct btrfs_map_token token;
|
|
struct btrfs_map_token token;
|
|
@@ -2675,9 +2674,7 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans,
|
|
clean_tree_block(trans, root, right);
|
|
clean_tree_block(trans, root, right);
|
|
|
|
|
|
btrfs_item_key(right, &disk_key, 0);
|
|
btrfs_item_key(right, &disk_key, 0);
|
|
- wret = fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
|
|
|
|
/* then fixup the leaf pointer in the path */
|
|
/* then fixup the leaf pointer in the path */
|
|
if (path->slots[0] < push_items) {
|
|
if (path->slots[0] < push_items) {
|
|
@@ -2748,7 +2745,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
path->nodes[1], slot - 1, &left);
|
|
path->nodes[1], slot - 1, &left);
|
|
if (ret) {
|
|
if (ret) {
|
|
/* we hit -ENOSPC, but it isn't fatal here */
|
|
/* we hit -ENOSPC, but it isn't fatal here */
|
|
- ret = 1;
|
|
|
|
|
|
+ if (ret == -ENOSPC)
|
|
|
|
+ ret = 1;
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2770,21 +2768,17 @@ out:
|
|
/*
|
|
/*
|
|
* split the path's leaf in two, making sure there is at least data_size
|
|
* split the path's leaf in two, making sure there is at least data_size
|
|
* available for the resulting leaf level of the path.
|
|
* available for the resulting leaf level of the path.
|
|
- *
|
|
|
|
- * returns 0 if all went well and < 0 on failure.
|
|
|
|
*/
|
|
*/
|
|
-static noinline int copy_for_split(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root,
|
|
|
|
- struct btrfs_path *path,
|
|
|
|
- struct extent_buffer *l,
|
|
|
|
- struct extent_buffer *right,
|
|
|
|
- int slot, int mid, int nritems)
|
|
|
|
|
|
+static noinline void copy_for_split(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root,
|
|
|
|
+ struct btrfs_path *path,
|
|
|
|
+ struct extent_buffer *l,
|
|
|
|
+ struct extent_buffer *right,
|
|
|
|
+ int slot, int mid, int nritems)
|
|
{
|
|
{
|
|
int data_copy_size;
|
|
int data_copy_size;
|
|
int rt_data_off;
|
|
int rt_data_off;
|
|
int i;
|
|
int i;
|
|
- int ret = 0;
|
|
|
|
- int wret;
|
|
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_map_token token;
|
|
struct btrfs_map_token token;
|
|
|
|
|
|
@@ -2816,12 +2810,9 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
|
|
}
|
|
}
|
|
|
|
|
|
btrfs_set_header_nritems(l, mid);
|
|
btrfs_set_header_nritems(l, mid);
|
|
- ret = 0;
|
|
|
|
btrfs_item_key(right, &disk_key, 0);
|
|
btrfs_item_key(right, &disk_key, 0);
|
|
- wret = insert_ptr(trans, root, path, &disk_key, right->start,
|
|
|
|
- path->slots[1] + 1, 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ insert_ptr(trans, root, path, &disk_key, right->start,
|
|
|
|
+ path->slots[1] + 1, 1);
|
|
|
|
|
|
btrfs_mark_buffer_dirty(right);
|
|
btrfs_mark_buffer_dirty(right);
|
|
btrfs_mark_buffer_dirty(l);
|
|
btrfs_mark_buffer_dirty(l);
|
|
@@ -2839,8 +2830,6 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
|
|
}
|
|
}
|
|
|
|
|
|
BUG_ON(path->slots[0] < 0);
|
|
BUG_ON(path->slots[0] < 0);
|
|
-
|
|
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -3029,12 +3018,8 @@ again:
|
|
if (split == 0) {
|
|
if (split == 0) {
|
|
if (mid <= slot) {
|
|
if (mid <= slot) {
|
|
btrfs_set_header_nritems(right, 0);
|
|
btrfs_set_header_nritems(right, 0);
|
|
- wret = insert_ptr(trans, root, path,
|
|
|
|
- &disk_key, right->start,
|
|
|
|
- path->slots[1] + 1, 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
-
|
|
|
|
|
|
+ insert_ptr(trans, root, path, &disk_key, right->start,
|
|
|
|
+ path->slots[1] + 1, 1);
|
|
btrfs_tree_unlock(path->nodes[0]);
|
|
btrfs_tree_unlock(path->nodes[0]);
|
|
free_extent_buffer(path->nodes[0]);
|
|
free_extent_buffer(path->nodes[0]);
|
|
path->nodes[0] = right;
|
|
path->nodes[0] = right;
|
|
@@ -3042,29 +3027,21 @@ again:
|
|
path->slots[1] += 1;
|
|
path->slots[1] += 1;
|
|
} else {
|
|
} else {
|
|
btrfs_set_header_nritems(right, 0);
|
|
btrfs_set_header_nritems(right, 0);
|
|
- wret = insert_ptr(trans, root, path,
|
|
|
|
- &disk_key,
|
|
|
|
- right->start,
|
|
|
|
|
|
+ insert_ptr(trans, root, path, &disk_key, right->start,
|
|
path->slots[1], 1);
|
|
path->slots[1], 1);
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
btrfs_tree_unlock(path->nodes[0]);
|
|
btrfs_tree_unlock(path->nodes[0]);
|
|
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;
|
|
- if (path->slots[1] == 0) {
|
|
|
|
- wret = fixup_low_keys(trans, root,
|
|
|
|
- path, &disk_key, 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
- }
|
|
|
|
|
|
+ if (path->slots[1] == 0)
|
|
|
|
+ fixup_low_keys(trans, root, path,
|
|
|
|
+ &disk_key, 1);
|
|
}
|
|
}
|
|
btrfs_mark_buffer_dirty(right);
|
|
btrfs_mark_buffer_dirty(right);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
- ret = copy_for_split(trans, root, path, l, right, slot, mid, nritems);
|
|
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ copy_for_split(trans, root, path, l, right, slot, mid, nritems);
|
|
|
|
|
|
if (split == 2) {
|
|
if (split == 2) {
|
|
BUG_ON(num_doubles != 0);
|
|
BUG_ON(num_doubles != 0);
|
|
@@ -3072,7 +3049,7 @@ again:
|
|
goto again;
|
|
goto again;
|
|
}
|
|
}
|
|
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return 0;
|
|
|
|
|
|
push_for_double:
|
|
push_for_double:
|
|
push_for_double_split(trans, root, path, data_size);
|
|
push_for_double_split(trans, root, path, data_size);
|
|
@@ -3274,11 +3251,9 @@ int btrfs_duplicate_item(struct btrfs_trans_handle *trans,
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
path->slots[0]++;
|
|
path->slots[0]++;
|
|
- ret = setup_items_for_insert(trans, root, path, new_key, &item_size,
|
|
|
|
- item_size, item_size +
|
|
|
|
- sizeof(struct btrfs_item), 1);
|
|
|
|
- BUG_ON(ret);
|
|
|
|
-
|
|
|
|
|
|
+ setup_items_for_insert(trans, root, path, new_key, &item_size,
|
|
|
|
+ item_size, item_size +
|
|
|
|
+ sizeof(struct btrfs_item), 1);
|
|
leaf = path->nodes[0];
|
|
leaf = path->nodes[0];
|
|
memcpy_extent_buffer(leaf,
|
|
memcpy_extent_buffer(leaf,
|
|
btrfs_item_ptr_offset(leaf, path->slots[0]),
|
|
btrfs_item_ptr_offset(leaf, path->slots[0]),
|
|
@@ -3293,10 +3268,10 @@ int btrfs_duplicate_item(struct btrfs_trans_handle *trans,
|
|
* off the end of the item or if we shift the item to chop bytes off
|
|
* off the end of the item or if we shift the item to chop bytes off
|
|
* the front.
|
|
* the front.
|
|
*/
|
|
*/
|
|
-int btrfs_truncate_item(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root,
|
|
|
|
- struct btrfs_path *path,
|
|
|
|
- u32 new_size, int from_end)
|
|
|
|
|
|
+void btrfs_truncate_item(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root,
|
|
|
|
+ struct btrfs_path *path,
|
|
|
|
+ u32 new_size, int from_end)
|
|
{
|
|
{
|
|
int slot;
|
|
int slot;
|
|
struct extent_buffer *leaf;
|
|
struct extent_buffer *leaf;
|
|
@@ -3316,7 +3291,7 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
old_size = btrfs_item_size_nr(leaf, slot);
|
|
old_size = btrfs_item_size_nr(leaf, slot);
|
|
if (old_size == new_size)
|
|
if (old_size == new_size)
|
|
- return 0;
|
|
|
|
|
|
+ return;
|
|
|
|
|
|
nritems = btrfs_header_nritems(leaf);
|
|
nritems = btrfs_header_nritems(leaf);
|
|
data_end = leaf_data_end(root, leaf);
|
|
data_end = leaf_data_end(root, leaf);
|
|
@@ -3390,15 +3365,14 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
|
|
btrfs_print_leaf(root, leaf);
|
|
btrfs_print_leaf(root, leaf);
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
- return 0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* make the item pointed to by the path bigger, data_size is the new size.
|
|
* make the item pointed to by the path bigger, data_size is the new size.
|
|
*/
|
|
*/
|
|
-int btrfs_extend_item(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
- u32 data_size)
|
|
|
|
|
|
+void btrfs_extend_item(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
+ u32 data_size)
|
|
{
|
|
{
|
|
int slot;
|
|
int slot;
|
|
struct extent_buffer *leaf;
|
|
struct extent_buffer *leaf;
|
|
@@ -3460,7 +3434,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
|
|
btrfs_print_leaf(root, leaf);
|
|
btrfs_print_leaf(root, leaf);
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
- return 0;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -3593,7 +3566,7 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
|
|
ret = 0;
|
|
ret = 0;
|
|
if (slot == 0) {
|
|
if (slot == 0) {
|
|
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
|
|
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
|
|
- ret = fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
|
|
|
|
+ fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
}
|
|
}
|
|
|
|
|
|
if (btrfs_leaf_free_space(root, leaf) < 0) {
|
|
if (btrfs_leaf_free_space(root, leaf) < 0) {
|
|
@@ -3611,17 +3584,16 @@ out:
|
|
* to save stack depth by doing the bulk of the work in a function
|
|
* to save stack depth by doing the bulk of the work in a function
|
|
* that doesn't call btrfs_search_slot
|
|
* that doesn't call btrfs_search_slot
|
|
*/
|
|
*/
|
|
-int setup_items_for_insert(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
- struct btrfs_key *cpu_key, u32 *data_size,
|
|
|
|
- u32 total_data, u32 total_size, int nr)
|
|
|
|
|
|
+void setup_items_for_insert(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root, struct btrfs_path *path,
|
|
|
|
+ struct btrfs_key *cpu_key, u32 *data_size,
|
|
|
|
+ u32 total_data, u32 total_size, int nr)
|
|
{
|
|
{
|
|
struct btrfs_item *item;
|
|
struct btrfs_item *item;
|
|
int i;
|
|
int i;
|
|
u32 nritems;
|
|
u32 nritems;
|
|
unsigned int data_end;
|
|
unsigned int data_end;
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
- int ret;
|
|
|
|
struct extent_buffer *leaf;
|
|
struct extent_buffer *leaf;
|
|
int slot;
|
|
int slot;
|
|
struct btrfs_map_token token;
|
|
struct btrfs_map_token token;
|
|
@@ -3687,10 +3659,9 @@ int setup_items_for_insert(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
btrfs_set_header_nritems(leaf, nritems + nr);
|
|
btrfs_set_header_nritems(leaf, nritems + nr);
|
|
|
|
|
|
- ret = 0;
|
|
|
|
if (slot == 0) {
|
|
if (slot == 0) {
|
|
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
|
|
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
|
|
- ret = fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
|
|
|
|
+ fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
}
|
|
}
|
|
btrfs_unlock_up_safe(path, 1);
|
|
btrfs_unlock_up_safe(path, 1);
|
|
btrfs_mark_buffer_dirty(leaf);
|
|
btrfs_mark_buffer_dirty(leaf);
|
|
@@ -3699,7 +3670,6 @@ int setup_items_for_insert(struct btrfs_trans_handle *trans,
|
|
btrfs_print_leaf(root, leaf);
|
|
btrfs_print_leaf(root, leaf);
|
|
BUG();
|
|
BUG();
|
|
}
|
|
}
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -3726,16 +3696,14 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
|
|
if (ret == 0)
|
|
if (ret == 0)
|
|
return -EEXIST;
|
|
return -EEXIST;
|
|
if (ret < 0)
|
|
if (ret < 0)
|
|
- goto out;
|
|
|
|
|
|
+ return ret;
|
|
|
|
|
|
slot = path->slots[0];
|
|
slot = path->slots[0];
|
|
BUG_ON(slot < 0);
|
|
BUG_ON(slot < 0);
|
|
|
|
|
|
- ret = setup_items_for_insert(trans, root, path, cpu_key, data_size,
|
|
|
|
|
|
+ setup_items_for_insert(trans, root, path, cpu_key, data_size,
|
|
total_data, total_size, nr);
|
|
total_data, total_size, nr);
|
|
-
|
|
|
|
-out:
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -3771,13 +3739,11 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
|
|
* the tree should have been previously balanced so the deletion does not
|
|
* the tree should have been previously balanced so the deletion does not
|
|
* empty a node.
|
|
* empty a node.
|
|
*/
|
|
*/
|
|
-static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
|
|
- struct btrfs_path *path, int level, int slot)
|
|
|
|
|
|
+static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
|
|
+ struct btrfs_path *path, int level, int slot)
|
|
{
|
|
{
|
|
struct extent_buffer *parent = path->nodes[level];
|
|
struct extent_buffer *parent = path->nodes[level];
|
|
u32 nritems;
|
|
u32 nritems;
|
|
- int ret = 0;
|
|
|
|
- int wret;
|
|
|
|
|
|
|
|
nritems = btrfs_header_nritems(parent);
|
|
nritems = btrfs_header_nritems(parent);
|
|
if (slot != nritems - 1) {
|
|
if (slot != nritems - 1) {
|
|
@@ -3797,12 +3763,9 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
|
|
|
|
btrfs_node_key(parent, &disk_key, 0);
|
|
btrfs_node_key(parent, &disk_key, 0);
|
|
- wret = fixup_low_keys(trans, root, path, &disk_key, level + 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ fixup_low_keys(trans, root, path, &disk_key, level + 1);
|
|
}
|
|
}
|
|
btrfs_mark_buffer_dirty(parent);
|
|
btrfs_mark_buffer_dirty(parent);
|
|
- return ret;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -3815,17 +3778,13 @@ static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
* The path must have already been setup for deleting the leaf, including
|
|
* The path must have already been setup for deleting the leaf, including
|
|
* all the proper balancing. path->nodes[1] must be locked.
|
|
* all the proper balancing. path->nodes[1] must be locked.
|
|
*/
|
|
*/
|
|
-static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
|
|
|
|
- struct btrfs_root *root,
|
|
|
|
- struct btrfs_path *path,
|
|
|
|
- struct extent_buffer *leaf)
|
|
|
|
|
|
+static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans,
|
|
|
|
+ struct btrfs_root *root,
|
|
|
|
+ struct btrfs_path *path,
|
|
|
|
+ struct extent_buffer *leaf)
|
|
{
|
|
{
|
|
- int ret;
|
|
|
|
-
|
|
|
|
WARN_ON(btrfs_header_generation(leaf) != trans->transid);
|
|
WARN_ON(btrfs_header_generation(leaf) != trans->transid);
|
|
- ret = del_ptr(trans, root, path, 1, path->slots[1]);
|
|
|
|
- if (ret)
|
|
|
|
- return ret;
|
|
|
|
|
|
+ del_ptr(trans, root, path, 1, path->slots[1]);
|
|
|
|
|
|
/*
|
|
/*
|
|
* btrfs_free_extent is expensive, we want to make sure we
|
|
* btrfs_free_extent is expensive, we want to make sure we
|
|
@@ -3838,7 +3797,6 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
|
|
extent_buffer_get(leaf);
|
|
extent_buffer_get(leaf);
|
|
btrfs_free_tree_block(trans, root, leaf, 0, 1, 0);
|
|
btrfs_free_tree_block(trans, root, leaf, 0, 1, 0);
|
|
free_extent_buffer_stale(leaf);
|
|
free_extent_buffer_stale(leaf);
|
|
- return 0;
|
|
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
* delete the item at the leaf level in path. If that empties
|
|
* delete the item at the leaf level in path. If that empties
|
|
@@ -3899,8 +3857,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
} else {
|
|
} else {
|
|
btrfs_set_path_blocking(path);
|
|
btrfs_set_path_blocking(path);
|
|
clean_tree_block(trans, root, leaf);
|
|
clean_tree_block(trans, root, leaf);
|
|
- ret = btrfs_del_leaf(trans, root, path, leaf);
|
|
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ btrfs_del_leaf(trans, root, path, leaf);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
int used = leaf_space_used(leaf, 0, nritems);
|
|
int used = leaf_space_used(leaf, 0, nritems);
|
|
@@ -3908,10 +3865,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
struct btrfs_disk_key disk_key;
|
|
struct btrfs_disk_key disk_key;
|
|
|
|
|
|
btrfs_item_key(leaf, &disk_key, 0);
|
|
btrfs_item_key(leaf, &disk_key, 0);
|
|
- wret = fixup_low_keys(trans, root, path,
|
|
|
|
- &disk_key, 1);
|
|
|
|
- if (wret)
|
|
|
|
- ret = wret;
|
|
|
|
|
|
+ fixup_low_keys(trans, root, path, &disk_key, 1);
|
|
}
|
|
}
|
|
|
|
|
|
/* delete the leaf if it is mostly empty */
|
|
/* delete the leaf if it is mostly empty */
|
|
@@ -3939,9 +3893,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
|
|
|
|
|
if (btrfs_header_nritems(leaf) == 0) {
|
|
if (btrfs_header_nritems(leaf) == 0) {
|
|
path->slots[1] = slot;
|
|
path->slots[1] = slot;
|
|
- ret = btrfs_del_leaf(trans, root, path, leaf);
|
|
|
|
- BUG_ON(ret);
|
|
|
|
|
|
+ btrfs_del_leaf(trans, root, path, leaf);
|
|
free_extent_buffer(leaf);
|
|
free_extent_buffer(leaf);
|
|
|
|
+ ret = 0;
|
|
} else {
|
|
} else {
|
|
/* if we're still in the path, make sure
|
|
/* if we're still in the path, make sure
|
|
* we're dirty. Otherwise, one of the
|
|
* we're dirty. Otherwise, one of the
|
|
@@ -4124,7 +4078,7 @@ find_next_key:
|
|
}
|
|
}
|
|
btrfs_set_path_blocking(path);
|
|
btrfs_set_path_blocking(path);
|
|
cur = read_node_slot(root, cur, slot);
|
|
cur = read_node_slot(root, cur, slot);
|
|
- BUG_ON(!cur);
|
|
|
|
|
|
+ BUG_ON(!cur); /* -ENOMEM */
|
|
|
|
|
|
btrfs_tree_read_lock(cur);
|
|
btrfs_tree_read_lock(cur);
|
|
|
|
|