aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2009-12-04 12:38:27 -0500
committerChris Mason <chris.mason@oracle.com>2010-03-15 10:58:13 -0400
commit73f73415caddbc01d9f10c03e0a677d5b3d11569 (patch)
tree249ef103a73e8d99efe409b7988b694537b3d6ad /fs/btrfs/inode.c
parent12534832cb7b0abc7369298246e8b7af03b863ca (diff)
Btrfs: change how we mount subvolumes
This work is in preperation for being able to set a different root as the default mounting root. There is currently a problem with how we mount subvolumes. We cannot currently mount a subvolume of a subvolume, you can only mount subvolumes/snapshots of the default subvolume. So say you take a snapshot of the default subvolume and call it snap1, and then take a snapshot of snap1 and call it snap2, so now you have / /snap1 /snap1/snap2 as your available volumes. Currently you can only mount / and /snap1, you cannot mount /snap1/snap2. To fix this problem instead of passing subvolid=<name> you must pass in subvolid=<treeid>, where <treeid> is the tree id that gets spit out via the subvolume listing you get from the subvolume listing patches (btrfs filesystem list). This allows us to mount /, /snap1 and /snap1/snap2 as the root volume. In addition to the above, we also now read the default dir item in the tree root to get the root key that it points to. For now this just points at what has always been the default subvolme, but later on I plan to change it to point at whatever root you want to be the new default root, so you can just set the default mount and not have to mount with -o subvolid=<treeid>. I tested this out with the above scenario and it worked perfectly. Thanks, mount -o subvol operates inside the selected subvolid. For example: mount -o subvol=snap1,subvolid=256 /dev/xxx /mnt /mnt will have the snap1 directory for the subvolume with id 256. mount -o subvol=snap /dev/xxx /mnt /mnt will be the snap directory of whatever the default subvolume is. Signed-off-by: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 4deb280f8969..7d10d1ccb0fe 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2153,7 +2153,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
2153 found_key.objectid = found_key.offset; 2153 found_key.objectid = found_key.offset;
2154 found_key.type = BTRFS_INODE_ITEM_KEY; 2154 found_key.type = BTRFS_INODE_ITEM_KEY;
2155 found_key.offset = 0; 2155 found_key.offset = 0;
2156 inode = btrfs_iget(root->fs_info->sb, &found_key, root); 2156 inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
2157 if (IS_ERR(inode)) 2157 if (IS_ERR(inode))
2158 break; 2158 break;
2159 2159
@@ -3687,7 +3687,7 @@ static struct inode *btrfs_iget_locked(struct super_block *s,
3687 * Returns in *is_new if the inode was read from disk 3687 * Returns in *is_new if the inode was read from disk
3688 */ 3688 */
3689struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, 3689struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3690 struct btrfs_root *root) 3690 struct btrfs_root *root, int *new)
3691{ 3691{
3692 struct inode *inode; 3692 struct inode *inode;
3693 3693
@@ -3702,6 +3702,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
3702 3702
3703 inode_tree_add(inode); 3703 inode_tree_add(inode);
3704 unlock_new_inode(inode); 3704 unlock_new_inode(inode);
3705 if (new)
3706 *new = 1;
3705 } 3707 }
3706 3708
3707 return inode; 3709 return inode;
@@ -3754,7 +3756,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
3754 return NULL; 3756 return NULL;
3755 3757
3756 if (location.type == BTRFS_INODE_ITEM_KEY) { 3758 if (location.type == BTRFS_INODE_ITEM_KEY) {
3757 inode = btrfs_iget(dir->i_sb, &location, root); 3759 inode = btrfs_iget(dir->i_sb, &location, root, NULL);
3758 return inode; 3760 return inode;
3759 } 3761 }
3760 3762
@@ -3769,7 +3771,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
3769 else 3771 else
3770 inode = new_simple_dir(dir->i_sb, &location, sub_root); 3772 inode = new_simple_dir(dir->i_sb, &location, sub_root);
3771 } else { 3773 } else {
3772 inode = btrfs_iget(dir->i_sb, &location, sub_root); 3774 inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL);
3773 } 3775 }
3774 srcu_read_unlock(&root->fs_info->subvol_srcu, index); 3776 srcu_read_unlock(&root->fs_info->subvol_srcu, index);
3775 3777