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.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index ac999f0060b6..319f9f9bf8d4 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -29,7 +29,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
29 struct btrfs_path *path, int data_size, int extend); 29 struct btrfs_path *path, int data_size, int extend);
30static int push_node_left(struct btrfs_trans_handle *trans, 30static int push_node_left(struct btrfs_trans_handle *trans,
31 struct btrfs_root *root, struct extent_buffer *dst, 31 struct btrfs_root *root, struct extent_buffer *dst,
32 struct extent_buffer *src); 32 struct extent_buffer *src, int empty);
33static int balance_node_right(struct btrfs_trans_handle *trans, 33static int balance_node_right(struct btrfs_trans_handle *trans,
34 struct btrfs_root *root, 34 struct btrfs_root *root,
35 struct extent_buffer *dst_buf, 35 struct extent_buffer *dst_buf,
@@ -789,7 +789,7 @@ static int balance_level(struct btrfs_trans_handle *trans,
789 /* first, try to make some room in the middle buffer */ 789 /* first, try to make some room in the middle buffer */
790 if (left) { 790 if (left) {
791 orig_slot += btrfs_header_nritems(left); 791 orig_slot += btrfs_header_nritems(left);
792 wret = push_node_left(trans, root, left, mid); 792 wret = push_node_left(trans, root, left, mid, 0);
793 if (wret < 0) 793 if (wret < 0)
794 ret = wret; 794 ret = wret;
795 if (btrfs_header_nritems(mid) < 2) 795 if (btrfs_header_nritems(mid) < 2)
@@ -800,7 +800,7 @@ static int balance_level(struct btrfs_trans_handle *trans,
800 * then try to empty the right most buffer into the middle 800 * then try to empty the right most buffer into the middle
801 */ 801 */
802 if (right) { 802 if (right) {
803 wret = push_node_left(trans, root, mid, right); 803 wret = push_node_left(trans, root, mid, right, 1);
804 if (wret < 0 && wret != -ENOSPC) 804 if (wret < 0 && wret != -ENOSPC)
805 ret = wret; 805 ret = wret;
806 if (btrfs_header_nritems(right) == 0) { 806 if (btrfs_header_nritems(right) == 0) {
@@ -941,7 +941,7 @@ static int noinline push_nodes_for_insert(struct btrfs_trans_handle *trans,
941 wret = 1; 941 wret = 1;
942 else { 942 else {
943 wret = push_node_left(trans, root, 943 wret = push_node_left(trans, root,
944 left, mid); 944 left, mid, 0);
945 } 945 }
946 } 946 }
947 if (wret < 0) 947 if (wret < 0)
@@ -1239,7 +1239,7 @@ static int fixup_low_keys(struct btrfs_trans_handle *trans,
1239 */ 1239 */
1240static int push_node_left(struct btrfs_trans_handle *trans, 1240static int push_node_left(struct btrfs_trans_handle *trans,
1241 struct btrfs_root *root, struct extent_buffer *dst, 1241 struct btrfs_root *root, struct extent_buffer *dst,
1242 struct extent_buffer *src) 1242 struct extent_buffer *src, int empty)
1243{ 1243{
1244 int push_items = 0; 1244 int push_items = 0;
1245 int src_nritems; 1245 int src_nritems;
@@ -1252,12 +1252,17 @@ static int push_node_left(struct btrfs_trans_handle *trans,
1252 WARN_ON(btrfs_header_generation(src) != trans->transid); 1252 WARN_ON(btrfs_header_generation(src) != trans->transid);
1253 WARN_ON(btrfs_header_generation(dst) != trans->transid); 1253 WARN_ON(btrfs_header_generation(dst) != trans->transid);
1254 1254
1255 if (!empty && src_nritems <= 2)
1256 return 1;
1257
1255 if (push_items <= 0) { 1258 if (push_items <= 0) {
1256 return 1; 1259 return 1;
1257 } 1260 }
1258 1261
1259 if (src_nritems < push_items) 1262 if (empty)
1260 push_items = src_nritems; 1263 push_items = min(src_nritems, push_items);
1264 else
1265 push_items = min(src_nritems - 2, push_items);
1261 1266
1262 copy_extent_buffer(dst, src, 1267 copy_extent_buffer(dst, src,
1263 btrfs_node_key_ptr_offset(dst_nritems), 1268 btrfs_node_key_ptr_offset(dst_nritems),