diff options
Diffstat (limited to 'fs')
| -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 | /* |
