diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 234 |
1 files changed, 226 insertions, 8 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 3b6e35aafc9e..3af777357acb 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -54,6 +54,31 @@ struct btrfs_path *btrfs_alloc_path(void) | |||
54 | return path; | 54 | return path; |
55 | } | 55 | } |
56 | 56 | ||
57 | /* | ||
58 | * set all locked nodes in the path to blocking locks. This should | ||
59 | * be done before scheduling | ||
60 | */ | ||
61 | noinline void btrfs_set_path_blocking(struct btrfs_path *p) | ||
62 | { | ||
63 | int i; | ||
64 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
65 | if (p->nodes[i] && p->locks[i]) | ||
66 | btrfs_set_lock_blocking(p->nodes[i]); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * reset all the locked nodes in the patch to spinning locks. | ||
72 | */ | ||
73 | noinline void btrfs_clear_path_blocking(struct btrfs_path *p) | ||
74 | { | ||
75 | int i; | ||
76 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | ||
77 | if (p->nodes[i] && p->locks[i]) | ||
78 | btrfs_clear_lock_blocking(p->nodes[i]); | ||
79 | } | ||
80 | } | ||
81 | |||
57 | /* this also releases the path */ | 82 | /* this also releases the path */ |
58 | void btrfs_free_path(struct btrfs_path *p) | 83 | void btrfs_free_path(struct btrfs_path *p) |
59 | { | 84 | { |
@@ -272,6 +297,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
272 | if (IS_ERR(cow)) | 297 | if (IS_ERR(cow)) |
273 | return PTR_ERR(cow); | 298 | return PTR_ERR(cow); |
274 | 299 | ||
300 | /* cow is set to blocking by btrfs_init_new_buffer */ | ||
301 | |||
275 | copy_extent_buffer(cow, buf, 0, 0, cow->len); | 302 | copy_extent_buffer(cow, buf, 0, 0, cow->len); |
276 | btrfs_set_header_bytenr(cow, cow->start); | 303 | btrfs_set_header_bytenr(cow, cow->start); |
277 | btrfs_set_header_generation(cow, trans->transid); | 304 | btrfs_set_header_generation(cow, trans->transid); |
@@ -397,6 +424,11 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
397 | } | 424 | } |
398 | 425 | ||
399 | search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); | 426 | search_start = buf->start & ~((u64)(1024 * 1024 * 1024) - 1); |
427 | |||
428 | if (parent) | ||
429 | btrfs_set_lock_blocking(parent); | ||
430 | btrfs_set_lock_blocking(buf); | ||
431 | |||
400 | ret = __btrfs_cow_block(trans, root, buf, parent, | 432 | ret = __btrfs_cow_block(trans, root, buf, parent, |
401 | parent_slot, cow_ret, search_start, 0, | 433 | parent_slot, cow_ret, search_start, 0, |
402 | prealloc_dest); | 434 | prealloc_dest); |
@@ -502,6 +534,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
502 | if (parent_nritems == 1) | 534 | if (parent_nritems == 1) |
503 | return 0; | 535 | return 0; |
504 | 536 | ||
537 | btrfs_set_lock_blocking(parent); | ||
538 | |||
505 | for (i = start_slot; i < end_slot; i++) { | 539 | for (i = start_slot; i < end_slot; i++) { |
506 | int close = 1; | 540 | int close = 1; |
507 | 541 | ||
@@ -562,6 +596,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
562 | search_start = last_block; | 596 | search_start = last_block; |
563 | 597 | ||
564 | btrfs_tree_lock(cur); | 598 | btrfs_tree_lock(cur); |
599 | btrfs_set_lock_blocking(cur); | ||
565 | err = __btrfs_cow_block(trans, root, cur, parent, i, | 600 | err = __btrfs_cow_block(trans, root, cur, parent, i, |
566 | &cur, search_start, | 601 | &cur, search_start, |
567 | min(16 * blocksize, | 602 | min(16 * blocksize, |
@@ -860,6 +895,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
860 | return 0; | 895 | return 0; |
861 | 896 | ||
862 | mid = path->nodes[level]; | 897 | mid = path->nodes[level]; |
898 | |||
863 | WARN_ON(!path->locks[level]); | 899 | WARN_ON(!path->locks[level]); |
864 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | 900 | WARN_ON(btrfs_header_generation(mid) != trans->transid); |
865 | 901 | ||
@@ -882,6 +918,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
882 | /* promote the child to a root */ | 918 | /* promote the child to a root */ |
883 | child = read_node_slot(root, mid, 0); | 919 | child = read_node_slot(root, mid, 0); |
884 | btrfs_tree_lock(child); | 920 | btrfs_tree_lock(child); |
921 | btrfs_set_lock_blocking(child); | ||
885 | BUG_ON(!child); | 922 | BUG_ON(!child); |
886 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); | 923 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); |
887 | BUG_ON(ret); | 924 | BUG_ON(ret); |
@@ -898,6 +935,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
898 | 935 | ||
899 | add_root_to_dirty_list(root); | 936 | add_root_to_dirty_list(root); |
900 | btrfs_tree_unlock(child); | 937 | btrfs_tree_unlock(child); |
938 | |||
901 | path->locks[level] = 0; | 939 | path->locks[level] = 0; |
902 | path->nodes[level] = NULL; | 940 | path->nodes[level] = NULL; |
903 | clean_tree_block(trans, root, mid); | 941 | clean_tree_block(trans, root, mid); |
@@ -922,6 +960,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
922 | left = read_node_slot(root, parent, pslot - 1); | 960 | left = read_node_slot(root, parent, pslot - 1); |
923 | if (left) { | 961 | if (left) { |
924 | btrfs_tree_lock(left); | 962 | btrfs_tree_lock(left); |
963 | btrfs_set_lock_blocking(left); | ||
925 | wret = btrfs_cow_block(trans, root, left, | 964 | wret = btrfs_cow_block(trans, root, left, |
926 | parent, pslot - 1, &left, 0); | 965 | parent, pslot - 1, &left, 0); |
927 | if (wret) { | 966 | if (wret) { |
@@ -932,6 +971,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
932 | right = read_node_slot(root, parent, pslot + 1); | 971 | right = read_node_slot(root, parent, pslot + 1); |
933 | if (right) { | 972 | if (right) { |
934 | btrfs_tree_lock(right); | 973 | btrfs_tree_lock(right); |
974 | btrfs_set_lock_blocking(right); | ||
935 | wret = btrfs_cow_block(trans, root, right, | 975 | wret = btrfs_cow_block(trans, root, right, |
936 | parent, pslot + 1, &right, 0); | 976 | parent, pslot + 1, &right, 0); |
937 | if (wret) { | 977 | if (wret) { |
@@ -1107,6 +1147,8 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
1107 | u32 left_nr; | 1147 | u32 left_nr; |
1108 | 1148 | ||
1109 | btrfs_tree_lock(left); | 1149 | btrfs_tree_lock(left); |
1150 | btrfs_set_lock_blocking(left); | ||
1151 | |||
1110 | left_nr = btrfs_header_nritems(left); | 1152 | left_nr = btrfs_header_nritems(left); |
1111 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1153 | if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
1112 | wret = 1; | 1154 | wret = 1; |
@@ -1153,7 +1195,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
1153 | */ | 1195 | */ |
1154 | if (right) { | 1196 | if (right) { |
1155 | u32 right_nr; | 1197 | u32 right_nr; |
1198 | |||
1156 | btrfs_tree_lock(right); | 1199 | btrfs_tree_lock(right); |
1200 | btrfs_set_lock_blocking(right); | ||
1201 | |||
1157 | right_nr = btrfs_header_nritems(right); | 1202 | right_nr = btrfs_header_nritems(right); |
1158 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { | 1203 | if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(root) - 1) { |
1159 | wret = 1; | 1204 | wret = 1; |
@@ -1265,6 +1310,68 @@ static noinline void reada_for_search(struct btrfs_root *root, | |||
1265 | } | 1310 | } |
1266 | 1311 | ||
1267 | /* | 1312 | /* |
1313 | * returns -EAGAIN if it had to drop the path, or zero if everything was in | ||
1314 | * cache | ||
1315 | */ | ||
1316 | static noinline int reada_for_balance(struct btrfs_root *root, | ||
1317 | struct btrfs_path *path, int level) | ||
1318 | { | ||
1319 | int slot; | ||
1320 | int nritems; | ||
1321 | struct extent_buffer *parent; | ||
1322 | struct extent_buffer *eb; | ||
1323 | u64 gen; | ||
1324 | u64 block1 = 0; | ||
1325 | u64 block2 = 0; | ||
1326 | int ret = 0; | ||
1327 | int blocksize; | ||
1328 | |||
1329 | parent = path->nodes[level - 1]; | ||
1330 | if (!parent) | ||
1331 | return 0; | ||
1332 | |||
1333 | nritems = btrfs_header_nritems(parent); | ||
1334 | slot = path->slots[level]; | ||
1335 | blocksize = btrfs_level_size(root, level); | ||
1336 | |||
1337 | if (slot > 0) { | ||
1338 | block1 = btrfs_node_blockptr(parent, slot - 1); | ||
1339 | gen = btrfs_node_ptr_generation(parent, slot - 1); | ||
1340 | eb = btrfs_find_tree_block(root, block1, blocksize); | ||
1341 | if (eb && btrfs_buffer_uptodate(eb, gen)) | ||
1342 | block1 = 0; | ||
1343 | free_extent_buffer(eb); | ||
1344 | } | ||
1345 | if (slot < nritems) { | ||
1346 | block2 = btrfs_node_blockptr(parent, slot + 1); | ||
1347 | gen = btrfs_node_ptr_generation(parent, slot + 1); | ||
1348 | eb = btrfs_find_tree_block(root, block2, blocksize); | ||
1349 | if (eb && btrfs_buffer_uptodate(eb, gen)) | ||
1350 | block2 = 0; | ||
1351 | free_extent_buffer(eb); | ||
1352 | } | ||
1353 | if (block1 || block2) { | ||
1354 | ret = -EAGAIN; | ||
1355 | btrfs_release_path(root, path); | ||
1356 | if (block1) | ||
1357 | readahead_tree_block(root, block1, blocksize, 0); | ||
1358 | if (block2) | ||
1359 | readahead_tree_block(root, block2, blocksize, 0); | ||
1360 | |||
1361 | if (block1) { | ||
1362 | eb = read_tree_block(root, block1, blocksize, 0); | ||
1363 | free_extent_buffer(eb); | ||
1364 | } | ||
1365 | if (block1) { | ||
1366 | eb = read_tree_block(root, block2, blocksize, 0); | ||
1367 | free_extent_buffer(eb); | ||
1368 | } | ||
1369 | } | ||
1370 | return ret; | ||
1371 | } | ||
1372 | |||
1373 | |||
1374 | /* | ||
1268 | * when we walk down the tree, it is usually safe to unlock the higher layers | 1375 | * when we walk down the tree, it is usually safe to unlock the higher layers |
1269 | * in the tree. The exceptions are when our path goes through slot 0, because | 1376 | * in the tree. The exceptions are when our path goes through slot 0, because |
1270 | * operations on the tree might require changing key pointers higher up in the | 1377 | * operations on the tree might require changing key pointers higher up in the |
@@ -1315,6 +1422,32 @@ static noinline void unlock_up(struct btrfs_path *path, int level, | |||
1315 | } | 1422 | } |
1316 | 1423 | ||
1317 | /* | 1424 | /* |
1425 | * This releases any locks held in the path starting at level and | ||
1426 | * going all the way up to the root. | ||
1427 | * | ||
1428 | * btrfs_search_slot will keep the lock held on higher nodes in a few | ||
1429 | * corner cases, such as COW of the block at slot zero in the node. This | ||
1430 | * ignores those rules, and it should only be called when there are no | ||
1431 | * more updates to be done higher up in the tree. | ||
1432 | */ | ||
1433 | noinline void btrfs_unlock_up_safe(struct btrfs_path *path, int level) | ||
1434 | { | ||
1435 | int i; | ||
1436 | |||
1437 | if (path->keep_locks || path->lowest_level) | ||
1438 | return; | ||
1439 | |||
1440 | for (i = level; i < BTRFS_MAX_LEVEL; i++) { | ||
1441 | if (!path->nodes[i]) | ||
1442 | break; | ||
1443 | if (!path->locks[i]) | ||
1444 | break; | ||
1445 | btrfs_tree_unlock(path->nodes[i]); | ||
1446 | path->locks[i] = 0; | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | /* | ||
1318 | * look for key in the tree. path is filled in with nodes along the way | 1451 | * look for key in the tree. path is filled in with nodes along the way |
1319 | * if key is found, we return zero and you can find the item in the leaf | 1452 | * if key is found, we return zero and you can find the item in the leaf |
1320 | * level of the path (level 0) | 1453 | * level of the path (level 0) |
@@ -1385,6 +1518,7 @@ again: | |||
1385 | */ | 1518 | */ |
1386 | if (prealloc_block.objectid && | 1519 | if (prealloc_block.objectid && |
1387 | prealloc_block.offset != b->len) { | 1520 | prealloc_block.offset != b->len) { |
1521 | btrfs_set_path_blocking(p); | ||
1388 | btrfs_free_reserved_extent(root, | 1522 | btrfs_free_reserved_extent(root, |
1389 | prealloc_block.objectid, | 1523 | prealloc_block.objectid, |
1390 | prealloc_block.offset); | 1524 | prealloc_block.offset); |
@@ -1409,6 +1543,8 @@ again: | |||
1409 | goto again; | 1543 | goto again; |
1410 | } | 1544 | } |
1411 | 1545 | ||
1546 | btrfs_set_path_blocking(p); | ||
1547 | |||
1412 | wret = btrfs_cow_block(trans, root, b, | 1548 | wret = btrfs_cow_block(trans, root, b, |
1413 | p->nodes[level + 1], | 1549 | p->nodes[level + 1], |
1414 | p->slots[level + 1], | 1550 | p->slots[level + 1], |
@@ -1430,6 +1566,22 @@ cow_done: | |||
1430 | if (!p->skip_locking) | 1566 | if (!p->skip_locking) |
1431 | p->locks[level] = 1; | 1567 | p->locks[level] = 1; |
1432 | 1568 | ||
1569 | btrfs_clear_path_blocking(p); | ||
1570 | |||
1571 | /* | ||
1572 | * we have a lock on b and as long as we aren't changing | ||
1573 | * the tree, there is no way to for the items in b to change. | ||
1574 | * It is safe to drop the lock on our parent before we | ||
1575 | * go through the expensive btree search on b. | ||
1576 | * | ||
1577 | * If cow is true, then we might be changing slot zero, | ||
1578 | * which may require changing the parent. So, we can't | ||
1579 | * drop the lock until after we know which slot we're | ||
1580 | * operating on. | ||
1581 | */ | ||
1582 | if (!cow) | ||
1583 | btrfs_unlock_up_safe(p, level + 1); | ||
1584 | |||
1433 | ret = check_block(root, p, level); | 1585 | ret = check_block(root, p, level); |
1434 | if (ret) { | 1586 | if (ret) { |
1435 | ret = -1; | 1587 | ret = -1; |
@@ -1437,6 +1589,7 @@ cow_done: | |||
1437 | } | 1589 | } |
1438 | 1590 | ||
1439 | ret = bin_search(b, key, level, &slot); | 1591 | ret = bin_search(b, key, level, &slot); |
1592 | |||
1440 | if (level != 0) { | 1593 | if (level != 0) { |
1441 | if (ret && slot > 0) | 1594 | if (ret && slot > 0) |
1442 | slot -= 1; | 1595 | slot -= 1; |
@@ -1444,7 +1597,16 @@ cow_done: | |||
1444 | if ((p->search_for_split || ins_len > 0) && | 1597 | if ((p->search_for_split || ins_len > 0) && |
1445 | btrfs_header_nritems(b) >= | 1598 | btrfs_header_nritems(b) >= |
1446 | BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { | 1599 | BTRFS_NODEPTRS_PER_BLOCK(root) - 3) { |
1447 | int sret = split_node(trans, root, p, level); | 1600 | int sret; |
1601 | |||
1602 | sret = reada_for_balance(root, p, level); | ||
1603 | if (sret) | ||
1604 | goto again; | ||
1605 | |||
1606 | btrfs_set_path_blocking(p); | ||
1607 | sret = split_node(trans, root, p, level); | ||
1608 | btrfs_clear_path_blocking(p); | ||
1609 | |||
1448 | BUG_ON(sret > 0); | 1610 | BUG_ON(sret > 0); |
1449 | if (sret) { | 1611 | if (sret) { |
1450 | ret = sret; | 1612 | ret = sret; |
@@ -1453,8 +1615,16 @@ cow_done: | |||
1453 | b = p->nodes[level]; | 1615 | b = p->nodes[level]; |
1454 | slot = p->slots[level]; | 1616 | slot = p->slots[level]; |
1455 | } else if (ins_len < 0) { | 1617 | } else if (ins_len < 0) { |
1456 | int sret = balance_level(trans, root, p, | 1618 | int sret; |
1457 | level); | 1619 | |
1620 | sret = reada_for_balance(root, p, level); | ||
1621 | if (sret) | ||
1622 | goto again; | ||
1623 | |||
1624 | btrfs_set_path_blocking(p); | ||
1625 | sret = balance_level(trans, root, p, level); | ||
1626 | btrfs_clear_path_blocking(p); | ||
1627 | |||
1458 | if (sret) { | 1628 | if (sret) { |
1459 | ret = sret; | 1629 | ret = sret; |
1460 | goto done; | 1630 | goto done; |
@@ -1488,7 +1658,7 @@ cow_done: | |||
1488 | * of the btree by dropping locks before | 1658 | * of the btree by dropping locks before |
1489 | * we read. | 1659 | * we read. |
1490 | */ | 1660 | */ |
1491 | if (level > 1) { | 1661 | if (level > 0) { |
1492 | btrfs_release_path(NULL, p); | 1662 | btrfs_release_path(NULL, p); |
1493 | if (tmp) | 1663 | if (tmp) |
1494 | free_extent_buffer(tmp); | 1664 | free_extent_buffer(tmp); |
@@ -1503,6 +1673,7 @@ cow_done: | |||
1503 | free_extent_buffer(tmp); | 1673 | free_extent_buffer(tmp); |
1504 | goto again; | 1674 | goto again; |
1505 | } else { | 1675 | } else { |
1676 | btrfs_set_path_blocking(p); | ||
1506 | if (tmp) | 1677 | if (tmp) |
1507 | free_extent_buffer(tmp); | 1678 | free_extent_buffer(tmp); |
1508 | if (should_reada) | 1679 | if (should_reada) |
@@ -1512,14 +1683,29 @@ cow_done: | |||
1512 | b = read_node_slot(root, b, slot); | 1683 | b = read_node_slot(root, b, slot); |
1513 | } | 1684 | } |
1514 | } | 1685 | } |
1515 | if (!p->skip_locking) | 1686 | if (!p->skip_locking) { |
1516 | btrfs_tree_lock(b); | 1687 | int lret; |
1688 | |||
1689 | btrfs_clear_path_blocking(p); | ||
1690 | lret = btrfs_try_spin_lock(b); | ||
1691 | |||
1692 | if (!lret) { | ||
1693 | btrfs_set_path_blocking(p); | ||
1694 | btrfs_tree_lock(b); | ||
1695 | btrfs_clear_path_blocking(p); | ||
1696 | } | ||
1697 | } | ||
1517 | } else { | 1698 | } else { |
1518 | p->slots[level] = slot; | 1699 | p->slots[level] = slot; |
1519 | if (ins_len > 0 && | 1700 | if (ins_len > 0 && |
1520 | btrfs_leaf_free_space(root, b) < ins_len) { | 1701 | btrfs_leaf_free_space(root, b) < ins_len) { |
1521 | int sret = split_leaf(trans, root, key, | 1702 | int sret; |
1703 | |||
1704 | btrfs_set_path_blocking(p); | ||
1705 | sret = split_leaf(trans, root, key, | ||
1522 | p, ins_len, ret == 0); | 1706 | p, ins_len, ret == 0); |
1707 | btrfs_clear_path_blocking(p); | ||
1708 | |||
1523 | BUG_ON(sret > 0); | 1709 | BUG_ON(sret > 0); |
1524 | if (sret) { | 1710 | if (sret) { |
1525 | ret = sret; | 1711 | ret = sret; |
@@ -1533,12 +1719,16 @@ cow_done: | |||
1533 | } | 1719 | } |
1534 | ret = 1; | 1720 | ret = 1; |
1535 | done: | 1721 | done: |
1722 | /* | ||
1723 | * we don't really know what they plan on doing with the path | ||
1724 | * from here on, so for now just mark it as blocking | ||
1725 | */ | ||
1726 | btrfs_set_path_blocking(p); | ||
1536 | if (prealloc_block.objectid) { | 1727 | if (prealloc_block.objectid) { |
1537 | btrfs_free_reserved_extent(root, | 1728 | btrfs_free_reserved_extent(root, |
1538 | prealloc_block.objectid, | 1729 | prealloc_block.objectid, |
1539 | prealloc_block.offset); | 1730 | prealloc_block.offset); |
1540 | } | 1731 | } |
1541 | |||
1542 | return ret; | 1732 | return ret; |
1543 | } | 1733 | } |
1544 | 1734 | ||
@@ -1562,6 +1752,8 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
1562 | ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); | 1752 | ret = btrfs_cow_block(trans, root, eb, NULL, 0, &eb, 0); |
1563 | BUG_ON(ret); | 1753 | BUG_ON(ret); |
1564 | 1754 | ||
1755 | btrfs_set_lock_blocking(eb); | ||
1756 | |||
1565 | parent = eb; | 1757 | parent = eb; |
1566 | while (1) { | 1758 | while (1) { |
1567 | level = btrfs_header_level(parent); | 1759 | level = btrfs_header_level(parent); |
@@ -1586,6 +1778,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
1586 | eb = read_tree_block(root, bytenr, blocksize, | 1778 | eb = read_tree_block(root, bytenr, blocksize, |
1587 | generation); | 1779 | generation); |
1588 | btrfs_tree_lock(eb); | 1780 | btrfs_tree_lock(eb); |
1781 | btrfs_set_lock_blocking(eb); | ||
1589 | } | 1782 | } |
1590 | 1783 | ||
1591 | /* | 1784 | /* |
@@ -1610,6 +1803,7 @@ int btrfs_merge_path(struct btrfs_trans_handle *trans, | |||
1610 | eb = read_tree_block(root, bytenr, blocksize, | 1803 | eb = read_tree_block(root, bytenr, blocksize, |
1611 | generation); | 1804 | generation); |
1612 | btrfs_tree_lock(eb); | 1805 | btrfs_tree_lock(eb); |
1806 | btrfs_set_lock_blocking(eb); | ||
1613 | } | 1807 | } |
1614 | 1808 | ||
1615 | ret = btrfs_cow_block(trans, root, eb, parent, slot, | 1809 | ret = btrfs_cow_block(trans, root, eb, parent, slot, |
@@ -2156,6 +2350,8 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2156 | 2350 | ||
2157 | right = read_node_slot(root, upper, slot + 1); | 2351 | right = read_node_slot(root, upper, slot + 1); |
2158 | btrfs_tree_lock(right); | 2352 | btrfs_tree_lock(right); |
2353 | btrfs_set_lock_blocking(right); | ||
2354 | |||
2159 | free_space = btrfs_leaf_free_space(root, right); | 2355 | free_space = btrfs_leaf_free_space(root, right); |
2160 | if (free_space < data_size) | 2356 | if (free_space < data_size) |
2161 | goto out_unlock; | 2357 | goto out_unlock; |
@@ -2351,6 +2547,8 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2351 | 2547 | ||
2352 | left = read_node_slot(root, path->nodes[1], slot - 1); | 2548 | left = read_node_slot(root, path->nodes[1], slot - 1); |
2353 | btrfs_tree_lock(left); | 2549 | btrfs_tree_lock(left); |
2550 | btrfs_set_lock_blocking(left); | ||
2551 | |||
2354 | free_space = btrfs_leaf_free_space(root, left); | 2552 | free_space = btrfs_leaf_free_space(root, left); |
2355 | if (free_space < data_size) { | 2553 | if (free_space < data_size) { |
2356 | ret = 1; | 2554 | ret = 1; |
@@ -2809,6 +3007,12 @@ int btrfs_split_item(struct btrfs_trans_handle *trans, | |||
2809 | path->keep_locks = 0; | 3007 | path->keep_locks = 0; |
2810 | BUG_ON(ret); | 3008 | BUG_ON(ret); |
2811 | 3009 | ||
3010 | /* | ||
3011 | * make sure any changes to the path from split_leaf leave it | ||
3012 | * in a blocking state | ||
3013 | */ | ||
3014 | btrfs_set_path_blocking(path); | ||
3015 | |||
2812 | leaf = path->nodes[0]; | 3016 | leaf = path->nodes[0]; |
2813 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); | 3017 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); |
2814 | 3018 | ||
@@ -3338,6 +3542,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, | |||
3338 | BUG(); | 3542 | BUG(); |
3339 | } | 3543 | } |
3340 | out: | 3544 | out: |
3545 | btrfs_unlock_up_safe(path, 1); | ||
3341 | return ret; | 3546 | return ret; |
3342 | } | 3547 | } |
3343 | 3548 | ||
@@ -3705,12 +3910,14 @@ find_next_key: | |||
3705 | */ | 3910 | */ |
3706 | if (slot >= nritems) { | 3911 | if (slot >= nritems) { |
3707 | path->slots[level] = slot; | 3912 | path->slots[level] = slot; |
3913 | btrfs_set_path_blocking(path); | ||
3708 | sret = btrfs_find_next_key(root, path, min_key, level, | 3914 | sret = btrfs_find_next_key(root, path, min_key, level, |
3709 | cache_only, min_trans); | 3915 | cache_only, min_trans); |
3710 | if (sret == 0) { | 3916 | if (sret == 0) { |
3711 | btrfs_release_path(root, path); | 3917 | btrfs_release_path(root, path); |
3712 | goto again; | 3918 | goto again; |
3713 | } else { | 3919 | } else { |
3920 | btrfs_clear_path_blocking(path); | ||
3714 | goto out; | 3921 | goto out; |
3715 | } | 3922 | } |
3716 | } | 3923 | } |
@@ -3722,16 +3929,20 @@ find_next_key: | |||
3722 | unlock_up(path, level, 1); | 3929 | unlock_up(path, level, 1); |
3723 | goto out; | 3930 | goto out; |
3724 | } | 3931 | } |
3932 | btrfs_set_path_blocking(path); | ||
3725 | cur = read_node_slot(root, cur, slot); | 3933 | cur = read_node_slot(root, cur, slot); |
3726 | 3934 | ||
3727 | btrfs_tree_lock(cur); | 3935 | btrfs_tree_lock(cur); |
3936 | |||
3728 | path->locks[level - 1] = 1; | 3937 | path->locks[level - 1] = 1; |
3729 | path->nodes[level - 1] = cur; | 3938 | path->nodes[level - 1] = cur; |
3730 | unlock_up(path, level, 1); | 3939 | unlock_up(path, level, 1); |
3940 | btrfs_clear_path_blocking(path); | ||
3731 | } | 3941 | } |
3732 | out: | 3942 | out: |
3733 | if (ret == 0) | 3943 | if (ret == 0) |
3734 | memcpy(min_key, &found_key, sizeof(found_key)); | 3944 | memcpy(min_key, &found_key, sizeof(found_key)); |
3945 | btrfs_set_path_blocking(path); | ||
3735 | return ret; | 3946 | return ret; |
3736 | } | 3947 | } |
3737 | 3948 | ||
@@ -3827,6 +4038,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
3827 | if (ret < 0) | 4038 | if (ret < 0) |
3828 | return ret; | 4039 | return ret; |
3829 | 4040 | ||
4041 | btrfs_set_path_blocking(path); | ||
3830 | nritems = btrfs_header_nritems(path->nodes[0]); | 4042 | nritems = btrfs_header_nritems(path->nodes[0]); |
3831 | /* | 4043 | /* |
3832 | * by releasing the path above we dropped all our locks. A balance | 4044 | * by releasing the path above we dropped all our locks. A balance |
@@ -3857,6 +4069,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
3857 | free_extent_buffer(next); | 4069 | free_extent_buffer(next); |
3858 | } | 4070 | } |
3859 | 4071 | ||
4072 | /* the path was set to blocking above */ | ||
3860 | if (level == 1 && (path->locks[1] || path->skip_locking) && | 4073 | if (level == 1 && (path->locks[1] || path->skip_locking) && |
3861 | path->reada) | 4074 | path->reada) |
3862 | reada_for_search(root, path, level, slot, 0); | 4075 | reada_for_search(root, path, level, slot, 0); |
@@ -3865,6 +4078,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
3865 | if (!path->skip_locking) { | 4078 | if (!path->skip_locking) { |
3866 | WARN_ON(!btrfs_tree_locked(c)); | 4079 | WARN_ON(!btrfs_tree_locked(c)); |
3867 | btrfs_tree_lock(next); | 4080 | btrfs_tree_lock(next); |
4081 | btrfs_set_lock_blocking(next); | ||
3868 | } | 4082 | } |
3869 | break; | 4083 | break; |
3870 | } | 4084 | } |
@@ -3881,12 +4095,15 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
3881 | path->locks[level] = 1; | 4095 | path->locks[level] = 1; |
3882 | if (!level) | 4096 | if (!level) |
3883 | break; | 4097 | break; |
4098 | |||
4099 | btrfs_set_path_blocking(path); | ||
3884 | if (level == 1 && path->locks[1] && path->reada) | 4100 | if (level == 1 && path->locks[1] && path->reada) |
3885 | reada_for_search(root, path, level, slot, 0); | 4101 | reada_for_search(root, path, level, slot, 0); |
3886 | next = read_node_slot(root, next, 0); | 4102 | next = read_node_slot(root, next, 0); |
3887 | if (!path->skip_locking) { | 4103 | if (!path->skip_locking) { |
3888 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); | 4104 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); |
3889 | btrfs_tree_lock(next); | 4105 | btrfs_tree_lock(next); |
4106 | btrfs_set_lock_blocking(next); | ||
3890 | } | 4107 | } |
3891 | } | 4108 | } |
3892 | done: | 4109 | done: |
@@ -3911,6 +4128,7 @@ int btrfs_previous_item(struct btrfs_root *root, | |||
3911 | 4128 | ||
3912 | while (1) { | 4129 | while (1) { |
3913 | if (path->slots[0] == 0) { | 4130 | if (path->slots[0] == 0) { |
4131 | btrfs_set_path_blocking(path); | ||
3914 | ret = btrfs_prev_leaf(root, path); | 4132 | ret = btrfs_prev_leaf(root, path); |
3915 | if (ret != 0) | 4133 | if (ret != 0) |
3916 | return ret; | 4134 | return ret; |