aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2013-08-15 11:11:23 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:15:58 -0400
commit70f801754728017ebc909d603c69255dc1e6f06f (patch)
treef4af464776a17b130686cb85a98adbeb6083d43c /fs/btrfs/disk-io.c
parent26432799c902b76e87f68f5c88f2146a78ba84af (diff)
Btrfs: check UUID tree during mount if required
If the filesystem was mounted with an old kernel that was not aware of the UUID tree, this is detected by looking at the uuid_tree_generation field of the superblock (similar to how the free space cache is doing it). If a mismatch is detected at mount time, a thread is started that does two things: 1. Iterate through the UUID tree, check each entry, delete those entries that are not valid anymore (i.e., the subvol does not exist anymore or the value changed). 2. Iterate through the root tree, for each found subvolume, add the UUID tree entries for the subvolume (if they are not already there). This mechanism is also used to handle and repair errors that happened during the initial creation and filling of the tree. The update of the uuid_tree_generation field (which indicates that the state of the UUID tree is up to date) is blocked until all create and repair operations are successfully completed. Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index fa49e900216a..e7ef82ad0d26 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2120,7 +2120,8 @@ int open_ctree(struct super_block *sb,
2120 int err = -EINVAL; 2120 int err = -EINVAL;
2121 int num_backups_tried = 0; 2121 int num_backups_tried = 0;
2122 int backup_index = 0; 2122 int backup_index = 0;
2123 bool create_uuid_tree = false; 2123 bool create_uuid_tree;
2124 bool check_uuid_tree;
2124 2125
2125 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info); 2126 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info);
2126 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); 2127 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info);
@@ -2724,9 +2725,13 @@ retry_root_backup:
2724 if (ret != -ENOENT) 2725 if (ret != -ENOENT)
2725 goto recovery_tree_root; 2726 goto recovery_tree_root;
2726 create_uuid_tree = true; 2727 create_uuid_tree = true;
2728 check_uuid_tree = false;
2727 } else { 2729 } else {
2728 uuid_root->track_dirty = 1; 2730 uuid_root->track_dirty = 1;
2729 fs_info->uuid_root = uuid_root; 2731 fs_info->uuid_root = uuid_root;
2732 create_uuid_tree = false;
2733 check_uuid_tree =
2734 generation != btrfs_super_uuid_tree_generation(disk_super);
2730 } 2735 }
2731 2736
2732 fs_info->generation = generation; 2737 fs_info->generation = generation;
@@ -2924,6 +2929,17 @@ retry_root_backup:
2924 close_ctree(tree_root); 2929 close_ctree(tree_root);
2925 return ret; 2930 return ret;
2926 } 2931 }
2932 } else if (check_uuid_tree) {
2933 pr_info("btrfs: checking UUID tree\n");
2934 ret = btrfs_check_uuid_tree(fs_info);
2935 if (ret) {
2936 pr_warn("btrfs: failed to check the UUID tree %d\n",
2937 ret);
2938 close_ctree(tree_root);
2939 return ret;
2940 }
2941 } else {
2942 fs_info->update_uuid_tree_gen = 1;
2927 } 2943 }
2928 2944
2929 return 0; 2945 return 0;