diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 13 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 15 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 4 |
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 | ||
4922 | static struct inode_operations btrfs_dir_inode_operations = { | 4932 | static 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); |
130 | printk("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; |
176 | fail_commit: | 175 | fail_commit: |
177 | btrfs_btree_balance_dirty(root, nr); | 176 | btrfs_btree_balance_dirty(root, nr); |
178 | printk("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, |