aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-07-25 15:40:35 -0400
committerJosef Bacik <josef@redhat.com>2011-10-19 15:12:29 -0400
commitba5b8958dabbd7890a6929af1ffc0d87187765dc (patch)
tree5d4776506d38b5ac463147cae754ba0d6b6394c0 /fs/btrfs
parent0cbbdf7c9c46467bfb7129c30236f36a679ab244 (diff)
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')
-rw-r--r--fs/btrfs/super.c25
1 files changed, 1 insertions, 24 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 15634d4648d..244fa46c50b 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,
492 struct btrfs_path *path; 492 struct btrfs_path *path;
493 struct btrfs_key location; 493 struct btrfs_key location;
494 struct inode *inode; 494 struct inode *inode;
495 struct dentry *dentry;
496 u64 dir_id; 495 u64 dir_id;
497 int new = 0; 496 int new = 0;
498 497
@@ -566,29 +565,7 @@ setup_root:
566 return dget(sb->s_root); 565 return dget(sb->s_root);
567 } 566 }
568 567
569 if (new) { 568 return d_obtain_alias(inode);
570 const struct qstr name = { .name = "/", .len = 1 };
571
572 /*
573 * New inode, we need to make the dentry a sibling of s_root so
574 * everything gets cleaned up properly on unmount.
575 */
576 dentry = d_alloc(sb->s_root, &name);
577 if (!dentry) {
578 iput(inode);
579 return ERR_PTR(-ENOMEM);
580 }
581 d_splice_alias(inode, dentry);
582 } else {
583 /*
584 * We found the inode in cache, just find a dentry for it and
585 * put the reference to the inode we just got.
586 */
587 dentry = d_find_alias(inode);
588 iput(inode);
589 }
590
591 return dentry;
592} 569}
593 570
594static int btrfs_fill_super(struct super_block *sb, 571static int btrfs_fill_super(struct super_block *sb,