* [RFC][PATCH] get rid of weirdness around NFS dummy root dentries
@ 2026-01-24 19:58 Al Viro
0 siblings, 0 replies; only message in thread
From: Al Viro @ 2026-01-24 19:58 UTC (permalink / raw)
To: linux-fsdevel
Cc: linux-nfs, Trond Myklebust, Anna Schumaker, David Howells,
Linus Torvalds, Christian Brauner, Jan Kara
These days (starting from 2013, actually) dcache_shrink_for_umount() is not
bothered by having ->s_root spliced onto one of the secondary trees, so the reason
for having a weird alias for root directory (manually removed from the alias list
of directory inode, which violates all kinds of assumptions) no longer applies.
Just use the dentry we are about to return as ->s_root, if it hasn't been
set already. And don't bother with manual security_d_instantiate(), while we are
at it - d_obtain_root() has already done that.
NOTE: if root of the first mount does get spliced onto the bigger subtree
of subsequent mount, it will keep the resulting chain of ancestors pinned in dcache
for as long as any of mounts exist. That won't affect the "is the filesystem busy"
logics, though; just that after
mount foo:/bar/baz/barf /path1
mount foo:/bar/ /path2
ls /path2/baz/barf
umount /path1
we'll get the dentries of /path2/baz and /path2/baz/barf stay in dcache (unhashed
if invalidated, etc.) until /path2 is also unmounted, rather than having only the
dummy root pinned.
AFAICS, it works and unless there are other reasons why need it, it would
be nice to get rid of that wart.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index f13d25d95b85..2ac8404e1a15 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -32,35 +32,6 @@
#define NFSDBG_FACILITY NFSDBG_CLIENT
-/*
- * Set the superblock root dentry.
- * Note that this function frees the inode in case of error.
- */
-static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *inode)
-{
- /* The mntroot acts as the dummy root dentry for this superblock */
- if (sb->s_root == NULL) {
- sb->s_root = d_make_root(inode);
- if (sb->s_root == NULL)
- return -ENOMEM;
- ihold(inode);
- /*
- * Ensure that this dentry is invisible to d_find_alias().
- * Otherwise, it may be spliced into the tree by
- * d_splice_alias if a parent directory from the same
- * filesystem gets mounted at a later time.
- * This again causes shrink_dcache_for_umount_subtree() to
- * Oops, since the test for IS_ROOT() will fail.
- */
- spin_lock(&d_inode(sb->s_root)->i_lock);
- spin_lock(&sb->s_root->d_lock);
- hlist_del_init(&sb->s_root->d_u.d_alias);
- spin_unlock(&sb->s_root->d_lock);
- spin_unlock(&d_inode(sb->s_root)->i_lock);
- }
- return 0;
-}
-
/*
* get a root dentry from the root filehandle
*/
@@ -99,10 +70,6 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
goto out_fattr;
}
- error = nfs_superblock_set_dummy_root(s, inode);
- if (error != 0)
- goto out_fattr;
-
/* root dentries normally start off anonymous and get spliced in later
* if the dentry tree reaches them; however if the dentry already
* exists, we'll pick it up at this point and use it as the root
@@ -115,7 +82,6 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
goto out_fattr;
}
- security_d_instantiate(root, inode);
spin_lock(&root->d_lock);
if (IS_ROOT(root) && !root->d_fsdata &&
!(root->d_flags & DCACHE_NFSFS_RENAMED)) {
@@ -123,6 +89,8 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
name = NULL;
}
spin_unlock(&root->d_lock);
+ if (!s->s_root)
+ s->s_root = dget(root);
fc->root = root;
if (server->caps & NFS_CAP_SECURITY_LABEL)
kflags |= SECURITY_LSM_NATIVE_LABELS;
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-01-24 19:56 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-24 19:58 [RFC][PATCH] get rid of weirdness around NFS dummy root dentries Al Viro
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox