aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index b0e18d986e0a..2e667868e0d2 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -43,8 +43,6 @@ struct btrfs_path *btrfs_alloc_path(void)
43{ 43{
44 struct btrfs_path *path; 44 struct btrfs_path *path;
45 path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); 45 path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS);
46 if (path)
47 path->reada = 1;
48 return path; 46 return path;
49} 47}
50 48
@@ -1224,11 +1222,13 @@ static void reada_for_search(struct btrfs_root *root,
1224 u64 search; 1222 u64 search;
1225 u64 target; 1223 u64 target;
1226 u64 nread = 0; 1224 u64 nread = 0;
1225 u64 gen;
1227 int direction = path->reada; 1226 int direction = path->reada;
1228 struct extent_buffer *eb; 1227 struct extent_buffer *eb;
1229 u32 nr; 1228 u32 nr;
1230 u32 blocksize; 1229 u32 blocksize;
1231 u32 nscan = 0; 1230 u32 nscan = 0;
1231 bool map = true;
1232 1232
1233 if (level != 1) 1233 if (level != 1)
1234 return; 1234 return;
@@ -1250,7 +1250,19 @@ static void reada_for_search(struct btrfs_root *root,
1250 1250
1251 nritems = btrfs_header_nritems(node); 1251 nritems = btrfs_header_nritems(node);
1252 nr = slot; 1252 nr = slot;
1253 if (node->map_token || path->skip_locking)
1254 map = false;
1255
1253 while (1) { 1256 while (1) {
1257 if (map && !node->map_token) {
1258 unsigned long offset = btrfs_node_key_ptr_offset(nr);
1259 map_private_extent_buffer(node, offset,
1260 sizeof(struct btrfs_key_ptr),
1261 &node->map_token,
1262 &node->kaddr,
1263 &node->map_start,
1264 &node->map_len, KM_USER1);
1265 }
1254 if (direction < 0) { 1266 if (direction < 0) {
1255 if (nr == 0) 1267 if (nr == 0)
1256 break; 1268 break;
@@ -1268,14 +1280,23 @@ static void reada_for_search(struct btrfs_root *root,
1268 search = btrfs_node_blockptr(node, nr); 1280 search = btrfs_node_blockptr(node, nr);
1269 if ((search <= target && target - search <= 65536) || 1281 if ((search <= target && target - search <= 65536) ||
1270 (search > target && search - target <= 65536)) { 1282 (search > target && search - target <= 65536)) {
1271 readahead_tree_block(root, search, blocksize, 1283 gen = btrfs_node_ptr_generation(node, nr);
1272 btrfs_node_ptr_generation(node, nr)); 1284 if (map && node->map_token) {
1285 unmap_extent_buffer(node, node->map_token,
1286 KM_USER1);
1287 node->map_token = NULL;
1288 }
1289 readahead_tree_block(root, search, blocksize, gen);
1273 nread += blocksize; 1290 nread += blocksize;
1274 } 1291 }
1275 nscan++; 1292 nscan++;
1276 if ((nread > 65536 || nscan > 32)) 1293 if ((nread > 65536 || nscan > 32))
1277 break; 1294 break;
1278 } 1295 }
1296 if (map && node->map_token) {
1297 unmap_extent_buffer(node, node->map_token, KM_USER1);
1298 node->map_token = NULL;
1299 }
1279} 1300}
1280 1301
1281/* 1302/*
@@ -1648,9 +1669,6 @@ again:
1648 } 1669 }
1649cow_done: 1670cow_done:
1650 BUG_ON(!cow && ins_len); 1671 BUG_ON(!cow && ins_len);
1651 if (level != btrfs_header_level(b))
1652 WARN_ON(1);
1653 level = btrfs_header_level(b);
1654 1672
1655 p->nodes[level] = b; 1673 p->nodes[level] = b;
1656 if (!p->skip_locking) 1674 if (!p->skip_locking)