Josef Bacik <jba...@fb.com> writes: > A user was running into errors from an NFS export of a subvolume that had a > default subvol set. When we mount a default subvol we will use > d_obtain_alias() > to find an existing dentry for the subvolume in the case that the root subvol > has already been mounted, or a dummy one is allocated in the case that the > root > subvol has not already been mounted. This allows us to connect the dentry > later > on if we wander into the path. However if we don't ever wander into the path > we > will keep DCACHE_DISCONNECTED set for a long time, which angers NFS. It > doesn't > appear to cause any problems but it is annoying nonetheless, so simply unset > DCACHE_DISCONNECTED in the get_default_root case and switch btrfs_lookup() to > use d_materialise_unique() instead which will make everything play nicely > together and reconnect stuff if we wander into the defaul subvol path from a > different way. With this patch I'm no longer getting the NFS errors when > exporting a volume that has been mounted with a default subvol set. Thanks, > > cc: bfie...@fieldses.org > cc: ebied...@xmission.com Acked-by: "Eric W. Biederman" <ebied...@xmission.com>
> Signed-off-by: Josef Bacik <jba...@fb.com> > --- > fs/btrfs/inode.c | 2 +- > fs/btrfs/super.c | 9 ++++++++- > 2 files changed, 9 insertions(+), 2 deletions(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index 197edee..8dba152 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -5157,7 +5157,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, > struct dentry *dentry, > return ERR_CAST(inode); > } > > - return d_splice_alias(inode, dentry); > + return d_materialise_unique(dentry, inode); > } > > unsigned char btrfs_filetype_table[] = { > diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c > index 147ca1d..dc0a315 100644 > --- a/fs/btrfs/super.c > +++ b/fs/btrfs/super.c > @@ -855,6 +855,7 @@ 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; > > @@ -925,7 +926,13 @@ setup_root: > return dget(sb->s_root); > } > > - return d_obtain_alias(inode); > + dentry = d_obtain_alias(inode); > + if (!IS_ERR(dentry)) { > + spin_lock(&dentry->d_lock); > + dentry->d_flags &= ~DCACHE_DISCONNECTED; > + spin_unlock(&dentry->d_lock); > + } > + return dentry; > } > > static int btrfs_fill_super(struct super_block *sb, -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html