]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
btrfs: set update the uuid generation as soon as possible
authorJosef Bacik <josef@toxicpanda.com>
Fri, 14 Feb 2020 20:22:06 +0000 (15:22 -0500)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 29 Apr 2020 12:56:07 +0000 (14:56 +0200)
BugLink: https://bugs.launchpad.net/bugs/1874502
commit 75ec1db8717a8f0a9d9c8d033e542fdaa7b73898 upstream.

In my EIO stress testing I noticed I was getting forced to rescan the
uuid tree pretty often, which was weird.  This is because my error
injection stuff would sometimes inject an error after log replay but
before we loaded the UUID tree.  If log replay committed the transaction
it wouldn't have updated the uuid tree generation, but the tree was
valid and didn't change, so there's no reason to not update the
generation here.

Fix this by setting the BTRFS_FS_UPDATE_UUID_TREE_GEN bit immediately
after reading all the fs roots if the uuid tree generation matches the
fs generation.  Then any transaction commits that happen during mount
won't screw up our uuid tree state, forcing us to do needless uuid
rescans.

Fixes: 70f801754728 ("Btrfs: check UUID tree during mount if required")
CC: stable@vger.kernel.org # 4.19+
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Kelsey Skunberg <kelsey.skunberg@canonical.com>
fs/btrfs/disk-io.c

index 830240a21d9abd52a1b379929bae9a1f975932af..654618d7ca0a04bbe616d33544434d08521cf0f9 100644 (file)
@@ -2795,6 +2795,18 @@ retry_root_backup:
        fs_info->generation = generation;
        fs_info->last_trans_committed = generation;
 
+       /*
+        * If we have a uuid root and we're not being told to rescan we need to
+        * check the generation here so we can set the
+        * BTRFS_FS_UPDATE_UUID_TREE_GEN bit.  Otherwise we could commit the
+        * transaction during a balance or the log replay without updating the
+        * uuid generation, and then if we crash we would rescan the uuid tree,
+        * even though it was perfectly fine.
+        */
+       if (fs_info->uuid_root && !btrfs_test_opt(fs_info, RESCAN_UUID_TREE) &&
+           fs_info->generation == btrfs_super_uuid_tree_generation(disk_super))
+               set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags);
+
        ret = btrfs_recover_balance(fs_info);
        if (ret) {
                btrfs_err(fs_info, "failed to recover balance: %d", ret);
@@ -3017,8 +3029,6 @@ retry_root_backup:
                        close_ctree(fs_info);
                        return ret;
                }
-       } else {
-               set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags);
        }
        set_bit(BTRFS_FS_OPEN, &fs_info->flags);