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 ac8ebdf..0781089 100644 (file)
@@ -1353,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);
@@ -1570,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;
@@ -1578,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);
 
@@ -1597,7 +1593,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
                return 0;
 
        for (i = start_slot; i <= end_slot; i++) {
-               struct btrfs_key first_key;
                int close = 1;
 
                btrfs_node_key(parent, &disk_key, i);
@@ -1606,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;
 
@@ -1624,31 +1617,9 @@ 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;
 
@@ -1712,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);
@@ -1790,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)) {
@@ -2226,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++;
@@ -2235,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)
@@ -2253,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);
 }
 
 
@@ -2406,8 +2352,8 @@ read_block_for_search(struct btrfs_root *root, struct btrfs_path *p,
                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,
@@ -2442,56 +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;
                }
 
-               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;
                }
 
-               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;
 }
 
@@ -2588,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;
@@ -2857,8 +2789,7 @@ cow_done:
                                btrfs_tree_lock(b);
                                p->locks[level] = BTRFS_WRITE_LOCK;
                        } else {
-                               __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;
@@ -3515,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);
@@ -3533,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;
 }
 
 /*
@@ -5327,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)
@@ -5338,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);
@@ -5402,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)
@@ -5434,27 +5370,18 @@ again:
                                cond_resched();
                                goto again;
                        }
-                       if (!ret) {
-                               __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;
 
@@ -5468,16 +5395,12 @@ again:
                        goto done;
                }
 
-               if (!path->skip_locking) {
-                       __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;
 
        return ret;
 }