diff options
author | Josef Bacik <josef@redhat.com> | 2011-05-11 12:17:34 -0400 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2011-05-23 13:03:10 -0400 |
commit | cb25c2ea6a79702ab7895b873c6c43e0d3bc3c72 (patch) | |
tree | 08d112b38a1e017b563035b78861288dbf0d2fd6 | |
parent | af60bed24eb0e3b6d93eaa6bb395a5721e6c09a8 (diff) |
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: Josef Bacik <josef@redhat.com>
-rw-r--r-- | fs/btrfs/ctree.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 84d7ca1fe0ba..009bcf7f1e4b 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1229,6 +1229,7 @@ static void reada_for_search(struct btrfs_root *root, | |||
1229 | u64 search; | 1229 | u64 search; |
1230 | u64 target; | 1230 | u64 target; |
1231 | u64 nread = 0; | 1231 | u64 nread = 0; |
1232 | u64 gen; | ||
1232 | int direction = path->reada; | 1233 | int direction = path->reada; |
1233 | struct extent_buffer *eb; | 1234 | struct extent_buffer *eb; |
1234 | u32 nr; | 1235 | u32 nr; |
@@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root, | |||
1256 | nritems = btrfs_header_nritems(node); | 1257 | nritems = btrfs_header_nritems(node); |
1257 | nr = slot; | 1258 | nr = slot; |
1258 | while (1) { | 1259 | while (1) { |
1260 | if (!node->map_token) { | ||
1261 | unsigned long offset = btrfs_node_key_ptr_offset(nr); | ||
1262 | map_private_extent_buffer(node, offset, | ||
1263 | sizeof(struct btrfs_key_ptr), | ||
1264 | &node->map_token, | ||
1265 | &node->kaddr, | ||
1266 | &node->map_start, | ||
1267 | &node->map_len, KM_USER1); | ||
1268 | } | ||
1259 | if (direction < 0) { | 1269 | if (direction < 0) { |
1260 | if (nr == 0) | 1270 | if (nr == 0) |
1261 | break; | 1271 | break; |
@@ -1273,14 +1283,23 @@ static void reada_for_search(struct btrfs_root *root, | |||
1273 | search = btrfs_node_blockptr(node, nr); | 1283 | search = btrfs_node_blockptr(node, nr); |
1274 | if ((search <= target && target - search <= 65536) || | 1284 | if ((search <= target && target - search <= 65536) || |
1275 | (search > target && search - target <= 65536)) { | 1285 | (search > target && search - target <= 65536)) { |
1276 | readahead_tree_block(root, search, blocksize, | 1286 | gen = btrfs_node_ptr_generation(node, nr); |
1277 | btrfs_node_ptr_generation(node, nr)); | 1287 | if (node->map_token) { |
1288 | unmap_extent_buffer(node, node->map_token, | ||
1289 | KM_USER1); | ||
1290 | node->map_token = NULL; | ||
1291 | } | ||
1292 | readahead_tree_block(root, search, blocksize, gen); | ||
1278 | nread += blocksize; | 1293 | nread += blocksize; |
1279 | } | 1294 | } |
1280 | nscan++; | 1295 | nscan++; |
1281 | if ((nread > 65536 || nscan > 32)) | 1296 | if ((nread > 65536 || nscan > 32)) |
1282 | break; | 1297 | break; |
1283 | } | 1298 | } |
1299 | if (node->map_token) { | ||
1300 | unmap_extent_buffer(node, node->map_token, KM_USER1); | ||
1301 | node->map_token = NULL; | ||
1302 | } | ||
1284 | } | 1303 | } |
1285 | 1304 | ||
1286 | /* | 1305 | /* |