switch try_to_unlazy_next() to __legitimize_mnt()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 5 Jul 2022 16:22:46 +0000 (12:22 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 5 Jul 2022 20:18:21 +0000 (16:18 -0400)
The tricky case (__legitimize_mnt() failing after having grabbed
a reference) can be trivially dealt with by leaving nd->path.mnt
non-NULL, for terminate_walk() to drop it.

legitimize_mnt() becomes static after that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/mount.h
fs/namei.c
fs/namespace.c

index 0b6e08cf8afb07639b844588b82cfc153e5059de..130c07c2f8d258165b7056646dee76dd4c1e7d13 100644 (file)
@@ -100,7 +100,6 @@ static inline int is_mounted(struct vfsmount *mnt)
 extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
 
 extern int __legitimize_mnt(struct vfsmount *, unsigned);
-extern bool legitimize_mnt(struct vfsmount *, unsigned);
 
 static inline bool __path_is_mountpoint(const struct path *path)
 {
index 9c50facb97699d74615ff71fe7cd24edd544ba12..e864d5b9eeac192fcba1d132c87e9e9a9aab05c7 100644 (file)
@@ -799,13 +799,18 @@ out:
  */
 static bool try_to_unlazy_next(struct nameidata *nd, struct dentry *dentry, unsigned seq)
 {
+       int res;
        BUG_ON(!(nd->flags & LOOKUP_RCU));
 
        nd->flags &= ~LOOKUP_RCU;
        if (unlikely(!legitimize_links(nd)))
                goto out2;
-       if (unlikely(!legitimize_mnt(nd->path.mnt, nd->m_seq)))
-               goto out2;
+       res = __legitimize_mnt(nd->path.mnt, nd->m_seq);
+       if (unlikely(res)) {
+               if (res > 0)
+                       goto out2;
+               goto out1;
+       }
        if (unlikely(!lockref_get_not_dead(&nd->path.dentry->d_lockref)))
                goto out1;
 
index e6a7e769d25dd1a9bee1837dd3c8cf1933052e6e..68789f896f0819e0abeb509e90aea20dbc0fc7c7 100644 (file)
@@ -648,7 +648,7 @@ int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
 }
 
 /* call under rcu_read_lock */
-bool legitimize_mnt(struct vfsmount *bastard, unsigned seq)
+static bool legitimize_mnt(struct vfsmount *bastard, unsigned seq)
 {
        int res = __legitimize_mnt(bastard, seq);
        if (likely(!res))