Skip to content

Commit 3a0dfa6

Browse files
Josef Bacikmasoncl
authored andcommitted
Btrfs: unset DCACHE_DISCONNECTED when mounting default subvol
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: bfields@fieldses.org cc: ebiederm@xmission.com Signed-off-by: Josef Bacik <jbacik@fb.com> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Chris Mason <clm@fb.com>
1 parent feb5f96 commit 3a0dfa6

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

fs/btrfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5150,7 +5150,7 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
51505150
return ERR_CAST(inode);
51515151
}
51525152

5153-
return d_splice_alias(inode, dentry);
5153+
return d_materialise_unique(dentry, inode);
51545154
}
51555155

51565156
unsigned char btrfs_filetype_table[] = {

fs/btrfs/super.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@ static struct dentry *get_default_root(struct super_block *sb,
855855
struct btrfs_path *path;
856856
struct btrfs_key location;
857857
struct inode *inode;
858+
struct dentry *dentry;
858859
u64 dir_id;
859860
int new = 0;
860861

@@ -925,7 +926,13 @@ static struct dentry *get_default_root(struct super_block *sb,
925926
return dget(sb->s_root);
926927
}
927928

928-
return d_obtain_alias(inode);
929+
dentry = d_obtain_alias(inode);
930+
if (!IS_ERR(dentry)) {
931+
spin_lock(&dentry->d_lock);
932+
dentry->d_flags &= ~DCACHE_DISCONNECTED;
933+
spin_unlock(&dentry->d_lock);
934+
}
935+
return dentry;
929936
}
930937

931938
static int btrfs_fill_super(struct super_block *sb,

0 commit comments

Comments
 (0)