diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index b98f8604f4f6e8029edf20ca78ab0ce31c30c1ea..8206b3900587efa23570b5b8f7f8071ab6e73156 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -5119,6 +5119,18 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path, if (!path->skip_locking) { ret = btrfs_try_tree_read_lock(next); + if (!ret && time_seq) { + /* + * If we don't get the lock, we may be racing + * with push_leaf_left, holding that lock while + * itself waiting for the leaf we've currently + * locked. To solve this situation, we give up + * on our lock and cycle. + */ + btrfs_release_path(path); + cond_resched(); + goto again; + } if (!ret) { btrfs_set_path_blocking(path); btrfs_tree_read_lock(next);