aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-11-17 21:02:50 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-17 21:02:50 -0500
commit3de4586c5278a28107030c336956381f69ff7a9d (patch)
treed636e3806cd5ecff71927d0300e46526fa23de1a /fs/btrfs/disk-io.c
parent4ce4cb526f67775c1cce3e3fa01c292672ba874e (diff)
Btrfs: Allow subvolumes and snapshots anywhere in the directory tree
Before, all snapshots and subvolumes lived in a single flat directory. This was awkward and confusing because the single flat directory was only writable with the ioctls. This commit changes the ioctls to create subvols and snapshots at any point in the directory tree. This requires making separate ioctls for snapshot and subvol creation instead of a combining them into one. The subvol ioctl does: btrfsctl -S subvol_name parent_dir After the ioctl is done subvol_name lives inside parent_dir. The snapshot ioctl does: btrfsctl -s path_for_snapshot root_to_snapshot path_for_snapshot can be an absolute or relative path. btrfsctl breaks it up into directory and basename components. root_to_snapshot can be any file or directory in the FS. The snapshot is taken of the entire root where that file lives. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 82833e5d84b6..0a5350573f61 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -838,7 +838,6 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
838 u64 objectid) 838 u64 objectid)
839{ 839{
840 root->node = NULL; 840 root->node = NULL;
841 root->inode = NULL;
842 root->commit_root = NULL; 841 root->commit_root = NULL;
843 root->ref_tree = NULL; 842 root->ref_tree = NULL;
844 root->sectorsize = sectorsize; 843 root->sectorsize = sectorsize;
@@ -1430,6 +1429,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1430 u32 blocksize; 1429 u32 blocksize;
1431 u32 stripesize; 1430 u32 stripesize;
1432 u64 generation; 1431 u64 generation;
1432 struct btrfs_key location;
1433 struct buffer_head *bh; 1433 struct buffer_head *bh;
1434 struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root), 1434 struct btrfs_root *extent_root = kzalloc(sizeof(struct btrfs_root),
1435 GFP_NOFS); 1435 GFP_NOFS);
@@ -1729,7 +1729,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1729 goto fail_cleaner; 1729 goto fail_cleaner;
1730 1730
1731 if (sb->s_flags & MS_RDONLY) 1731 if (sb->s_flags & MS_RDONLY)
1732 return tree_root; 1732 goto read_fs_root;
1733 1733
1734 if (btrfs_super_log_root(disk_super) != 0) { 1734 if (btrfs_super_log_root(disk_super) != 0) {
1735 u32 blocksize; 1735 u32 blocksize;
@@ -1755,6 +1755,14 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1755 ret = btrfs_cleanup_reloc_trees(tree_root); 1755 ret = btrfs_cleanup_reloc_trees(tree_root);
1756 BUG_ON(ret); 1756 BUG_ON(ret);
1757 1757
1758 location.objectid = BTRFS_FS_TREE_OBJECTID;
1759 location.type = BTRFS_ROOT_ITEM_KEY;
1760 location.offset = (u64)-1;
1761
1762read_fs_root:
1763 fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
1764 if (!fs_info->fs_root)
1765 goto fail_cleaner;
1758 return tree_root; 1766 return tree_root;
1759 1767
1760fail_cleaner: 1768fail_cleaner:
@@ -1944,8 +1952,6 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
1944 (unsigned long)root->root_key.objectid); 1952 (unsigned long)root->root_key.objectid);
1945 if (root->in_sysfs) 1953 if (root->in_sysfs)
1946 btrfs_sysfs_del_root(root); 1954 btrfs_sysfs_del_root(root);
1947 if (root->inode)
1948 iput(root->inode);
1949 if (root->node) 1955 if (root->node)
1950 free_extent_buffer(root->node); 1956 free_extent_buffer(root->node);
1951 if (root->commit_root) 1957 if (root->commit_root)