diff options
-rw-r--r-- | fs/btrfs/ctree.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b98f8604f4f6..8206b3900587 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -5119,6 +5119,18 @@ again: | |||
5119 | 5119 | ||
5120 | if (!path->skip_locking) { | 5120 | if (!path->skip_locking) { |
5121 | ret = btrfs_try_tree_read_lock(next); | 5121 | ret = btrfs_try_tree_read_lock(next); |
5122 | if (!ret && time_seq) { | ||
5123 | /* | ||
5124 | * If we don't get the lock, we may be racing | ||
5125 | * with push_leaf_left, holding that lock while | ||
5126 | * itself waiting for the leaf we've currently | ||
5127 | * locked. To solve this situation, we give up | ||
5128 | * on our lock and cycle. | ||
5129 | */ | ||
5130 | btrfs_release_path(path); | ||
5131 | cond_resched(); | ||
5132 | goto again; | ||
5133 | } | ||
5122 | if (!ret) { | 5134 | if (!ret) { |
5123 | btrfs_set_path_blocking(path); | 5135 | btrfs_set_path_blocking(path); |
5124 | btrfs_tree_read_lock(next); | 5136 | btrfs_tree_read_lock(next); |