| From 55204a0c0e3d447852d3c524d03e28773b5bfe86 Mon Sep 17 00:00:00 2001 |
| From: Josef Bacik <josef@toxicpanda.com> |
| Date: Fri, 14 Feb 2020 15:22:06 -0500 |
| Subject: [PATCH] btrfs: set update the uuid generation as soon as possible |
| |
| 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: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c |
| index bb33bbc7348f..54d9af9ddb1a 100644 |
| --- a/fs/btrfs/disk-io.c |
| +++ b/fs/btrfs/disk-io.c |
| @@ -3050,6 +3050,18 @@ int open_ctree(struct super_block *sb, |
| 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_verify_dev_extents(fs_info); |
| if (ret) { |
| btrfs_err(fs_info, |
| @@ -3280,8 +3292,6 @@ int open_ctree(struct super_block *sb, |
| 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); |
| |
| -- |
| 2.7.4 |
| |