diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2013-08-15 17:11:23 +0200 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-09-01 08:15:58 -0400 |
commit | 70f801754728017ebc909d603c69255dc1e6f06f (patch) | |
tree | f4af464776a17b130686cb85a98adbeb6083d43c /fs/btrfs/disk-io.c | |
parent | 26432799c902b76e87f68f5c88f2146a78ba84af (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.c | 18 |
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, int err = -EINVAL; int num_backups_tried = 0; int backup_index = 0; - bool create_uuid_tree = false; + bool create_uuid_tree; + bool check_uuid_tree; tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info); chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); @@ -2724,9 +2725,13 @@ retry_root_backup: if (ret != -ENOENT) goto recovery_tree_root; create_uuid_tree = true; + check_uuid_tree = false; } else { uuid_root->track_dirty = 1; fs_info->uuid_root = uuid_root; + create_uuid_tree = false; + check_uuid_tree = + generation != btrfs_super_uuid_tree_generation(disk_super); } fs_info->generation = generation; @@ -2924,6 +2929,17 @@ retry_root_backup: close_ctree(tree_root); return ret; } + } else if (check_uuid_tree) { + pr_info("btrfs: checking UUID tree\n"); + ret = btrfs_check_uuid_tree(fs_info); + if (ret) { + pr_warn("btrfs: failed to check the UUID tree %d\n", + ret); + close_ctree(tree_root); + return ret; + } + } else { + fs_info->update_uuid_tree_gen = 1; } return 0; |