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.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index c8f4c540cc2c..42491d728e99 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -62,14 +62,38 @@ noinline void btrfs_set_path_blocking(struct btrfs_path *p)
62 62
63/* 63/*
64 * reset all the locked nodes in the patch to spinning locks. 64 * reset all the locked nodes in the patch to spinning locks.
65 *
66 * held is used to keep lockdep happy, when lockdep is enabled
67 * we set held to a blocking lock before we go around and
68 * retake all the spinlocks in the path. You can safely use NULL
69 * for held
65 */ 70 */
66noinline void btrfs_clear_path_blocking(struct btrfs_path *p) 71noinline void btrfs_clear_path_blocking(struct btrfs_path *p,
72 struct extent_buffer *held)
67{ 73{
68 int i; 74 int i;
69 for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 75
76#ifdef CONFIG_DEBUG_LOCK_ALLOC
77 /* lockdep really cares that we take all of these spinlocks
78 * in the right order. If any of the locks in the path are not
79 * currently blocking, it is going to complain. So, make really
80 * really sure by forcing the path to blocking before we clear
81 * the path blocking.
82 */
83 if (held)
84 btrfs_set_lock_blocking(held);
85 btrfs_set_path_blocking(p);
86#endif
87
88 for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) {
70 if (p->nodes[i] && p->locks[i]) 89 if (p->nodes[i] && p->locks[i])
71 btrfs_clear_lock_blocking(p->nodes[i]); 90 btrfs_clear_lock_blocking(p->nodes[i]);
72 } 91 }
92
93#ifdef CONFIG_DEBUG_LOCK_ALLOC
94 if (held)
95 btrfs_clear_lock_blocking(held);
96#endif
73} 97}
74 98
75/* this also releases the path */ 99/* this also releases the path */
@@ -279,7 +303,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
279 trans->transid, level, &ins); 303 trans->transid, level, &ins);
280 BUG_ON(ret); 304 BUG_ON(ret);
281 cow = btrfs_init_new_buffer(trans, root, prealloc_dest, 305 cow = btrfs_init_new_buffer(trans, root, prealloc_dest,
282 buf->len); 306 buf->len, level);
283 } else { 307 } else {
284 cow = btrfs_alloc_free_block(trans, root, buf->len, 308 cow = btrfs_alloc_free_block(trans, root, buf->len,
285 parent_start, 309 parent_start,
@@ -1559,7 +1583,7 @@ cow_done:
1559 if (!p->skip_locking) 1583 if (!p->skip_locking)
1560 p->locks[level] = 1; 1584 p->locks[level] = 1;
1561 1585
1562 btrfs_clear_path_blocking(p); 1586 btrfs_clear_path_blocking(p, NULL);
1563 1587
1564 /* 1588 /*
1565 * we have a lock on b and as long as we aren't changing 1589 * we have a lock on b and as long as we aren't changing
@@ -1598,7 +1622,7 @@ cow_done:
1598 1622
1599 btrfs_set_path_blocking(p); 1623 btrfs_set_path_blocking(p);
1600 sret = split_node(trans, root, p, level); 1624 sret = split_node(trans, root, p, level);
1601 btrfs_clear_path_blocking(p); 1625 btrfs_clear_path_blocking(p, NULL);
1602 1626
1603 BUG_ON(sret > 0); 1627 BUG_ON(sret > 0);
1604 if (sret) { 1628 if (sret) {
@@ -1618,7 +1642,7 @@ cow_done:
1618 1642
1619 btrfs_set_path_blocking(p); 1643 btrfs_set_path_blocking(p);
1620 sret = balance_level(trans, root, p, level); 1644 sret = balance_level(trans, root, p, level);
1621 btrfs_clear_path_blocking(p); 1645 btrfs_clear_path_blocking(p, NULL);
1622 1646
1623 if (sret) { 1647 if (sret) {
1624 ret = sret; 1648 ret = sret;
@@ -1681,13 +1705,13 @@ cow_done:
1681 if (!p->skip_locking) { 1705 if (!p->skip_locking) {
1682 int lret; 1706 int lret;
1683 1707
1684 btrfs_clear_path_blocking(p); 1708 btrfs_clear_path_blocking(p, NULL);
1685 lret = btrfs_try_spin_lock(b); 1709 lret = btrfs_try_spin_lock(b);
1686 1710
1687 if (!lret) { 1711 if (!lret) {
1688 btrfs_set_path_blocking(p); 1712 btrfs_set_path_blocking(p);
1689 btrfs_tree_lock(b); 1713 btrfs_tree_lock(b);
1690 btrfs_clear_path_blocking(p); 1714 btrfs_clear_path_blocking(p, b);
1691 } 1715 }
1692 } 1716 }
1693 } else { 1717 } else {
@@ -1699,7 +1723,7 @@ cow_done:
1699 btrfs_set_path_blocking(p); 1723 btrfs_set_path_blocking(p);
1700 sret = split_leaf(trans, root, key, 1724 sret = split_leaf(trans, root, key,
1701 p, ins_len, ret == 0); 1725 p, ins_len, ret == 0);
1702 btrfs_clear_path_blocking(p); 1726 btrfs_clear_path_blocking(p, NULL);
1703 1727
1704 BUG_ON(sret > 0); 1728 BUG_ON(sret > 0);
1705 if (sret) { 1729 if (sret) {
@@ -3919,7 +3943,6 @@ find_next_key:
3919 btrfs_release_path(root, path); 3943 btrfs_release_path(root, path);
3920 goto again; 3944 goto again;
3921 } else { 3945 } else {
3922 btrfs_clear_path_blocking(path);
3923 goto out; 3946 goto out;
3924 } 3947 }
3925 } 3948 }
@@ -3939,7 +3962,7 @@ find_next_key:
3939 path->locks[level - 1] = 1; 3962 path->locks[level - 1] = 1;
3940 path->nodes[level - 1] = cur; 3963 path->nodes[level - 1] = cur;
3941 unlock_up(path, level, 1); 3964 unlock_up(path, level, 1);
3942 btrfs_clear_path_blocking(path); 3965 btrfs_clear_path_blocking(path, NULL);
3943 } 3966 }
3944out: 3967out:
3945 if (ret == 0) 3968 if (ret == 0)