Btrfs: optimize leaf_space_used
authorJosef Bacik <jbacik@fusionio.com>
Mon, 15 Oct 2012 17:43:18 +0000 (13:43 -0400)
committerChris Mason <chris.mason@fusionio.com>
Mon, 17 Dec 2012 01:46:26 +0000 (20:46 -0500)
This gets called at least 4 times for every level while adding an object,
and it involves 3 kmapping calls, which on my box take about 5us a piece.
So instead use a token, which brings us down to 1 kmap call and makes this
function take 1/3 of the time per call.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/ctree.c

index e8b32641ea90dbfeb51c98ffb1a84e06d65c90d5..e7bea1d5f75fd7aab850b789ab0052717185e82a 100644 (file)
@@ -3298,14 +3298,21 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
  */
 static int leaf_space_used(struct extent_buffer *l, int start, int nr)
 {
+       struct btrfs_item *start_item;
+       struct btrfs_item *end_item;
+       struct btrfs_map_token token;
        int data_len;
        int nritems = btrfs_header_nritems(l);
        int end = min(nritems, start + nr) - 1;
 
        if (!nr)
                return 0;
-       data_len = btrfs_item_end_nr(l, start);
-       data_len = data_len - btrfs_item_offset_nr(l, end);
+       btrfs_init_map_token(&token);
+       start_item = btrfs_item_nr(l, start);
+       end_item = btrfs_item_nr(l, end);
+       data_len = btrfs_token_item_offset(l, start_item, &token) +
+               btrfs_token_item_size(l, start_item, &token);
+       data_len = data_len - btrfs_token_item_offset(l, end_item, &token);
        data_len += sizeof(struct btrfs_item) * nr;
        WARN_ON(data_len < 0);
        return data_len;