Commit cb25c2ea authored by Josef Bacik's avatar Josef Bacik

Btrfs: map the node block when looking for readahead targets

If we have particularly full nodes, we could call btrfs_node_blockptr up to 32
times, which is 32 pairs of kmap/kunmap, which _sucks_.  So go ahead and map the
extent buffer while we look for readahead targets.  Thanks,
Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
parent af60bed2
......@@ -1229,6 +1229,7 @@ static void reada_for_search(struct btrfs_root *root,
u64 search;
u64 target;
u64 nread = 0;
u64 gen;
int direction = path->reada;
struct extent_buffer *eb;
u32 nr;
......@@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root,
nritems = btrfs_header_nritems(node);
nr = slot;
while (1) {
if (!node->map_token) {
unsigned long offset = btrfs_node_key_ptr_offset(nr);
map_private_extent_buffer(node, offset,
sizeof(struct btrfs_key_ptr),
&node->map_token,
&node->kaddr,
&node->map_start,
&node->map_len, KM_USER1);
}
if (direction < 0) {
if (nr == 0)
break;
......@@ -1273,14 +1283,23 @@ static void reada_for_search(struct btrfs_root *root,
search = btrfs_node_blockptr(node, nr);
if ((search <= target && target - search <= 65536) ||
(search > target && search - target <= 65536)) {
readahead_tree_block(root, search, blocksize,
btrfs_node_ptr_generation(node, nr));
gen = btrfs_node_ptr_generation(node, nr);
if (node->map_token) {
unmap_extent_buffer(node, node->map_token,
KM_USER1);
node->map_token = NULL;
}
readahead_tree_block(root, search, blocksize, gen);
nread += blocksize;
}
nscan++;
if ((nread > 65536 || nscan > 32))
break;
}
if (node->map_token) {
unmap_extent_buffer(node, node->map_token, KM_USER1);
node->map_token = NULL;
}
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment