]> git.hungrycats.org Git - linux/commitdiff
btrfs: reloc: reorder reservation before root selection
authorJosef Bacik <josef@toxicpanda.com>
Fri, 13 Mar 2020 21:17:06 +0000 (17:17 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Thu, 9 Apr 2020 03:30:39 +0000 (23:30 -0400)
Since we're not only checking for metadata reservations but also if we
need to throttle our delayed ref generation, reorder
reserve_metadata_space() above the select_one_root() call in
relocate_tree_block().

The reason we want this is because select_reloc_root() will mess with
the backref cache, and if we're going to bail we want to be able to
cleanly remove this node from the backref cache and come back along to
regenerate it.  Move it up so this is the first thing we do to make
restarting cleaner.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
(cherry picked from commit 5f6b2e5cd67a7bb39eb24fa3206e54803e1a25ff)
(cherry picked from commit 7cc6fc512a506bc67013849c8f56110b625805f5)

fs/btrfs/relocation.c

index 937d1ef5c26e059daf8fa2f933bf56ab86c80d67..74ef64e9d56558c04a17910d25fe77bba8237ef4 100644 (file)
@@ -2940,6 +2940,14 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
        if (!node)
                return 0;
 
+       /*
+        * If we fail here we want to drop our backref_node because we are going
+        * to start over and regenerate the tree for it.
+        */
+       ret = reserve_metadata_space(trans, rc, node);
+       if (ret)
+               goto out;
+
        BUG_ON(node->processed);
        root = select_one_root(node);
        if (root == ERR_PTR(-ENOENT)) {
@@ -2947,12 +2955,6 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
                goto out;
        }
 
-       if (!root || test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
-               ret = reserve_metadata_space(trans, rc, node);
-               if (ret)
-                       goto out;
-       }
-
        if (root) {
                if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
                        BUG_ON(node->new_bytenr);