Merge tag 'for-5.11/drivers-2020-12-14' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / fs / btrfs / ctree.c
index 113da62..0781089 100644 (file)
@@ -1278,14 +1278,11 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
        if (!tm)
                return eb;
 
-       btrfs_set_path_blocking(path);
-       btrfs_set_lock_blocking_read(eb);
-
        if (tm->op == MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
                BUG_ON(tm->slot != 0);
                eb_rewin = alloc_dummy_extent_buffer(fs_info, eb->start);
                if (!eb_rewin) {
-                       btrfs_tree_read_unlock_blocking(eb);
+                       btrfs_tree_read_unlock(eb);
                        free_extent_buffer(eb);
                        return NULL;
                }
@@ -1297,13 +1294,13 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
        } else {
                eb_rewin = btrfs_clone_extent_buffer(eb);
                if (!eb_rewin) {
-                       btrfs_tree_read_unlock_blocking(eb);
+                       btrfs_tree_read_unlock(eb);
                        free_extent_buffer(eb);
                        return NULL;
                }
        }
 
-       btrfs_tree_read_unlock_blocking(eb);
+       btrfs_tree_read_unlock(eb);
        free_extent_buffer(eb);
 
        btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb_rewin),
@@ -1356,7 +1353,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
        if (old_root && tm && tm->op != MOD_LOG_KEY_REMOVE_WHILE_FREEING) {
                btrfs_tree_read_unlock(eb_root);
                free_extent_buffer(eb_root);
-               old = read_tree_block(fs_info, logical, 0, level, NULL);
+               old = read_tree_block(fs_info, logical, root->root_key.objectid,
+                                     0, level, NULL);
                if (WARN_ON(IS_ERR(old) || !extent_buffer_uptodate(old))) {
                        if (!IS_ERR(old))
                                free_extent_buffer(old);
@@ -1373,9 +1371,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq)
                free_extent_buffer(eb_root);
                eb = alloc_dummy_extent_buffer(fs_info, logical);
        } else {
-               btrfs_set_lock_blocking_read(eb_root);
                eb = btrfs_clone_extent_buffer(eb_root);
-               btrfs_tree_read_unlock_blocking(eb_root);
+               btrfs_tree_read_unlock(eb_root);
                free_extent_buffer(eb_root);
        }
 
@@ -1483,10 +1480,6 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
 
        search_start = buf->start & ~((u64)SZ_1G - 1);
 
-       if (parent)
-               btrfs_set_lock_blocking_write(parent);
-       btrfs_set_lock_blocking_write(buf);
-
        /*
         * Before CoWing this block for later modification, check if it's
         * the subtree root and do the delayed subtree trace if needed.
@@ -1578,7 +1571,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct extent_buffer *cur;
        u64 blocknr;
-       u64 gen;
        u64 search_start = *last_ret;
        u64 last_block = 0;
        u64 other;
@@ -1586,14 +1578,10 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
        int end_slot;
        int i;
        int err = 0;
-       int parent_level;
-       int uptodate;
        u32 blocksize;
        int progress_passed = 0;
        struct btrfs_disk_key disk_key;
 
-       parent_level = btrfs_header_level(parent);
-
        WARN_ON(trans->transaction != fs_info->running_transaction);
        WARN_ON(trans->transid != fs_info->generation);
 
@@ -1604,10 +1592,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
        if (parent_nritems <= 1)
                return 0;
 
-       btrfs_set_lock_blocking_write(parent);
-
        for (i = start_slot; i <= end_slot; i++) {
-               struct btrfs_key first_key;
                int close = 1;
 
                btrfs_node_key(parent, &disk_key, i);
@@ -1616,8 +1601,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
 
                progress_passed = 1;
                blocknr = btrfs_node_blockptr(parent, i);
-               gen = btrfs_node_ptr_generation(parent, i);
-               btrfs_node_key_to_cpu(parent, &first_key, i);
                if (last_block == 0)
                        last_block = blocknr;
 
@@ -1634,36 +1617,13 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
                        continue;
                }
 
-               cur = find_extent_buffer(fs_info, blocknr);
-               if (cur)
-                       uptodate = btrfs_buffer_uptodate(cur, gen, 0);
-               else
-                       uptodate = 0;
-               if (!cur || !uptodate) {
-                       if (!cur) {
-                               cur = read_tree_block(fs_info, blocknr, gen,
-                                                     parent_level - 1,
-                                                     &first_key);
-                               if (IS_ERR(cur)) {
-                                       return PTR_ERR(cur);
-                               } else if (!extent_buffer_uptodate(cur)) {
-                                       free_extent_buffer(cur);
-                                       return -EIO;
-                               }
-                       } else if (!uptodate) {
-                               err = btrfs_read_buffer(cur, gen,
-                                               parent_level - 1,&first_key);
-                               if (err) {
-                                       free_extent_buffer(cur);
-                                       return err;
-                               }
-                       }
-               }
+               cur = btrfs_read_node_slot(parent, i);
+               if (IS_ERR(cur))
+                       return PTR_ERR(cur);
                if (search_start == 0)
                        search_start = last_block;
 
                btrfs_tree_lock(cur);
-               btrfs_set_lock_blocking_write(cur);
                err = __btrfs_cow_block(trans, root, cur, parent, i,
                                        &cur, search_start,
                                        min(16 * blocksize,
@@ -1723,9 +1683,10 @@ static noinline int generic_bin_search(struct extent_buffer *eb,
                oip = offset_in_page(offset);
 
                if (oip + key_size <= PAGE_SIZE) {
-                       const unsigned long idx = offset >> PAGE_SHIFT;
+                       const unsigned long idx = get_eb_page_index(offset);
                        char *kaddr = page_address(eb->pages[idx]);
 
+                       oip = get_eb_offset_in_page(eb, offset);
                        tmp = (struct btrfs_disk_key *)(kaddr + oip);
                } else {
                        read_extent_buffer(eb, &unaligned, offset, key_size);
@@ -1801,6 +1762,7 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent,
 
        btrfs_node_key_to_cpu(parent, &first_key, slot);
        eb = read_tree_block(parent->fs_info, btrfs_node_blockptr(parent, slot),
+                            btrfs_header_owner(parent),
                             btrfs_node_ptr_generation(parent, slot),
                             level - 1, &first_key);
        if (!IS_ERR(eb) && !extent_buffer_uptodate(eb)) {
@@ -1835,8 +1797,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
        mid = path->nodes[level];
 
-       WARN_ON(path->locks[level] != BTRFS_WRITE_LOCK &&
-               path->locks[level] != BTRFS_WRITE_LOCK_BLOCKING);
+       WARN_ON(path->locks[level] != BTRFS_WRITE_LOCK);
        WARN_ON(btrfs_header_generation(mid) != trans->transid);
 
        orig_ptr = btrfs_node_blockptr(mid, orig_slot);
@@ -1865,7 +1826,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                }
 
                btrfs_tree_lock(child);
-               btrfs_set_lock_blocking_write(child);
                ret = btrfs_cow_block(trans, root, child, mid, 0, &child,
                                      BTRFS_NESTING_COW);
                if (ret) {
@@ -1904,7 +1864,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
        if (left) {
                __btrfs_tree_lock(left, BTRFS_NESTING_LEFT);
-               btrfs_set_lock_blocking_write(left);
                wret = btrfs_cow_block(trans, root, left,
                                       parent, pslot - 1, &left,
                                       BTRFS_NESTING_LEFT_COW);
@@ -1920,7 +1879,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
 
        if (right) {
                __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT);
-               btrfs_set_lock_blocking_write(right);
                wret = btrfs_cow_block(trans, root, right,
                                       parent, pslot + 1, &right,
                                       BTRFS_NESTING_RIGHT_COW);
@@ -2084,7 +2042,6 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
                u32 left_nr;
 
                __btrfs_tree_lock(left, BTRFS_NESTING_LEFT);
-               btrfs_set_lock_blocking_write(left);
 
                left_nr = btrfs_header_nritems(left);
                if (left_nr >= BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 1) {
@@ -2139,7 +2096,6 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
                u32 right_nr;
 
                __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT);
-               btrfs_set_lock_blocking_write(right);
 
                right_nr = btrfs_header_nritems(right);
                if (right_nr >= BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 1) {
@@ -2243,7 +2199,7 @@ static void reada_for_search(struct btrfs_fs_info *fs_info,
                search = btrfs_node_blockptr(node, nr);
                if ((search <= target && target - search <= 65536) ||
                    (search > target && search - target <= 65536)) {
-                       readahead_tree_block(fs_info, search);
+                       btrfs_readahead_node_child(node, nr);
                        nread += blocksize;
                }
                nscan++;
@@ -2252,16 +2208,11 @@ static void reada_for_search(struct btrfs_fs_info *fs_info,
        }
 }
 
-static noinline void reada_for_balance(struct btrfs_fs_info *fs_info,
-                                      struct btrfs_path *path, int level)
+static noinline void reada_for_balance(struct btrfs_path *path, int level)
 {
+       struct extent_buffer *parent;
        int slot;
        int nritems;
-       struct extent_buffer *parent;
-       struct extent_buffer *eb;
-       u64 gen;
-       u64 block1 = 0;
-       u64 block2 = 0;
 
        parent = path->nodes[level + 1];
        if (!parent)
@@ -2270,32 +2221,10 @@ static noinline void reada_for_balance(struct btrfs_fs_info *fs_info,
        nritems = btrfs_header_nritems(parent);
        slot = path->slots[level + 1];
 
-       if (slot > 0) {
-               block1 = btrfs_node_blockptr(parent, slot - 1);
-               gen = btrfs_node_ptr_generation(parent, slot - 1);
-               eb = find_extent_buffer(fs_info, block1);
-               /*
-                * if we get -eagain from btrfs_buffer_uptodate, we
-                * don't want to return eagain here.  That will loop
-                * forever
-                */
-               if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
-                       block1 = 0;
-               free_extent_buffer(eb);
-       }
-       if (slot + 1 < nritems) {
-               block2 = btrfs_node_blockptr(parent, slot + 1);
-               gen = btrfs_node_ptr_generation(parent, slot + 1);
-               eb = find_extent_buffer(fs_info, block2);
-               if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
-                       block2 = 0;
-               free_extent_buffer(eb);
-       }
-
-       if (block1)
-               readahead_tree_block(fs_info, block1);
-       if (block2)
-               readahead_tree_block(fs_info, block2);
+       if (slot > 0)
+               btrfs_readahead_node_child(parent, slot - 1);
+       if (slot + 1 < nritems)
+               btrfs_readahead_node_child(parent, slot + 1);
 }
 
 
@@ -2399,14 +2328,6 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
                        return 0;
                }
 
-               /* the pages were up to date, but we failed
-                * the generation number check.  Do a full
-                * read for the generation number that is correct.
-                * We must do this without dropping locks so
-                * we can trust our generation number
-                */
-               btrfs_set_path_blocking(p);
-
                /* now we're allowed to do a blocking uptodate check */
                ret = btrfs_read_buffer(tmp, gen, parent_level - 1, &first_key);
                if (!ret) {
@@ -2426,14 +2347,13 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
         * out which blocks to read.
         */
        btrfs_unlock_up_safe(p, level + 1);
-       btrfs_set_path_blocking(p);
 
        if (p->reada != READA_NONE)
                reada_for_search(fs_info, p, level, slot, key->objectid);
 
        ret = -EAGAIN;
-       tmp = read_tree_block(fs_info, blocknr, gen, parent_level - 1,
-                             &first_key);
+       tmp = read_tree_block(fs_info, blocknr, root->root_key.objectid,
+                             gen, parent_level - 1, &first_key);
        if (!IS_ERR(tmp)) {
                /*
                 * If the read above didn't mark this buffer up to date,
@@ -2468,58 +2388,42 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
                       int *write_lock_level)
 {
        struct btrfs_fs_info *fs_info = root->fs_info;
-       int ret;
+       int ret = 0;
 
        if ((p->search_for_split || ins_len > 0) && btrfs_header_nritems(b) >=
            BTRFS_NODEPTRS_PER_BLOCK(fs_info) - 3) {
-               int sret;
 
                if (*write_lock_level < level + 1) {
                        *write_lock_level = level + 1;
                        btrfs_release_path(p);
-                       goto again;
+                       return -EAGAIN;
                }
 
-               btrfs_set_path_blocking(p);
-               reada_for_balance(fs_info, p, level);
-               sret = split_node(trans, root, p, level);
+               reada_for_balance(p, level);
+               ret = split_node(trans, root, p, level);
 
-               BUG_ON(sret > 0);
-               if (sret) {
-                       ret = sret;
-                       goto done;
-               }
                b = p->nodes[level];
        } else if (ins_len < 0 && btrfs_header_nritems(b) <
                   BTRFS_NODEPTRS_PER_BLOCK(fs_info) / 2) {
-               int sret;
 
                if (*write_lock_level < level + 1) {
                        *write_lock_level = level + 1;
                        btrfs_release_path(p);
-                       goto again;
+                       return -EAGAIN;
                }
 
-               btrfs_set_path_blocking(p);
-               reada_for_balance(fs_info, p, level);
-               sret = balance_level(trans, root, p, level);
+               reada_for_balance(p, level);
+               ret = balance_level(trans, root, p, level);
+               if (ret)
+                       return ret;
 
-               if (sret) {
-                       ret = sret;
-                       goto done;
-               }
                b = p->nodes[level];
                if (!b) {
                        btrfs_release_path(p);
-                       goto again;
+                       return -EAGAIN;
                }
                BUG_ON(btrfs_header_nritems(b) == 1);
        }
-       return 0;
-
-again:
-       ret = -EAGAIN;
-done:
        return ret;
 }
 
@@ -2616,7 +2520,7 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root,
                 * We don't know the level of the root node until we actually
                 * have it read locked
                 */
-               b = __btrfs_read_lock_root_node(root, p->recurse);
+               b = btrfs_read_lock_root_node(root);
                level = btrfs_header_level(b);
                if (level > write_lock_level)
                        goto out;
@@ -2752,7 +2656,6 @@ again:
                                goto again;
                        }
 
-                       btrfs_set_path_blocking(p);
                        if (last_level)
                                err = btrfs_cow_block(trans, root, b, NULL, 0,
                                                      &b,
@@ -2822,7 +2725,6 @@ cow_done:
                                        goto again;
                                }
 
-                               btrfs_set_path_blocking(p);
                                err = split_leaf(trans, root, key,
                                                 p, ins_len, ret == 0);
 
@@ -2884,17 +2786,10 @@ cow_done:
                if (!p->skip_locking) {
                        level = btrfs_header_level(b);
                        if (level <= write_lock_level) {
-                               if (!btrfs_try_tree_write_lock(b)) {
-                                       btrfs_set_path_blocking(p);
-                                       btrfs_tree_lock(b);
-                               }
+                               btrfs_tree_lock(b);
                                p->locks[level] = BTRFS_WRITE_LOCK;
                        } else {
-                               if (!btrfs_tree_read_lock_atomic(b)) {
-                                       btrfs_set_path_blocking(p);
-                                       __btrfs_tree_read_lock(b, BTRFS_NESTING_NORMAL,
-                                                              p->recurse);
-                               }
+                               btrfs_tree_read_lock(b);
                                p->locks[level] = BTRFS_READ_LOCK;
                        }
                        p->nodes[level] = b;
@@ -2902,12 +2797,6 @@ cow_done:
        }
        ret = 1;
 done:
-       /*
-        * we don't really know what they plan on doing with the path
-        * from here on, so for now just mark it as blocking
-        */
-       if (!p->leave_spinning)
-               btrfs_set_path_blocking(p);
        if (ret < 0 && !p->skip_release_on_error)
                btrfs_release_path(p);
        return ret;
@@ -2999,10 +2888,7 @@ again:
                }
 
                level = btrfs_header_level(b);
-               if (!btrfs_tree_read_lock_atomic(b)) {
-                       btrfs_set_path_blocking(p);
-                       btrfs_tree_read_lock(b);
-               }
+               btrfs_tree_read_lock(b);
                b = tree_mod_log_rewind(fs_info, p, b, time_seq);
                if (!b) {
                        ret = -ENOMEM;
@@ -3013,8 +2899,6 @@ again:
        }
        ret = 1;
 done:
-       if (!p->leave_spinning)
-               btrfs_set_path_blocking(p);
        if (ret < 0)
                btrfs_release_path(p);
 
@@ -3441,7 +3325,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
        add_root_to_dirty_list(root);
        atomic_inc(&c->refs);
        path->nodes[level] = c;
-       path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
+       path->locks[level] = BTRFS_WRITE_LOCK;
        path->slots[level] = 0;
        return 0;
 }
@@ -3562,7 +3446,6 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
                           (c_nritems - mid) * sizeof(struct btrfs_key_ptr));
        btrfs_set_header_nritems(split, c_nritems - mid);
        btrfs_set_header_nritems(c, mid);
-       ret = 0;
 
        btrfs_mark_buffer_dirty(c);
        btrfs_mark_buffer_dirty(split);
@@ -3580,7 +3463,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
                btrfs_tree_unlock(split);
                free_extent_buffer(split);
        }
-       return ret;
+       return 0;
 }
 
 /*
@@ -3814,7 +3697,6 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
                return 1;
 
        __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT);
-       btrfs_set_lock_blocking_write(right);
 
        free_space = btrfs_leaf_free_space(right);
        if (free_space < data_size)
@@ -4053,7 +3935,6 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
                return 1;
 
        __btrfs_tree_lock(left, BTRFS_NESTING_LEFT);
-       btrfs_set_lock_blocking_write(left);
 
        free_space = btrfs_leaf_free_space(left);
        if (free_space < data_size) {
@@ -4448,7 +4329,6 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
                        goto err;
        }
 
-       btrfs_set_path_blocking(path);
        ret = split_leaf(trans, root, &key, path, ins_len, 1);
        if (ret)
                goto err;
@@ -4478,8 +4358,6 @@ static noinline int split_item(struct btrfs_path *path,
        leaf = path->nodes[0];
        BUG_ON(btrfs_leaf_free_space(leaf) < sizeof(struct btrfs_item));
 
-       btrfs_set_path_blocking(path);
-
        item = btrfs_item_nr(path->slots[0]);
        orig_offset = btrfs_item_offset(leaf, item);
        item_size = btrfs_item_size(leaf, item);
@@ -5055,7 +4933,6 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                if (leaf == root->node) {
                        btrfs_set_header_level(leaf, 0);
                } else {
-                       btrfs_set_path_blocking(path);
                        btrfs_clean_tree_block(leaf);
                        btrfs_del_leaf(trans, root, path, leaf);
                }
@@ -5077,7 +4954,6 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                        slot = path->slots[1];
                        atomic_inc(&leaf->refs);
 
-                       btrfs_set_path_blocking(path);
                        wret = push_leaf_left(trans, root, path, 1, 1,
                                              1, (u32)-1);
                        if (wret < 0 && wret != -ENOSPC)
@@ -5248,7 +5124,6 @@ find_next_key:
                 */
                if (slot >= nritems) {
                        path->slots[level] = slot;
-                       btrfs_set_path_blocking(path);
                        sret = btrfs_find_next_key(root, path, min_key, level,
                                                  min_trans);
                        if (sret == 0) {
@@ -5265,7 +5140,6 @@ find_next_key:
                        ret = 0;
                        goto out;
                }
-               btrfs_set_path_blocking(path);
                cur = btrfs_read_node_slot(cur, slot);
                if (IS_ERR(cur)) {
                        ret = PTR_ERR(cur);
@@ -5282,7 +5156,6 @@ out:
        path->keep_locks = keep_locks;
        if (ret == 0) {
                btrfs_unlock_up_safe(path, path->lowest_level + 1);
-               btrfs_set_path_blocking(path);
                memcpy(min_key, &found_key, sizeof(found_key));
        }
        return ret;
@@ -5384,8 +5257,7 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
        struct btrfs_key key;
        u32 nritems;
        int ret;
-       int old_spinning = path->leave_spinning;
-       int next_rw_lock = 0;
+       int i;
 
        nritems = btrfs_header_nritems(path->nodes[0]);
        if (nritems == 0)
@@ -5395,11 +5267,9 @@ int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
 again:
        level = 1;
        next = NULL;
-       next_rw_lock = 0;
        btrfs_release_path(path);
 
        path->keep_locks = 1;
-       path->leave_spinning = 1;
 
        if (time_seq)
                ret = btrfs_search_old_slot(root, &key, path, time_seq);
@@ -5459,13 +5329,22 @@ again:
                        continue;
                }
 
-               if (next) {
-                       btrfs_tree_unlock_rw(next, next_rw_lock);
-                       free_extent_buffer(next);
+
+               /*
+                * Our current level is where we're going to start from, and to
+                * make sure lockdep doesn't complain we need to drop our locks
+                * and nodes from 0 to our current level.
+                */
+               for (i = 0; i < level; i++) {
+                       if (path->locks[level]) {
+                               btrfs_tree_read_unlock(path->nodes[i]);
+                               path->locks[i] = 0;
+                       }
+                       free_extent_buffer(path->nodes[i]);
+                       path->nodes[i] = NULL;
                }
 
                next = c;
-               next_rw_lock = path->locks[level];
                ret = read_block_for_search(root, path, &next, level,
                                            slot, &key);
                if (ret == -EAGAIN)
@@ -5491,28 +5370,18 @@ again:
                                cond_resched();
                                goto again;
                        }
-                       if (!ret) {
-                               btrfs_set_path_blocking(path);
-                               __btrfs_tree_read_lock(next,
-                                                      BTRFS_NESTING_RIGHT,
-                                                      path->recurse);
-                       }
-                       next_rw_lock = BTRFS_READ_LOCK;
+                       if (!ret)
+                               btrfs_tree_read_lock(next);
                }
                break;
        }
        path->slots[level] = slot;
        while (1) {
                level--;
-               c = path->nodes[level];
-               if (path->locks[level])
-                       btrfs_tree_unlock_rw(c, path->locks[level]);
-
-               free_extent_buffer(c);
                path->nodes[level] = next;
                path->slots[level] = 0;
                if (!path->skip_locking)
-                       path->locks[level] = next_rw_lock;
+                       path->locks[level] = BTRFS_READ_LOCK;
                if (!level)
                        break;
 
@@ -5526,23 +5395,12 @@ again:
                        goto done;
                }
 
-               if (!path->skip_locking) {
-                       ret = btrfs_try_tree_read_lock(next);
-                       if (!ret) {
-                               btrfs_set_path_blocking(path);
-                               __btrfs_tree_read_lock(next,
-                                                      BTRFS_NESTING_RIGHT,
-                                                      path->recurse);
-                       }
-                       next_rw_lock = BTRFS_READ_LOCK;
-               }
+               if (!path->skip_locking)
+                       btrfs_tree_read_lock(next);
        }
        ret = 0;
 done:
        unlock_up(path, 0, 1, 0, NULL);
-       path->leave_spinning = old_spinning;
-       if (!old_spinning)
-               btrfs_set_path_blocking(path);
 
        return ret;
 }
@@ -5564,7 +5422,6 @@ int btrfs_previous_item(struct btrfs_root *root,
 
        while (1) {
                if (path->slots[0] == 0) {
-                       btrfs_set_path_blocking(path);
                        ret = btrfs_prev_leaf(root, path);
                        if (ret != 0)
                                return ret;
@@ -5606,7 +5463,6 @@ int btrfs_previous_extent_item(struct btrfs_root *root,
 
        while (1) {
                if (path->slots[0] == 0) {
-                       btrfs_set_path_blocking(path);
                        ret = btrfs_prev_leaf(root, path);
                        if (ret != 0)
                                return ret;