aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2017-02-17 13:43:57 -0500
committerFilipe Manana <fdmanana@suse.com>2017-02-23 19:39:44 -0500
commit263d3995c93c6020576f6c93506412a0b9d1e932 (patch)
tree5357c0d811540028845a3e303a1bf2101b9a22a6
parent76b42abbf7488121c4f9f1ea5941123306e25d99 (diff)
Btrfs: try harder to migrate items to left sibling before splitting a leaf
Before attempting to split a leaf we try to migrate items from the leaf to its right and left siblings. We start by trying to move items into the rigth sibling and, if the new item is meant to be inserted at the end of our leaf, we try to free from our leaf an amount of bytes equal to the number of bytes used by the new item, by setting the variable space_needed to the byte size of that new item. However if we fail to move enough items to the right sibling due to lack of space in that sibling, we then try to move items into the left sibling, and in that case we try to free an amount equal to the size of the new item from our leaf, when we need only to free an amount corresponding to the size of the new item minus the current free space of our leaf. So make sure that before we try to move items to the left sibling we do set the variable space_needed with a value corresponding to the new item's size minus the leaf's current free space. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
-rw-r--r--fs/btrfs/ctree.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 1192bc7d2ee7..1fb60ee77b4a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -4159,6 +4159,9 @@ static noinline int push_for_double_split(struct btrfs_trans_handle *trans,
4159 4159
4160 /* try to push all the items before our slot into the next leaf */ 4160 /* try to push all the items before our slot into the next leaf */
4161 slot = path->slots[0]; 4161 slot = path->slots[0];
4162 space_needed = data_size;
4163 if (slot > 0)
4164 space_needed -= btrfs_leaf_free_space(fs_info, path->nodes[0]);
4162 ret = push_leaf_left(trans, root, path, 1, space_needed, 0, slot); 4165 ret = push_leaf_left(trans, root, path, 1, space_needed, 0, slot);
4163 if (ret < 0) 4166 if (ret < 0)
4164 return ret; 4167 return ret;
@@ -4214,6 +4217,10 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
4214 if (wret < 0) 4217 if (wret < 0)
4215 return wret; 4218 return wret;
4216 if (wret) { 4219 if (wret) {
4220 space_needed = data_size;
4221 if (slot > 0)
4222 space_needed -= btrfs_leaf_free_space(fs_info,
4223 l);
4217 wret = push_leaf_left(trans, root, path, space_needed, 4224 wret = push_leaf_left(trans, root, path, space_needed,
4218 space_needed, 0, (u32)-1); 4225 space_needed, 0, (u32)-1);
4219 if (wret < 0) 4226 if (wret < 0)