aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h6
-rw-r--r--fs/btrfs/disk-io.c13
-rw-r--r--fs/btrfs/inode.c15
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/transaction.c4
5 files changed, 34 insertions, 6 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5611f8e035a4..b3bc65b08c6a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -799,6 +799,12 @@ struct btrfs_root {
799 spinlock_t list_lock; 799 spinlock_t list_lock;
800 struct list_head dead_list; 800 struct list_head dead_list;
801 struct list_head orphan_list; 801 struct list_head orphan_list;
802
803 /*
804 * right now this just gets used so that a root has its own devid
805 * for stat. It may be used for more later
806 */
807 struct super_block anon_super;
802}; 808};
803 809
804/* 810/*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 0a5350573f61..8d7866b733d6 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -877,6 +877,12 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
877 root->defrag_running = 0; 877 root->defrag_running = 0;
878 root->defrag_level = 0; 878 root->defrag_level = 0;
879 root->root_key.objectid = objectid; 879 root->root_key.objectid = objectid;
880 root->anon_super.s_root = NULL;
881 root->anon_super.s_dev = 0;
882 INIT_LIST_HEAD(&root->anon_super.s_list);
883 INIT_LIST_HEAD(&root->anon_super.s_instances);
884 init_rwsem(&root->anon_super.s_umount);
885
880 return 0; 886 return 0;
881} 887}
882 888
@@ -1083,6 +1089,9 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
1083 root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); 1089 root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location);
1084 if (IS_ERR(root)) 1090 if (IS_ERR(root))
1085 return root; 1091 return root;
1092
1093 set_anon_super(&root->anon_super, NULL);
1094
1086 ret = radix_tree_insert(&fs_info->fs_roots_radix, 1095 ret = radix_tree_insert(&fs_info->fs_roots_radix,
1087 (unsigned long)root->root_key.objectid, 1096 (unsigned long)root->root_key.objectid,
1088 root); 1097 root);
@@ -1950,6 +1959,10 @@ int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
1950{ 1959{
1951 radix_tree_delete(&fs_info->fs_roots_radix, 1960 radix_tree_delete(&fs_info->fs_roots_radix,
1952 (unsigned long)root->root_key.objectid); 1961 (unsigned long)root->root_key.objectid);
1962 if (root->anon_super.s_dev) {
1963 down_write(&root->anon_super.s_umount);
1964 kill_anon_super(&root->anon_super);
1965 }
1953 if (root->in_sysfs) 1966 if (root->in_sysfs)
1954 btrfs_sysfs_del_root(root); 1967 btrfs_sysfs_del_root(root);
1955 if (root->node) 1968 if (root->node)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e163b1b74707..7ef79ce86e25 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2212,7 +2212,12 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
2212 struct btrfs_trans_handle *trans; 2212 struct btrfs_trans_handle *trans;
2213 unsigned long nr = 0; 2213 unsigned long nr = 0;
2214 2214
2215 if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) { 2215 /*
2216 * the FIRST_FREE_OBJECTID check makes sure we don't try to rmdir
2217 * the root of a subvolume or snapshot
2218 */
2219 if (inode->i_size > BTRFS_EMPTY_DIR_SIZE ||
2220 inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
2216 return -ENOTEMPTY; 2221 return -ENOTEMPTY;
2217 } 2222 }
2218 2223
@@ -4410,7 +4415,6 @@ int btrfs_create_subvol_root(struct btrfs_root *new_root, struct dentry *dentry,
4410 if (error) 4415 if (error)
4411 return error; 4416 return error;
4412 4417
4413 atomic_inc(&inode->i_count);
4414 d_instantiate(dentry, inode); 4418 d_instantiate(dentry, inode);
4415 return 0; 4419 return 0;
4416} 4420}
@@ -4548,6 +4552,7 @@ static int btrfs_getattr(struct vfsmount *mnt,
4548{ 4552{
4549 struct inode *inode = dentry->d_inode; 4553 struct inode *inode = dentry->d_inode;
4550 generic_fillattr(inode, stat); 4554 generic_fillattr(inode, stat);
4555 stat->dev = BTRFS_I(inode)->root->anon_super.s_dev;
4551 stat->blksize = PAGE_CACHE_SIZE; 4556 stat->blksize = PAGE_CACHE_SIZE;
4552 stat->blocks = (inode_get_bytes(inode) + 4557 stat->blocks = (inode_get_bytes(inode) +
4553 BTRFS_I(inode)->delalloc_bytes) >> 9; 4558 BTRFS_I(inode)->delalloc_bytes) >> 9;
@@ -4565,6 +4570,11 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
4565 u64 index = 0; 4570 u64 index = 0;
4566 int ret; 4571 int ret;
4567 4572
4573 /* we're not allowed to rename between subvolumes */
4574 if (BTRFS_I(old_inode)->root->root_key.objectid !=
4575 BTRFS_I(new_dir)->root->root_key.objectid)
4576 return -EXDEV;
4577
4568 if (S_ISDIR(old_inode->i_mode) && new_inode && 4578 if (S_ISDIR(old_inode->i_mode) && new_inode &&
4569 new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) { 4579 new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) {
4570 return -ENOTEMPTY; 4580 return -ENOTEMPTY;
@@ -4920,6 +4930,7 @@ static int btrfs_permission(struct inode *inode, int mask)
4920} 4930}
4921 4931
4922static struct inode_operations btrfs_dir_inode_operations = { 4932static struct inode_operations btrfs_dir_inode_operations = {
4933 .getattr = btrfs_getattr,
4923 .lookup = btrfs_lookup, 4934 .lookup = btrfs_lookup,
4924 .create = btrfs_create, 4935 .create = btrfs_create,
4925 .unlink = btrfs_unlink, 4936 .unlink = btrfs_unlink,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index ec45b3086136..773db07b5f72 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -127,7 +127,6 @@ static noinline int create_subvol(struct btrfs_root *root,
127 key.objectid = objectid; 127 key.objectid = objectid;
128 key.offset = 1; 128 key.offset = 1;
129 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);
131 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, 130 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
132 &root_item); 131 &root_item);
133 if (ret) 132 if (ret)
@@ -175,7 +174,6 @@ fail:
175 ret = err; 174 ret = err;
176fail_commit: 175fail_commit:
177 btrfs_btree_balance_dirty(root, nr); 176 btrfs_btree_balance_dirty(root, nr);
178printk("all done ret %d\n", ret);
179 return ret; 177 return ret;
180} 178}
181 179
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index eec8b2465039..93f23a456a36 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -832,13 +832,13 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
832 struct inode *parent_inode; 832 struct inode *parent_inode;
833 struct inode *inode; 833 struct inode *inode;
834 834
835 trans = btrfs_start_transaction(fs_info->fs_root, 1); 835 parent_inode = pending->dentry->d_parent->d_inode;
836 trans = btrfs_start_transaction(BTRFS_I(parent_inode)->root, 1);
836 837
837 /* 838 /*
838 * insert the directory item 839 * insert the directory item
839 */ 840 */
840 namelen = strlen(pending->name); 841 namelen = strlen(pending->name);
841 parent_inode = pending->dentry->d_parent->d_inode;
842 ret = btrfs_set_inode_index(parent_inode, &index); 842 ret = btrfs_set_inode_index(parent_inode, &index);
843 ret = btrfs_insert_dir_item(trans, 843 ret = btrfs_insert_dir_item(trans,
844 BTRFS_I(parent_inode)->root, 844 BTRFS_I(parent_inode)->root,