aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-11-17 20:42:26 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-17 20:42:26 -0500
commit3394e1607eaf870ebba37d303fbd590a4c569908 (patch)
tree7833927ae6137122bea670544147be6a69f804ad /fs/btrfs/inode.c
parent3de4586c5278a28107030c336956381f69ff7a9d (diff)
Btrfs: Give each subvol and snapshot their own anonymous devid
Each subvolume has its own private inode number space, and so we need to fill in different device numbers for each subvolume to avoid confusing applications. This commit puts a struct super_block into struct btrfs_root so it can call set_anon_super() and get a different device number generated for each root. btrfs_rename is changed to prevent renames across subvols. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c15
1 files changed, 13 insertions, 2 deletions
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,