aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-02-04 09:25:08 -0500
committerChris Mason <chris.mason@oracle.com>2009-02-04 09:25:08 -0500
commitb4ce94de9b4d64e8ab3cf155d13653c666e22b9b (patch)
treeebc44a9554a50b495b091cb0979d79fd29e50fe7 /fs/btrfs/ctree.c
parentc487685d7c18a8481900755aa5c56a7a74193101 (diff)
Btrfs: Change btree locking to use explicit blocking points
Most of the btrfs metadata operations can be protected by a spinlock, but some operations still need to schedule. So far, btrfs has been using a mutex along with a trylock loop, most of the time it is able to avoid going for the full mutex, so the trylock loop is a big performance gain. This commit is step one for getting rid of the blocking locks entirely. btrfs_tree_lock takes a spinlock, and the code explicitly switches to a blocking lock when it starts an operation that can schedule. We'll be able get rid of the blocking locks in smaller pieces over time. Tracing allows us to find the most common cause of blocking, so we can start with the hot spots first. The basic idea is: btrfs_tree_lock() returns with the spin lock held btrfs_set_lock_blocking() sets the EXTENT_BUFFER_BLOCKING bit in the extent buffer flags, and then drops the spin lock. The buffer is still considered locked by all of the btrfs code. If btrfs_tree_lock gets the spinlock but finds the blocking bit set, it drops the spin lock and waits on a wait queue for the blocking bit to go away. Much of the code that needs to set the blocking bit finishes without actually blocking a good percentage of the time. So, an adaptive spin is still used against the blocking bit to avoid very high context switch rates. btrfs_clear_lock_blocking() clears the blocking bit and returns with the spinlock held again. btrfs_tree_unlock() can be called on either blocking or spinning locks, it does the right thing based on the blocking bit. ctree.c has a helper function to set/clear all the locked buffers in a path as blocking. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c234
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 */
61noinline 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 */
73noinline 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 */
58void btrfs_free_path(struct btrfs_path *p) 83void 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 */
1316static 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 */
1433noinline 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;
1535done: 1721done:
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 }
3340out: 3544out:
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 }
3732out: 3942out:
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 }
3892done: 4109done:
@@ -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;