aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 07c1a96aa4a8..69ce3f7deeef 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -38,7 +38,8 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
38 struct extent_buffer *dst_buf, 38 struct extent_buffer *dst_buf,
39 struct extent_buffer *src_buf); 39 struct extent_buffer *src_buf);
40static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 40static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
41 struct btrfs_path *path, int level, int slot); 41 struct btrfs_path *path, int level, int slot,
42 int tree_mod_log);
42static void tree_mod_log_free_eb(struct btrfs_fs_info *fs_info, 43static void tree_mod_log_free_eb(struct btrfs_fs_info *fs_info,
43 struct extent_buffer *eb); 44 struct extent_buffer *eb);
44struct extent_buffer *read_old_tree_block(struct btrfs_root *root, u64 bytenr, 45struct extent_buffer *read_old_tree_block(struct btrfs_root *root, u64 bytenr,
@@ -1465,7 +1466,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
1465 if (btrfs_header_nritems(right) == 0) { 1466 if (btrfs_header_nritems(right) == 0) {
1466 clean_tree_block(trans, root, right); 1467 clean_tree_block(trans, root, right);
1467 btrfs_tree_unlock(right); 1468 btrfs_tree_unlock(right);
1468 del_ptr(trans, root, path, level + 1, pslot + 1); 1469 del_ptr(trans, root, path, level + 1, pslot + 1, 1);
1469 root_sub_used(root, right->len); 1470 root_sub_used(root, right->len);
1470 btrfs_free_tree_block(trans, root, right, 0, 1); 1471 btrfs_free_tree_block(trans, root, right, 0, 1);
1471 free_extent_buffer_stale(right); 1472 free_extent_buffer_stale(right);
@@ -1509,7 +1510,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
1509 if (btrfs_header_nritems(mid) == 0) { 1510 if (btrfs_header_nritems(mid) == 0) {
1510 clean_tree_block(trans, root, mid); 1511 clean_tree_block(trans, root, mid);
1511 btrfs_tree_unlock(mid); 1512 btrfs_tree_unlock(mid);
1512 del_ptr(trans, root, path, level + 1, pslot); 1513 del_ptr(trans, root, path, level + 1, pslot, 1);
1513 root_sub_used(root, mid->len); 1514 root_sub_used(root, mid->len);
1514 btrfs_free_tree_block(trans, root, mid, 0, 1); 1515 btrfs_free_tree_block(trans, root, mid, 0, 1);
1515 free_extent_buffer_stale(mid); 1516 free_extent_buffer_stale(mid);
@@ -2626,10 +2627,11 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
2626static void insert_ptr(struct btrfs_trans_handle *trans, 2627static void insert_ptr(struct btrfs_trans_handle *trans,
2627 struct btrfs_root *root, struct btrfs_path *path, 2628 struct btrfs_root *root, struct btrfs_path *path,
2628 struct btrfs_disk_key *key, u64 bytenr, 2629 struct btrfs_disk_key *key, u64 bytenr,
2629 int slot, int level) 2630 int slot, int level, int tree_mod_log)
2630{ 2631{
2631 struct extent_buffer *lower; 2632 struct extent_buffer *lower;
2632 int nritems; 2633 int nritems;
2634 int ret;
2633 2635
2634 BUG_ON(!path->nodes[level]); 2636 BUG_ON(!path->nodes[level]);
2635 btrfs_assert_tree_locked(path->nodes[level]); 2637 btrfs_assert_tree_locked(path->nodes[level]);
@@ -2638,11 +2640,19 @@ static void insert_ptr(struct btrfs_trans_handle *trans,
2638 BUG_ON(slot > nritems); 2640 BUG_ON(slot > nritems);
2639 BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root)); 2641 BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root));
2640 if (slot != nritems) { 2642 if (slot != nritems) {
2643 if (tree_mod_log && level)
2644 tree_mod_log_eb_move(root->fs_info, lower, slot + 1,
2645 slot, nritems - slot);
2641 memmove_extent_buffer(lower, 2646 memmove_extent_buffer(lower,
2642 btrfs_node_key_ptr_offset(slot + 1), 2647 btrfs_node_key_ptr_offset(slot + 1),
2643 btrfs_node_key_ptr_offset(slot), 2648 btrfs_node_key_ptr_offset(slot),
2644 (nritems - slot) * sizeof(struct btrfs_key_ptr)); 2649 (nritems - slot) * sizeof(struct btrfs_key_ptr));
2645 } 2650 }
2651 if (tree_mod_log && level) {
2652 ret = tree_mod_log_insert_key(root->fs_info, lower, slot,
2653 MOD_LOG_KEY_ADD);
2654 BUG_ON(ret < 0);
2655 }
2646 btrfs_set_node_key(lower, key, slot); 2656 btrfs_set_node_key(lower, key, slot);
2647 btrfs_set_node_blockptr(lower, slot, bytenr); 2657 btrfs_set_node_blockptr(lower, slot, bytenr);
2648 WARN_ON(trans->transid == 0); 2658 WARN_ON(trans->transid == 0);
@@ -2726,7 +2736,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
2726 btrfs_mark_buffer_dirty(split); 2736 btrfs_mark_buffer_dirty(split);
2727 2737
2728 insert_ptr(trans, root, path, &disk_key, split->start, 2738 insert_ptr(trans, root, path, &disk_key, split->start,
2729 path->slots[level + 1] + 1, level + 1); 2739 path->slots[level + 1] + 1, level + 1, 1);
2730 2740
2731 if (path->slots[level] >= mid) { 2741 if (path->slots[level] >= mid) {
2732 path->slots[level] -= mid; 2742 path->slots[level] -= mid;
@@ -3263,7 +3273,7 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans,
3263 btrfs_set_header_nritems(l, mid); 3273 btrfs_set_header_nritems(l, mid);
3264 btrfs_item_key(right, &disk_key, 0); 3274 btrfs_item_key(right, &disk_key, 0);
3265 insert_ptr(trans, root, path, &disk_key, right->start, 3275 insert_ptr(trans, root, path, &disk_key, right->start,
3266 path->slots[1] + 1, 1); 3276 path->slots[1] + 1, 1, 0);
3267 3277
3268 btrfs_mark_buffer_dirty(right); 3278 btrfs_mark_buffer_dirty(right);
3269 btrfs_mark_buffer_dirty(l); 3279 btrfs_mark_buffer_dirty(l);
@@ -3470,7 +3480,7 @@ again:
3470 if (mid <= slot) { 3480 if (mid <= slot) {
3471 btrfs_set_header_nritems(right, 0); 3481 btrfs_set_header_nritems(right, 0);
3472 insert_ptr(trans, root, path, &disk_key, right->start, 3482 insert_ptr(trans, root, path, &disk_key, right->start,
3473 path->slots[1] + 1, 1); 3483 path->slots[1] + 1, 1, 0);
3474 btrfs_tree_unlock(path->nodes[0]); 3484 btrfs_tree_unlock(path->nodes[0]);
3475 free_extent_buffer(path->nodes[0]); 3485 free_extent_buffer(path->nodes[0]);
3476 path->nodes[0] = right; 3486 path->nodes[0] = right;
@@ -3479,7 +3489,7 @@ again:
3479 } else { 3489 } else {
3480 btrfs_set_header_nritems(right, 0); 3490 btrfs_set_header_nritems(right, 0);
3481 insert_ptr(trans, root, path, &disk_key, right->start, 3491 insert_ptr(trans, root, path, &disk_key, right->start,
3482 path->slots[1], 1); 3492 path->slots[1], 1, 0);
3483 btrfs_tree_unlock(path->nodes[0]); 3493 btrfs_tree_unlock(path->nodes[0]);
3484 free_extent_buffer(path->nodes[0]); 3494 free_extent_buffer(path->nodes[0]);
3485 path->nodes[0] = right; 3495 path->nodes[0] = right;
@@ -4191,19 +4201,31 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
4191 * empty a node. 4201 * empty a node.
4192 */ 4202 */
4193static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 4203static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
4194 struct btrfs_path *path, int level, int slot) 4204 struct btrfs_path *path, int level, int slot,
4205 int tree_mod_log)
4195{ 4206{
4196 struct extent_buffer *parent = path->nodes[level]; 4207 struct extent_buffer *parent = path->nodes[level];
4197 u32 nritems; 4208 u32 nritems;
4209 int ret;
4198 4210
4199 nritems = btrfs_header_nritems(parent); 4211 nritems = btrfs_header_nritems(parent);
4200 if (slot != nritems - 1) { 4212 if (slot != nritems - 1) {
4213 if (tree_mod_log && level)
4214 tree_mod_log_eb_move(root->fs_info, parent, slot,
4215 slot + 1, nritems - slot - 1);
4201 memmove_extent_buffer(parent, 4216 memmove_extent_buffer(parent,
4202 btrfs_node_key_ptr_offset(slot), 4217 btrfs_node_key_ptr_offset(slot),
4203 btrfs_node_key_ptr_offset(slot + 1), 4218 btrfs_node_key_ptr_offset(slot + 1),
4204 sizeof(struct btrfs_key_ptr) * 4219 sizeof(struct btrfs_key_ptr) *
4205 (nritems - slot - 1)); 4220 (nritems - slot - 1));
4206 } 4221 }
4222
4223 if (tree_mod_log && level) {
4224 ret = tree_mod_log_insert_key(root->fs_info, parent, slot,
4225 MOD_LOG_KEY_REMOVE);
4226 BUG_ON(ret < 0);
4227 }
4228
4207 nritems--; 4229 nritems--;
4208 btrfs_set_header_nritems(parent, nritems); 4230 btrfs_set_header_nritems(parent, nritems);
4209 if (nritems == 0 && parent == root->node) { 4231 if (nritems == 0 && parent == root->node) {
@@ -4235,7 +4257,7 @@ static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans,
4235 struct extent_buffer *leaf) 4257 struct extent_buffer *leaf)
4236{ 4258{
4237 WARN_ON(btrfs_header_generation(leaf) != trans->transid); 4259 WARN_ON(btrfs_header_generation(leaf) != trans->transid);
4238 del_ptr(trans, root, path, 1, path->slots[1]); 4260 del_ptr(trans, root, path, 1, path->slots[1], 1);
4239 4261
4240 /* 4262 /*
4241 * btrfs_free_extent is expensive, we want to make sure we 4263 * btrfs_free_extent is expensive, we want to make sure we