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, ...@@ -1229,6 +1229,7 @@ static void reada_for_search(struct btrfs_root *root,
u64 search; u64 search;
u64 target; u64 target;
u64 nread = 0; u64 nread = 0;
u64 gen;
int direction = path->reada; int direction = path->reada;
struct extent_buffer *eb; struct extent_buffer *eb;
u32 nr; u32 nr;
...@@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root, ...@@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root,
nritems = btrfs_header_nritems(node); nritems = btrfs_header_nritems(node);
nr = slot; nr = slot;
while (1) { 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 (direction < 0) {
if (nr == 0) if (nr == 0)
break; break;
...@@ -1273,14 +1283,23 @@ static void reada_for_search(struct btrfs_root *root, ...@@ -1273,14 +1283,23 @@ static void reada_for_search(struct btrfs_root *root,
search = btrfs_node_blockptr(node, nr); search = btrfs_node_blockptr(node, nr);
if ((search <= target && target - search <= 65536) || if ((search <= target && target - search <= 65536) ||
(search > target && search - target <= 65536)) { (search > target && search - target <= 65536)) {
readahead_tree_block(root, search, blocksize, gen = btrfs_node_ptr_generation(node, nr);
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; nread += blocksize;
} }
nscan++; nscan++;
if ((nread > 65536 || nscan > 32)) if ((nread > 65536 || nscan > 32))
break; 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