aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2013-08-15 11:11:19 -0400
committerChris Mason <chris.mason@fusionio.com>2013-09-01 08:15:54 -0400
commitf7a81ea4cc6bdb51d8267d2f3ff485f0b4070074 (patch)
tree61fd4fd144fae34736eb2cda2ed6b351c82d9b54 /fs
parent8f8ae8e213300378d2506b68d581c80d9dfd2faf (diff)
Btrfs: create UUID tree if required
This tree is not created by mkfs.btrfs. Therefore when a filesystem is mounted writable and the UUID tree does not exist, this tree is created if required. The tree is also added to the fs_info structure and initialized, but this commit does not yet read or write UUID tree elements. 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')
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c34
-rw-r--r--fs/btrfs/extent-tree.c3
-rw-r--r--fs/btrfs/volumes.c26
-rw-r--r--fs/btrfs/volumes.h1
5 files changed, 65 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 429c54ac1a65..c03e61ef7230 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1306,6 +1306,7 @@ struct btrfs_fs_info {
1306 struct btrfs_root *fs_root; 1306 struct btrfs_root *fs_root;
1307 struct btrfs_root *csum_root; 1307 struct btrfs_root *csum_root;
1308 struct btrfs_root *quota_root; 1308 struct btrfs_root *quota_root;
1309 struct btrfs_root *uuid_root;
1309 1310
1310 /* the log root tree is a directory of all the other log roots */ 1311 /* the log root tree is a directory of all the other log roots */
1311 struct btrfs_root *log_root_tree; 1312 struct btrfs_root *log_root_tree;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f96a237bb40a..80bd63738c6d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1586,6 +1586,9 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
1586 if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID) 1586 if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID)
1587 return fs_info->quota_root ? fs_info->quota_root : 1587 return fs_info->quota_root ? fs_info->quota_root :
1588 ERR_PTR(-ENOENT); 1588 ERR_PTR(-ENOENT);
1589 if (location->objectid == BTRFS_UUID_TREE_OBJECTID)
1590 return fs_info->uuid_root ? fs_info->uuid_root :
1591 ERR_PTR(-ENOENT);
1589again: 1592again:
1590 root = btrfs_lookup_fs_root(fs_info, location->objectid); 1593 root = btrfs_lookup_fs_root(fs_info, location->objectid);
1591 if (root) 1594 if (root)
@@ -2044,6 +2047,12 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
2044 info->quota_root->node = NULL; 2047 info->quota_root->node = NULL;
2045 info->quota_root->commit_root = NULL; 2048 info->quota_root->commit_root = NULL;
2046 } 2049 }
2050 if (info->uuid_root) {
2051 free_extent_buffer(info->uuid_root->node);
2052 free_extent_buffer(info->uuid_root->commit_root);
2053 info->uuid_root->node = NULL;
2054 info->uuid_root->commit_root = NULL;
2055 }
2047 if (chunk_root) { 2056 if (chunk_root) {
2048 free_extent_buffer(info->chunk_root->node); 2057 free_extent_buffer(info->chunk_root->node);
2049 free_extent_buffer(info->chunk_root->commit_root); 2058 free_extent_buffer(info->chunk_root->commit_root);
@@ -2104,11 +2113,13 @@ int open_ctree(struct super_block *sb,
2104 struct btrfs_root *chunk_root; 2113 struct btrfs_root *chunk_root;
2105 struct btrfs_root *dev_root; 2114 struct btrfs_root *dev_root;
2106 struct btrfs_root *quota_root; 2115 struct btrfs_root *quota_root;
2116 struct btrfs_root *uuid_root;
2107 struct btrfs_root *log_tree_root; 2117 struct btrfs_root *log_tree_root;
2108 int ret; 2118 int ret;
2109 int err = -EINVAL; 2119 int err = -EINVAL;
2110 int num_backups_tried = 0; 2120 int num_backups_tried = 0;
2111 int backup_index = 0; 2121 int backup_index = 0;
2122 bool create_uuid_tree = false;
2112 2123
2113 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info); 2124 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info);
2114 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); 2125 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info);
@@ -2704,6 +2715,18 @@ retry_root_backup:
2704 fs_info->quota_root = quota_root; 2715 fs_info->quota_root = quota_root;
2705 } 2716 }
2706 2717
2718 location.objectid = BTRFS_UUID_TREE_OBJECTID;
2719 uuid_root = btrfs_read_tree_root(tree_root, &location);
2720 if (IS_ERR(uuid_root)) {
2721 ret = PTR_ERR(uuid_root);
2722 if (ret != -ENOENT)
2723 goto recovery_tree_root;
2724 create_uuid_tree = true;
2725 } else {
2726 uuid_root->track_dirty = 1;
2727 fs_info->uuid_root = uuid_root;
2728 }
2729
2707 fs_info->generation = generation; 2730 fs_info->generation = generation;
2708 fs_info->last_trans_committed = generation; 2731 fs_info->last_trans_committed = generation;
2709 2732
@@ -2890,6 +2913,17 @@ retry_root_backup:
2890 2913
2891 btrfs_qgroup_rescan_resume(fs_info); 2914 btrfs_qgroup_rescan_resume(fs_info);
2892 2915
2916 if (create_uuid_tree) {
2917 pr_info("btrfs: creating UUID tree\n");
2918 ret = btrfs_create_uuid_tree(fs_info);
2919 if (ret) {
2920 pr_warn("btrfs: failed to create the UUID tree %d\n",
2921 ret);
2922 close_ctree(tree_root);
2923 return ret;
2924 }
2925 }
2926
2893 return 0; 2927 return 0;
2894 2928
2895fail_qgroup: 2929fail_qgroup:
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f1c1694d34b7..8cb1d41ba501 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4361,6 +4361,9 @@ static struct btrfs_block_rsv *get_block_rsv(
4361 if (root == root->fs_info->csum_root && trans->adding_csums) 4361 if (root == root->fs_info->csum_root && trans->adding_csums)
4362 block_rsv = trans->block_rsv; 4362 block_rsv = trans->block_rsv;
4363 4363
4364 if (root == root->fs_info->uuid_root)
4365 block_rsv = trans->block_rsv;
4366
4364 if (!block_rsv) 4367 if (!block_rsv)
4365 block_rsv = root->block_rsv; 4368 block_rsv = root->block_rsv;
4366 4369
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 306547b51a13..e084218c09d2 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3429,6 +3429,32 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info)
3429 return 0; 3429 return 0;
3430} 3430}
3431 3431
3432int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info)
3433{
3434 struct btrfs_trans_handle *trans;
3435 struct btrfs_root *tree_root = fs_info->tree_root;
3436 struct btrfs_root *uuid_root;
3437
3438 /*
3439 * 1 - root node
3440 * 1 - root item
3441 */
3442 trans = btrfs_start_transaction(tree_root, 2);
3443 if (IS_ERR(trans))
3444 return PTR_ERR(trans);
3445
3446 uuid_root = btrfs_create_tree(trans, fs_info,
3447 BTRFS_UUID_TREE_OBJECTID);
3448 if (IS_ERR(uuid_root)) {
3449 btrfs_abort_transaction(trans, tree_root,
3450 PTR_ERR(uuid_root));
3451 return PTR_ERR(uuid_root);
3452 }
3453
3454 fs_info->uuid_root = uuid_root;
3455
3456 return btrfs_commit_transaction(trans, tree_root);
3457}
3432/* 3458/*
3433 * shrinking a device means finding all of the device extents past 3459 * shrinking a device means finding all of the device extents past
3434 * the new size, and then following the back refs to the chunks. 3460 * the new size, and then following the back refs to the chunks.
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 08c44d9059b1..7071b2988305 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -322,6 +322,7 @@ int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info);
322int btrfs_recover_balance(struct btrfs_fs_info *fs_info); 322int btrfs_recover_balance(struct btrfs_fs_info *fs_info);
323int btrfs_pause_balance(struct btrfs_fs_info *fs_info); 323int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
324int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); 324int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
325int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info);
325int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); 326int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
326int find_free_dev_extent(struct btrfs_trans_handle *trans, 327int find_free_dev_extent(struct btrfs_trans_handle *trans,
327 struct btrfs_device *device, u64 num_bytes, 328 struct btrfs_device *device, u64 num_bytes,