diff options
author | Josef Bacik <josef@redhat.com> | 2011-07-25 15:40:35 -0400 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2011-10-19 15:12:29 -0400 |
commit | ba5b8958dabbd7890a6929af1ffc0d87187765dc (patch) | |
tree | 5d4776506d38b5ac463147cae754ba0d6b6394c0 /fs/btrfs/super.c | |
parent | 0cbbdf7c9c46467bfb7129c30236f36a679ab244 (diff) | |
download | lwn-ba5b8958dabbd7890a6929af1ffc0d87187765dc.tar.gz lwn-ba5b8958dabbd7890a6929af1ffc0d87187765dc.zip |
Btrfs: use d_obtain_alias when mounting subvol/subvolid
Currently what we do is just wrong. We either
1) Alloc a new "root" dentry with sb->s_root as it's parent which is just wrong
as we could walk into this subvol later on via another path and hilarity could
ensue. Also we don't check the return value of d_splice_alias which isn't good
either.
or
2) Do a d_find_alias() which we could have lost our dentry from cache at this
point and found nothing.
So use d_obtain_alias(). In the case that we already have the inode/dentry in
cache we will get the correct dentry. If not we will get a disconnected dentry
tree so if we walk into it later on everything will be connected up properly.
Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 25 |
1 files changed, 1 insertions, 24 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 15634d4648d7..244fa46c50b8 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -492,7 +492,6 @@ static struct dentry *get_default_root(struct super_block *sb, struct btrfs_path *path; struct btrfs_key location; struct inode *inode; - struct dentry *dentry; u64 dir_id; int new = 0; @@ -566,29 +565,7 @@ setup_root: return dget(sb->s_root); } - if (new) { - const struct qstr name = { .name = "/", .len = 1 }; - - /* - * New inode, we need to make the dentry a sibling of s_root so - * everything gets cleaned up properly on unmount. - */ - dentry = d_alloc(sb->s_root, &name); - if (!dentry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } - d_splice_alias(inode, dentry); - } else { - /* - * We found the inode in cache, just find a dentry for it and - * put the reference to the inode we just got. - */ - dentry = d_find_alias(inode); - iput(inode); - } - - return dentry; + return d_obtain_alias(inode); } static int btrfs_fill_super(struct super_block *sb, |