btrfs: cleanup extent buffer readahead
authorJosef Bacik <josef@toxicpanda.com>
Thu, 5 Nov 2020 15:45:09 +0000 (10:45 -0500)
committerDavid Sterba <dsterba@suse.com>
Tue, 8 Dec 2020 14:54:05 +0000 (15:54 +0100)
We're going to pass around more information when we allocate extent
buffers, in order to make that cleaner how we do readahead.  Most of the
callers have the parent node that we're getting our blockptr from, with
the sole exception of relocation which simply has the bytenr it wants to
read.

Add a helper that takes the current arguments that we need (bytenr and
gen), and add another helper for simply reading the slot out of a node.
In followup patches the helper that takes all the extra arguments will
be expanded, and the simpler helper won't need to have it's arguments
adjusted.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/relocation.c
fs/btrfs/volumes.c

index d2d5854d51a789dca63806599638a828231fbfc0..0ff866328a4f184d87e66c314ceee0c1baa64aee 100644 (file)
@@ -2226,7 +2226,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 +2235,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 +2248,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);
 }
 
 
@@ -2454,7 +2427,7 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
                        goto again;
                }
 
-               reada_for_balance(fs_info, p, level);
+               reada_for_balance(p, level);
                sret = split_node(trans, root, p, level);
 
                BUG_ON(sret > 0);
@@ -2473,7 +2446,7 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
                        goto again;
                }
 
-               reada_for_balance(fs_info, p, level);
+               reada_for_balance(p, level);
                sret = balance_level(trans, root, p, level);
 
                if (sret) {
index 9f0d30ea535d562e3251898d154561295e379684..012e66601270a2ef7f6ceacd7ce5bb2834015926 100644 (file)
@@ -953,22 +953,6 @@ static const struct address_space_operations btree_aops = {
        .set_page_dirty = btree_set_page_dirty,
 };
 
-void readahead_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr)
-{
-       struct extent_buffer *buf = NULL;
-       int ret;
-
-       buf = btrfs_find_create_tree_block(fs_info, bytenr);
-       if (IS_ERR(buf))
-               return;
-
-       ret = read_extent_buffer_pages(buf, WAIT_NONE, 0);
-       if (ret < 0)
-               free_extent_buffer_stale(buf);
-       else
-               free_extent_buffer(buf);
-}
-
 struct extent_buffer *btrfs_find_create_tree_block(
                                                struct btrfs_fs_info *fs_info,
                                                u64 bytenr)
index 238b45223f2eeee3529da9d7ef85f89b58f182a3..009f505d6c9792f1e5e469743798b956611b4d80 100644 (file)
@@ -45,7 +45,6 @@ int btrfs_verify_level_key(struct extent_buffer *eb, int level,
 struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
                                      u64 parent_transid, int level,
                                      struct btrfs_key *first_key);
-void readahead_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr);
 struct extent_buffer *btrfs_find_create_tree_block(
                                                struct btrfs_fs_info *fs_info,
                                                u64 bytenr);
index 5c82cfdb09445486b224b76edb29a4f6a1876384..5d54819aada7e0074be6cc843280f5d882ca2d8c 100644 (file)
@@ -4859,7 +4859,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
                                continue;
                }
 reada:
-               readahead_tree_block(fs_info, bytenr);
+               btrfs_readahead_node_child(eb, slot);
                nread++;
        }
        wc->reada_slot = slot;
index 1dfbe859c650e931cd59c0f769b373df62db9100..973254b1f21607cc638b9a19ee910b235d1a95ec 100644 (file)
@@ -6123,3 +6123,50 @@ int try_release_extent_buffer(struct page *page)
 
        return release_extent_buffer(eb);
 }
+
+/*
+ * btrfs_readahead_tree_block - attempt to readahead a child block
+ * @fs_info:   the fs_info
+ * @bytenr:    bytenr to read
+ * @gen:       generation for the uptodate check, can be 0
+ *
+ * Attempt to readahead a tree block at @bytenr.  If @gen is 0 then we do a
+ * normal uptodate check of the eb, without checking the generation.  If we have
+ * to read the block we will not block on anything.
+ */
+void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
+                               u64 bytenr, u64 gen)
+{
+       struct extent_buffer *eb;
+       int ret;
+
+       eb = btrfs_find_create_tree_block(fs_info, bytenr);
+       if (IS_ERR(eb))
+               return;
+
+       if (btrfs_buffer_uptodate(eb, gen, 1)) {
+               free_extent_buffer(eb);
+               return;
+       }
+
+       ret = read_extent_buffer_pages(eb, WAIT_NONE, 0);
+       if (ret < 0)
+               free_extent_buffer_stale(eb);
+       else
+               free_extent_buffer(eb);
+}
+
+/*
+ * btrfs_readahead_node_child - readahead a node's child block
+ * @node:      parent node we're reading from
+ * @slot:      slot in the parent node for the child we want to read
+ *
+ * A helper for btrfs_readahead_tree_block, we simply read the bytenr pointed at
+ * the slot in the node provided.
+ */
+void btrfs_readahead_node_child(struct extent_buffer *node, int slot)
+{
+       btrfs_readahead_tree_block(node->fs_info,
+                                  btrfs_node_blockptr(node, slot),
+                                  btrfs_node_ptr_generation(node, slot));
+}
index 3c2bf21c54ebe61f75d061fea297d8f56d139aae..a211e90292f8f517a33d74666cc1b52f2d9fdcae 100644 (file)
@@ -198,6 +198,9 @@ void free_extent_buffer_stale(struct extent_buffer *eb);
 int read_extent_buffer_pages(struct extent_buffer *eb, int wait,
                             int mirror_num);
 void wait_on_extent_buffer_writeback(struct extent_buffer *eb);
+void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info,
+                               u64 bytenr, u64 gen);
+void btrfs_readahead_node_child(struct extent_buffer *node, int slot);
 
 static inline int num_extent_pages(const struct extent_buffer *eb)
 {
index 0b3ccf464c3dfcccdfb62719dbc19e640e6c9b4d..415332a303ec37d172b1a2f13d72044217859f38 100644 (file)
@@ -2542,7 +2542,7 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
        /* Kick in readahead for tree blocks with missing keys */
        rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
                if (!block->key_ready)
-                       readahead_tree_block(fs_info, block->bytenr);
+                       btrfs_readahead_tree_block(fs_info, block->bytenr, 0);
        }
 
        /* Get first keys */
index ed4163b54f756221cdc19d6be21c8b84e1b9cda7..814abc0b3ff3dd4b5d4651d919692b4fc3327299 100644 (file)
@@ -7071,12 +7071,8 @@ static void readahead_tree_node_children(struct extent_buffer *node)
        int i;
        const int nr_items = btrfs_header_nritems(node);
 
-       for (i = 0; i < nr_items; i++) {
-               u64 start;
-
-               start = btrfs_node_blockptr(node, i);
-               readahead_tree_block(node->fs_info, start);
-       }
+       for (i = 0; i < nr_items; i++)
+               btrfs_readahead_node_child(node, i);
 }
 
 int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)