aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/btrfs/ctree.h7
-rw-r--r--fs/btrfs/disk-io.c14
-rw-r--r--fs/btrfs/inode.c50
-rw-r--r--fs/btrfs/ioctl.c71
-rw-r--r--fs/btrfs/ioctl.h7
-rw-r--r--fs/btrfs/super.c10
-rw-r--r--fs/btrfs/transaction.c66
-rw-r--r--fs/btrfs/transaction.h2
8 files changed, 162 insertions, 65 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5ff74282a620..5611f8e035a4 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -606,6 +606,7 @@ struct btrfs_fs_info {
606 struct btrfs_root *tree_root; 606 struct btrfs_root *tree_root;
607 struct btrfs_root *chunk_root; 607 struct btrfs_root *chunk_root;
608 struct btrfs_root *dev_root; 608 struct btrfs_root *dev_root;
609 struct btrfs_root *fs_root;
609 610
610 /* the log root tree is a directory of all the other log roots */ 611 /* the log root tree is a directory of all the other log roots */
611 struct btrfs_root *log_root_tree; 612 struct btrfs_root *log_root_tree;
@@ -758,7 +759,6 @@ struct btrfs_root {
758 struct btrfs_root_item root_item; 759 struct btrfs_root_item root_item;
759 struct btrfs_key root_key; 760 struct btrfs_key root_key;
760 struct btrfs_fs_info *fs_info; 761 struct btrfs_fs_info *fs_info;
761 struct inode *inode;
762 struct extent_io_tree dirty_log_pages; 762 struct extent_io_tree dirty_log_pages;
763 763
764 struct kobject root_kobj; 764 struct kobject root_kobj;
@@ -1876,6 +1876,8 @@ int btrfs_csum_truncate(struct btrfs_trans_handle *trans,
1876#define PageChecked PageFsMisc 1876#define PageChecked PageFsMisc
1877#endif 1877#endif
1878 1878
1879struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry);
1880int btrfs_set_inode_index(struct inode *dir, u64 *index);
1879int btrfs_unlink_inode(struct btrfs_trans_handle *trans, 1881int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
1880 struct btrfs_root *root, 1882 struct btrfs_root *root,
1881 struct inode *dir, struct inode *inode, 1883 struct inode *dir, struct inode *inode,
@@ -1896,9 +1898,6 @@ int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry,
1896 struct btrfs_trans_handle *trans, u64 new_dirid, 1898 struct btrfs_trans_handle *trans, u64 new_dirid,
1897 struct btrfs_block_group_cache *block_group); 1899 struct btrfs_block_group_cache *block_group);
1898 1900
1899void btrfs_invalidate_dcache_root(struct btrfs_root *root, char *name,
1900 int namelen);
1901
1902int btrfs_merge_bio_hook(struct page *page, unsigned long offset, 1901int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
1903 size_t size, struct bio *bio, unsigned long bio_flags); 1902 size_t size, struct bio *bio, unsigned long bio_flags);
1904 1903
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)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3e3620e69bb9..e163b1b74707 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3038,8 +3038,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3038 return inode; 3038 return inode;
3039} 3039}
3040 3040
3041static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, 3041struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
3042 struct nameidata *nd)
3043{ 3042{
3044 struct inode * inode; 3043 struct inode * inode;
3045 struct btrfs_inode *bi = BTRFS_I(dir); 3044 struct btrfs_inode *bi = BTRFS_I(dir);
@@ -3067,13 +3066,21 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
3067 inode = btrfs_iget(dir->i_sb, &location, sub_root, &new); 3066 inode = btrfs_iget(dir->i_sb, &location, sub_root, &new);
3068 if (IS_ERR(inode)) 3067 if (IS_ERR(inode))
3069 return ERR_CAST(inode); 3068 return ERR_CAST(inode);
3070
3071 /* the inode and parent dir are two different roots */
3072 if (new && root != sub_root) {
3073 igrab(inode);
3074 sub_root->inode = inode;
3075 }
3076 } 3069 }
3070 return inode;
3071}
3072
3073static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
3074 struct nameidata *nd)
3075{
3076 struct inode *inode;
3077
3078 if (dentry->d_name.len > BTRFS_NAME_LEN)
3079 return ERR_PTR(-ENAMETOOLONG);
3080
3081 inode = btrfs_lookup_dentry(dir, dentry);
3082 if (IS_ERR(inode))
3083 return ERR_CAST(inode);
3077 3084
3078 return d_splice_alias(inode, dentry); 3085 return d_splice_alias(inode, dentry);
3079} 3086}
@@ -3129,7 +3136,6 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
3129 return 0; 3136 return 0;
3130 filp->f_pos = 2; 3137 filp->f_pos = 2;
3131 } 3138 }
3132
3133 path = btrfs_alloc_path(); 3139 path = btrfs_alloc_path();
3134 path->reada = 2; 3140 path->reada = 2;
3135 3141
@@ -3159,6 +3165,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
3159 path->slots[0]++; 3165 path->slots[0]++;
3160 } 3166 }
3161 } 3167 }
3168
3162 advance = 1; 3169 advance = 1;
3163 item = btrfs_item_nr(leaf, slot); 3170 item = btrfs_item_nr(leaf, slot);
3164 btrfs_item_key_to_cpu(leaf, &found_key, slot); 3171 btrfs_item_key_to_cpu(leaf, &found_key, slot);
@@ -3194,16 +3201,25 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
3194 3201
3195 d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; 3202 d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
3196 btrfs_dir_item_key_to_cpu(leaf, di, &location); 3203 btrfs_dir_item_key_to_cpu(leaf, di, &location);
3204
3205 /* is this a reference to our own snapshot? If so
3206 * skip it
3207 */
3208 if (location.type == BTRFS_ROOT_ITEM_KEY &&
3209 location.objectid == root->root_key.objectid) {
3210 over = 0;
3211 goto skip;
3212 }
3197 over = filldir(dirent, name_ptr, name_len, 3213 over = filldir(dirent, name_ptr, name_len,
3198 found_key.offset, location.objectid, 3214 found_key.offset, location.objectid,
3199 d_type); 3215 d_type);
3200 3216
3217skip:
3201 if (name_ptr != tmp_name) 3218 if (name_ptr != tmp_name)
3202 kfree(name_ptr); 3219 kfree(name_ptr);
3203 3220
3204 if (over) 3221 if (over)
3205 goto nopos; 3222 goto nopos;
3206
3207 di_len = btrfs_dir_name_len(leaf, di) + 3223 di_len = btrfs_dir_name_len(leaf, di) +
3208 btrfs_dir_data_len(leaf, di) + sizeof(*di); 3224 btrfs_dir_data_len(leaf, di) + sizeof(*di);
3209 di_cur += di_len; 3225 di_cur += di_len;
@@ -3318,8 +3334,7 @@ out:
3318 * helper to find a free sequence number in a given directory. This current 3334 * helper to find a free sequence number in a given directory. This current
3319 * code is very simple, later versions will do smarter things in the btree 3335 * code is very simple, later versions will do smarter things in the btree
3320 */ 3336 */
3321static int btrfs_set_inode_index(struct inode *dir, struct inode *inode, 3337int btrfs_set_inode_index(struct inode *dir, u64 *index)
3322 u64 *index)
3323{ 3338{
3324 int ret = 0; 3339 int ret = 0;
3325 3340
@@ -3365,7 +3380,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3365 return ERR_PTR(-ENOMEM); 3380 return ERR_PTR(-ENOMEM);
3366 3381
3367 if (dir) { 3382 if (dir) {
3368 ret = btrfs_set_inode_index(dir, inode, index); 3383 ret = btrfs_set_inode_index(dir, index);
3369 if (ret) 3384 if (ret)
3370 return ERR_PTR(ret); 3385 return ERR_PTR(ret);
3371 } 3386 }
@@ -3651,7 +3666,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
3651 err = btrfs_check_free_space(root, 1, 0); 3666 err = btrfs_check_free_space(root, 1, 0);
3652 if (err) 3667 if (err)
3653 goto fail; 3668 goto fail;
3654 err = btrfs_set_inode_index(dir, inode, &index); 3669 err = btrfs_set_inode_index(dir, &index);
3655 if (err) 3670 if (err)
3656 goto fail; 3671 goto fail;
3657 3672
@@ -4349,13 +4364,13 @@ out:
4349 * Invalidate a single dcache entry at the root of the filesystem. 4364 * Invalidate a single dcache entry at the root of the filesystem.
4350 * Needed after creation of snapshot or subvolume. 4365 * Needed after creation of snapshot or subvolume.
4351 */ 4366 */
4352void btrfs_invalidate_dcache_root(struct btrfs_root *root, char *name, 4367void btrfs_invalidate_dcache_root(struct inode *dir, char *name,
4353 int namelen) 4368 int namelen)
4354{ 4369{
4355 struct dentry *alias, *entry; 4370 struct dentry *alias, *entry;
4356 struct qstr qstr; 4371 struct qstr qstr;
4357 4372
4358 alias = d_find_alias(root->fs_info->sb->s_root->d_inode); 4373 alias = d_find_alias(dir);
4359 if (alias) { 4374 if (alias) {
4360 qstr.name = name; 4375 qstr.name = name;
4361 qstr.len = namelen; 4376 qstr.len = namelen;
@@ -4387,7 +4402,6 @@ int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry,
4387 return PTR_ERR(inode); 4402 return PTR_ERR(inode);
4388 inode->i_op = &btrfs_dir_inode_operations; 4403 inode->i_op = &btrfs_dir_inode_operations;
4389 inode->i_fop = &btrfs_dir_file_operations; 4404 inode->i_fop = &btrfs_dir_file_operations;
4390 new_root->inode = inode;
4391 4405
4392 inode->i_nlink = 1; 4406 inode->i_nlink = 1;
4393 btrfs_i_size_write(inode, 0); 4407 btrfs_i_size_write(inode, 0);
@@ -4590,7 +4604,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
4590 } 4604 }
4591 4605
4592 } 4606 }
4593 ret = btrfs_set_inode_index(new_dir, old_inode, &index); 4607 ret = btrfs_set_inode_index(new_dir, &index);
4594 if (ret) 4608 if (ret)
4595 goto out_fail; 4609 goto out_fail;
4596 4610
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f43df72b0e17..ec45b3086136 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -67,6 +67,7 @@ static noinline int create_subvol(struct btrfs_root *root,
67 int err; 67 int err;
68 u64 objectid; 68 u64 objectid;
69 u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID; 69 u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID;
70 u64 index = 0;
70 unsigned long nr = 1; 71 unsigned long nr = 1;
71 72
72 ret = btrfs_check_free_space(root, 1, 0); 73 ret = btrfs_check_free_space(root, 1, 0);
@@ -126,6 +127,7 @@ static noinline int create_subvol(struct btrfs_root *root,
126 key.objectid = objectid; 127 key.objectid = objectid;
127 key.offset = 1; 128 key.offset = 1;
128 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); 129 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
130printk("inserting root objectid %Lu\n", objectid);
129 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, 131 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
130 &root_item); 132 &root_item);
131 if (ret) 133 if (ret)
@@ -135,24 +137,27 @@ static noinline int create_subvol(struct btrfs_root *root,
135 * insert the directory item 137 * insert the directory item
136 */ 138 */
137 key.offset = (u64)-1; 139 key.offset = (u64)-1;
138 dir = root->fs_info->sb->s_root->d_inode; 140 dir = dentry->d_parent->d_inode;
139 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, 141 ret = btrfs_set_inode_index(dir, &index);
142 BUG_ON(ret);
143
144 ret = btrfs_insert_dir_item(trans, root,
140 name, namelen, dir->i_ino, &key, 145 name, namelen, dir->i_ino, &key,
141 BTRFS_FT_DIR, 0); 146 BTRFS_FT_DIR, index);
142 if (ret) 147 if (ret)
143 goto fail; 148 goto fail;
144 149#if 0
145 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root, 150 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root,
146 name, namelen, objectid, 151 name, namelen, objectid,
147 root->fs_info->sb->s_root->d_inode->i_ino, 0); 152 root->fs_info->sb->s_root->d_inode->i_ino, 0);
148 if (ret) 153 if (ret)
149 goto fail; 154 goto fail;
150 155#endif
151 ret = btrfs_commit_transaction(trans, root); 156 ret = btrfs_commit_transaction(trans, root);
152 if (ret) 157 if (ret)
153 goto fail_commit; 158 goto fail_commit;
154 159
155 new_root = btrfs_read_fs_root(root->fs_info, &key, name, namelen); 160 new_root = btrfs_read_fs_root_no_name(root->fs_info, &key);
156 BUG_ON(!new_root); 161 BUG_ON(!new_root);
157 162
158 trans = btrfs_start_transaction(new_root, 1); 163 trans = btrfs_start_transaction(new_root, 1);
@@ -170,14 +175,16 @@ fail:
170 ret = err; 175 ret = err;
171fail_commit: 176fail_commit:
172 btrfs_btree_balance_dirty(root, nr); 177 btrfs_btree_balance_dirty(root, nr);
178printk("all done ret %d\n", ret);
173 return ret; 179 return ret;
174} 180}
175 181
176static int create_snapshot(struct btrfs_root *root, char *name, int namelen) 182static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
183 char *name, int namelen)
177{ 184{
178 struct btrfs_pending_snapshot *pending_snapshot; 185 struct btrfs_pending_snapshot *pending_snapshot;
179 struct btrfs_trans_handle *trans; 186 struct btrfs_trans_handle *trans;
180 int ret; 187 int ret = 0;
181 int err; 188 int err;
182 unsigned long nr = 0; 189 unsigned long nr = 0;
183 190
@@ -188,7 +195,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
188 if (ret) 195 if (ret)
189 goto fail_unlock; 196 goto fail_unlock;
190 197
191 pending_snapshot = kmalloc(sizeof(*pending_snapshot), GFP_NOFS); 198 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
192 if (!pending_snapshot) { 199 if (!pending_snapshot) {
193 ret = -ENOMEM; 200 ret = -ENOMEM;
194 goto fail_unlock; 201 goto fail_unlock;
@@ -201,12 +208,12 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
201 } 208 }
202 memcpy(pending_snapshot->name, name, namelen); 209 memcpy(pending_snapshot->name, name, namelen);
203 pending_snapshot->name[namelen] = '\0'; 210 pending_snapshot->name[namelen] = '\0';
211 pending_snapshot->dentry = dentry;
204 trans = btrfs_start_transaction(root, 1); 212 trans = btrfs_start_transaction(root, 1);
205 BUG_ON(!trans); 213 BUG_ON(!trans);
206 pending_snapshot->root = root; 214 pending_snapshot->root = root;
207 list_add(&pending_snapshot->list, 215 list_add(&pending_snapshot->list,
208 &trans->transaction->pending_snapshots); 216 &trans->transaction->pending_snapshots);
209 ret = btrfs_update_inode(trans, root, root->inode);
210 err = btrfs_commit_transaction(trans, root); 217 err = btrfs_commit_transaction(trans, root);
211 218
212fail_unlock: 219fail_unlock:
@@ -230,7 +237,8 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child)
230 * inside this filesystem so it's quite a bit simpler. 237 * inside this filesystem so it's quite a bit simpler.
231 */ 238 */
232static noinline int btrfs_mksubvol(struct path *parent, char *name, 239static noinline int btrfs_mksubvol(struct path *parent, char *name,
233 int mode, int namelen) 240 int mode, int namelen,
241 struct btrfs_root *snap_src)
234{ 242{
235 struct dentry *dentry; 243 struct dentry *dentry;
236 int error; 244 int error;
@@ -248,6 +256,7 @@ static noinline int btrfs_mksubvol(struct path *parent, char *name,
248 256
249 if (!IS_POSIXACL(parent->dentry->d_inode)) 257 if (!IS_POSIXACL(parent->dentry->d_inode))
250 mode &= ~current->fs->umask; 258 mode &= ~current->fs->umask;
259
251 error = mnt_want_write(parent->mnt); 260 error = mnt_want_write(parent->mnt);
252 if (error) 261 if (error)
253 goto out_dput; 262 goto out_dput;
@@ -266,8 +275,12 @@ static noinline int btrfs_mksubvol(struct path *parent, char *name,
266 * Also we should pass on the mode eventually to allow creating new 275 * Also we should pass on the mode eventually to allow creating new
267 * subvolume with specific mode bits. 276 * subvolume with specific mode bits.
268 */ 277 */
269 error = create_subvol(BTRFS_I(parent->dentry->d_inode)->root, dentry, 278 if (snap_src) {
270 name, namelen); 279 error = create_snapshot(snap_src, dentry, name, namelen);
280 } else {
281 error = create_subvol(BTRFS_I(parent->dentry->d_inode)->root,
282 dentry, name, namelen);
283 }
271 if (error) 284 if (error)
272 goto out_drop_write; 285 goto out_drop_write;
273 286
@@ -471,15 +484,16 @@ out:
471} 484}
472 485
473static noinline int btrfs_ioctl_snap_create(struct file *file, 486static noinline int btrfs_ioctl_snap_create(struct file *file,
474 void __user *arg) 487 void __user *arg, int subvol)
475{ 488{
476 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; 489 struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root;
477 struct btrfs_ioctl_vol_args *vol_args; 490 struct btrfs_ioctl_vol_args *vol_args;
478 struct btrfs_dir_item *di; 491 struct btrfs_dir_item *di;
479 struct btrfs_path *path; 492 struct btrfs_path *path;
493 struct file *src_file;
480 u64 root_dirid; 494 u64 root_dirid;
481 int namelen; 495 int namelen;
482 int ret; 496 int ret = 0;
483 497
484 if (root->fs_info->sb->s_flags & MS_RDONLY) 498 if (root->fs_info->sb->s_flags & MS_RDONLY)
485 return -EROFS; 499 return -EROFS;
@@ -523,12 +537,29 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
523 goto out; 537 goto out;
524 } 538 }
525 539
526 if (root == root->fs_info->tree_root) { 540 if (subvol) {
527 ret = btrfs_mksubvol(&file->f_path, vol_args->name, 541 ret = btrfs_mksubvol(&file->f_path, vol_args->name,
528 file->f_path.dentry->d_inode->i_mode, 542 file->f_path.dentry->d_inode->i_mode,
529 namelen); 543 namelen, NULL);
530 } else { 544 } else {
531 ret = create_snapshot(root, vol_args->name, namelen); 545 struct inode *src_inode;
546 src_file = fget(vol_args->fd);
547 if (!src_file) {
548 ret = -EINVAL;
549 goto out;
550 }
551
552 src_inode = src_file->f_path.dentry->d_inode;
553 if (src_inode->i_sb != file->f_path.dentry->d_inode->i_sb) {
554 printk("btrfs: Snapshot src from another FS\n");
555 ret = -EINVAL;
556 fput(src_file);
557 goto out;
558 }
559 ret = btrfs_mksubvol(&file->f_path, vol_args->name,
560 file->f_path.dentry->d_inode->i_mode,
561 namelen, BTRFS_I(src_inode)->root);
562 fput(src_file);
532 } 563 }
533 564
534out: 565out:
@@ -1030,7 +1061,9 @@ long btrfs_ioctl(struct file *file, unsigned int
1030 1061
1031 switch (cmd) { 1062 switch (cmd) {
1032 case BTRFS_IOC_SNAP_CREATE: 1063 case BTRFS_IOC_SNAP_CREATE:
1033 return btrfs_ioctl_snap_create(file, (void __user *)arg); 1064 return btrfs_ioctl_snap_create(file, (void __user *)arg, 0);
1065 case BTRFS_IOC_SUBVOL_CREATE:
1066 return btrfs_ioctl_snap_create(file, (void __user *)arg, 1);
1034 case BTRFS_IOC_DEFRAG: 1067 case BTRFS_IOC_DEFRAG:
1035 return btrfs_ioctl_defrag(file); 1068 return btrfs_ioctl_defrag(file);
1036 case BTRFS_IOC_RESIZE: 1069 case BTRFS_IOC_RESIZE:
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h
index 989ba8a01215..78049ea208db 100644
--- a/fs/btrfs/ioctl.h
+++ b/fs/btrfs/ioctl.h
@@ -22,9 +22,10 @@
22 22
23#define BTRFS_IOCTL_MAGIC 0x94 23#define BTRFS_IOCTL_MAGIC 0x94
24#define BTRFS_VOL_NAME_MAX 255 24#define BTRFS_VOL_NAME_MAX 255
25#define BTRFS_PATH_NAME_MAX 4095 25#define BTRFS_PATH_NAME_MAX 3072
26 26
27struct btrfs_ioctl_vol_args { 27struct btrfs_ioctl_vol_args {
28 __s64 fd;
28 char name[BTRFS_PATH_NAME_MAX + 1]; 29 char name[BTRFS_PATH_NAME_MAX + 1];
29}; 30};
30 31
@@ -51,7 +52,6 @@ struct btrfs_ioctl_vol_args {
51 struct btrfs_ioctl_vol_args) 52 struct btrfs_ioctl_vol_args)
52#define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \ 53#define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \
53 struct btrfs_ioctl_vol_args) 54 struct btrfs_ioctl_vol_args)
54
55struct btrfs_ioctl_clone_range_args { 55struct btrfs_ioctl_clone_range_args {
56 __s64 src_fd; 56 __s64 src_fd;
57 __u64 src_offset, src_length; 57 __u64 src_offset, src_length;
@@ -61,4 +61,7 @@ struct btrfs_ioctl_clone_range_args {
61#define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \ 61#define BTRFS_IOC_CLONE_RANGE _IOW(BTRFS_IOCTL_MAGIC, 13, \
62 struct btrfs_ioctl_clone_range_args) 62 struct btrfs_ioctl_clone_range_args)
63 63
64#define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \
65 struct btrfs_ioctl_vol_args)
66
64#endif 67#endif
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 92393cc60d08..77c5eff3e209 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -285,11 +285,11 @@ static int btrfs_parse_early_options(const char *options, int flags,
285 out: 285 out:
286 /* 286 /*
287 * If no subvolume name is specified we use the default one. Allocate 287 * If no subvolume name is specified we use the default one. Allocate
288 * a copy of the string "default" here so that code later in the 288 * a copy of the string "." here so that code later in the
289 * mount path doesn't care if it's the default volume or another one. 289 * mount path doesn't care if it's the default volume or another one.
290 */ 290 */
291 if (!*subvol_name) { 291 if (!*subvol_name) {
292 *subvol_name = kstrdup("default", GFP_KERNEL); 292 *subvol_name = kstrdup(".", GFP_KERNEL);
293 if (!*subvol_name) 293 if (!*subvol_name)
294 return -ENOMEM; 294 return -ENOMEM;
295 } 295 }
@@ -323,12 +323,12 @@ static int btrfs_fill_super(struct super_block * sb,
323 } 323 }
324 sb->s_fs_info = tree_root; 324 sb->s_fs_info = tree_root;
325 disk_super = &tree_root->fs_info->super_copy; 325 disk_super = &tree_root->fs_info->super_copy;
326 inode = btrfs_iget_locked(sb, btrfs_super_root_dir(disk_super), 326 inode = btrfs_iget_locked(sb, BTRFS_FIRST_FREE_OBJECTID,
327 tree_root); 327 tree_root->fs_info->fs_root);
328 bi = BTRFS_I(inode); 328 bi = BTRFS_I(inode);
329 bi->location.objectid = inode->i_ino; 329 bi->location.objectid = inode->i_ino;
330 bi->location.offset = 0; 330 bi->location.offset = 0;
331 bi->root = tree_root; 331 bi->root = tree_root->fs_info->fs_root;
332 332
333 btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY); 333 btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY);
334 334
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 202c1b6df4a4..eec8b2465039 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -779,7 +779,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
779 struct extent_buffer *tmp; 779 struct extent_buffer *tmp;
780 struct extent_buffer *old; 780 struct extent_buffer *old;
781 int ret; 781 int ret;
782 int namelen;
783 u64 objectid; 782 u64 objectid;
784 783
785 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 784 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
@@ -816,28 +815,48 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
816 if (ret) 815 if (ret)
817 goto fail; 816 goto fail;
818 817
818 key.offset = (u64)-1;
819 memcpy(&pending->root_key, &key, sizeof(key));
820fail:
821 kfree(new_root_item);
822 return ret;
823}
824
825static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
826 struct btrfs_pending_snapshot *pending)
827{
828 int ret;
829 int namelen;
830 u64 index = 0;
831 struct btrfs_trans_handle *trans;
832 struct inode *parent_inode;
833 struct inode *inode;
834
835 trans = btrfs_start_transaction(fs_info->fs_root, 1);
836
819 /* 837 /*
820 * insert the directory item 838 * insert the directory item
821 */ 839 */
822 key.offset = (u64)-1;
823 namelen = strlen(pending->name); 840 namelen = strlen(pending->name);
824 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, 841 parent_inode = pending->dentry->d_parent->d_inode;
825 pending->name, namelen, 842 ret = btrfs_set_inode_index(parent_inode, &index);
826 root->fs_info->sb->s_root->d_inode->i_ino, 843 ret = btrfs_insert_dir_item(trans,
827 &key, BTRFS_FT_DIR, 0); 844 BTRFS_I(parent_inode)->root,
845 pending->name, namelen,
846 parent_inode->i_ino,
847 &pending->root_key, BTRFS_FT_DIR, index);
828 848
829 if (ret) 849 if (ret)
830 goto fail; 850 goto fail;
831 851#if 0
832 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root, 852 ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root,
833 pending->name, strlen(pending->name), objectid, 853 pending->name, strlen(pending->name), objectid,
834 root->fs_info->sb->s_root->d_inode->i_ino, 0); 854 root->fs_info->sb->s_root->d_inode->i_ino, 0);
835 855#endif
836 /* Invalidate existing dcache entry for new snapshot. */ 856 inode = btrfs_lookup_dentry(parent_inode, pending->dentry);
837 btrfs_invalidate_dcache_root(root, pending->name, namelen); 857 d_instantiate(pending->dentry, inode);
838
839fail: 858fail:
840 kfree(new_root_item); 859 btrfs_end_transaction(trans, fs_info->fs_root);
841 return ret; 860 return ret;
842} 861}
843 862
@@ -849,12 +868,28 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
849{ 868{
850 struct btrfs_pending_snapshot *pending; 869 struct btrfs_pending_snapshot *pending;
851 struct list_head *head = &trans->transaction->pending_snapshots; 870 struct list_head *head = &trans->transaction->pending_snapshots;
871 struct list_head *cur;
872 int ret;
873
874 list_for_each(cur, head) {
875 pending = list_entry(cur, struct btrfs_pending_snapshot, list);
876 ret = create_pending_snapshot(trans, fs_info, pending);
877 BUG_ON(ret);
878 }
879 return 0;
880}
881
882static noinline int finish_pending_snapshots(struct btrfs_trans_handle *trans,
883 struct btrfs_fs_info *fs_info)
884{
885 struct btrfs_pending_snapshot *pending;
886 struct list_head *head = &trans->transaction->pending_snapshots;
852 int ret; 887 int ret;
853 888
854 while(!list_empty(head)) { 889 while(!list_empty(head)) {
855 pending = list_entry(head->next, 890 pending = list_entry(head->next,
856 struct btrfs_pending_snapshot, list); 891 struct btrfs_pending_snapshot, list);
857 ret = create_pending_snapshot(trans, fs_info, pending); 892 ret = finish_pending_snapshot(fs_info, pending);
858 BUG_ON(ret); 893 BUG_ON(ret);
859 list_del(&pending->list); 894 list_del(&pending->list);
860 kfree(pending->name); 895 kfree(pending->name);
@@ -1033,11 +1068,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1033 btrfs_drop_dead_reloc_roots(root); 1068 btrfs_drop_dead_reloc_roots(root);
1034 mutex_unlock(&root->fs_info->tree_reloc_mutex); 1069 mutex_unlock(&root->fs_info->tree_reloc_mutex);
1035 1070
1071 /* do the directory inserts of any pending snapshot creations */
1072 finish_pending_snapshots(trans, root->fs_info);
1073
1036 mutex_lock(&root->fs_info->trans_mutex); 1074 mutex_lock(&root->fs_info->trans_mutex);
1037 1075
1038 cur_trans->commit_done = 1; 1076 cur_trans->commit_done = 1;
1039 root->fs_info->last_trans_committed = cur_trans->transid; 1077 root->fs_info->last_trans_committed = cur_trans->transid;
1040 wake_up(&cur_trans->commit_wait); 1078 wake_up(&cur_trans->commit_wait);
1079
1041 put_transaction(cur_trans); 1080 put_transaction(cur_trans);
1042 put_transaction(cur_trans); 1081 put_transaction(cur_trans);
1043 1082
@@ -1046,6 +1085,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1046 list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots); 1085 list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots);
1047 1086
1048 mutex_unlock(&root->fs_info->trans_mutex); 1087 mutex_unlock(&root->fs_info->trans_mutex);
1088
1049 kmem_cache_free(btrfs_trans_handle_cachep, trans); 1089 kmem_cache_free(btrfs_trans_handle_cachep, trans);
1050 1090
1051 if (root->fs_info->closing) { 1091 if (root->fs_info->closing) {
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index eef2cb7d7e78..202c8be6c05d 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -47,8 +47,10 @@ struct btrfs_trans_handle {
47}; 47};
48 48
49struct btrfs_pending_snapshot { 49struct btrfs_pending_snapshot {
50 struct dentry *dentry;
50 struct btrfs_root *root; 51 struct btrfs_root *root;
51 char *name; 52 char *name;
53 struct btrfs_key root_key;
52 struct list_head list; 54 struct list_head list;
53}; 55};
54 56