git: f7833196bd6b - main - vfs_lookup(): Minor performance optimizations

From: Jason A. Harmening <jah_at_FreeBSD.org>
Date: Thu, 27 Oct 2022 00:24:33 UTC
The branch main has been updated by jah:

URL: https://cgit.FreeBSD.org/src/commit/?id=f7833196bd6ba9bfc060a41b353422b15d6aa95b

commit f7833196bd6ba9bfc060a41b353422b15d6aa95b
Author:     Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2022-10-20 03:33:19 +0000
Commit:     Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2022-10-27 00:33:33 +0000

    vfs_lookup(): Minor performance optimizations
    
    Refactor the symlink and mountpoint traversal logic to avoid
    repeatedly checking the vnode type; a symlink cannot be a mountpoint
    and vice versa.  Avoid repeatedly checking cn_flags for NOCROSSMOUNT
    and simplify the check which determines whether the vnode is a
    mountpoint.
    
    Suggested by:   mjg
    Reviewed by:    kib
    Tested by:      pho
    Differential Revision:  https://reviews.freebsd.org/D35054
---
 sys/kern/vfs_lookup.c | 74 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 40 insertions(+), 34 deletions(-)

diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 318dcf6fb72b..cc41849de532 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -1221,12 +1221,47 @@ good:
 #endif
 	dp = ndp->ni_vp;
 
+	/*
+	 * Check for symbolic link
+	 */
+	if ((dp->v_type == VLNK) &&
+	    ((cnp->cn_flags & FOLLOW) || (cnp->cn_flags & TRAILINGSLASH) ||
+	     *ndp->ni_next == '/')) {
+		cnp->cn_flags |= ISSYMLINK;
+		if (VN_IS_DOOMED(dp)) {
+			/*
+			 * We can't know whether the directory was mounted with
+			 * NOSYMFOLLOW, so we can't follow safely.
+			 */
+			error = ENOENT;
+			goto bad2;
+		}
+		if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) {
+			error = EACCES;
+			goto bad2;
+		}
+		/*
+		 * Symlink code always expects an unlocked dvp.
+		 */
+		if (ndp->ni_dvp != ndp->ni_vp) {
+			VOP_UNLOCK(ndp->ni_dvp);
+			ni_dvp_unlocked = 1;
+		}
+		goto success;
+	} else if ((vn_irflag_read(dp) & VIRF_MOUNTPOINT) != 0) {
+		if ((cnp->cn_flags & NOCROSSMOUNT) != 0)
+			goto nextname;
+	} else
+		goto nextname;
+
 	/*
 	 * Check to see if the vnode has been mounted on;
 	 * if so find the root of the mounted filesystem.
 	 */
-	while (dp->v_type == VDIR && (mp = dp->v_mountedhere) &&
-	       (cnp->cn_flags & NOCROSSMOUNT) == 0) {
+	do {
+		mp = dp->v_mountedhere;
+		KASSERT(mp != NULL,
+		    ("%s: NULL mountpoint for VIRF_MOUNTPOINT vnode", __func__));
 		crosslock = (dp->v_vflag & VV_CROSSLOCK) != 0;
 		crosslkflags = compute_cn_lkflags(mp, cnp->cn_lkflags,
 		    cnp->cn_flags);
@@ -1239,7 +1274,7 @@ good:
 				goto bad2;
 			}
 		}
-		if (vfs_busy(mp, 0))
+		if (vfs_busy(mp, 0) != 0)
 			continue;
 		if (__predict_true(!crosslock))
 			vput(dp);
@@ -1255,41 +1290,12 @@ good:
 			vput(dp);
 		if (vn_lock(vp_crossmp, LK_SHARED | LK_NOWAIT))
 			panic("vp_crossmp exclusively locked or reclaimed");
-		if (error) {
+		if (error != 0) {
 			dpunlocked = 1;
 			goto bad2;
 		}
 		ndp->ni_vp = dp = tdp;
-	}
-
-	/*
-	 * Check for symbolic link
-	 */
-	if ((dp->v_type == VLNK) &&
-	    ((cnp->cn_flags & FOLLOW) || (cnp->cn_flags & TRAILINGSLASH) ||
-	     *ndp->ni_next == '/')) {
-		cnp->cn_flags |= ISSYMLINK;
-		if (VN_IS_DOOMED(dp)) {
-			/*
-			 * We can't know whether the directory was mounted with
-			 * NOSYMFOLLOW, so we can't follow safely.
-			 */
-			error = ENOENT;
-			goto bad2;
-		}
-		if (dp->v_mount->mnt_flag & MNT_NOSYMFOLLOW) {
-			error = EACCES;
-			goto bad2;
-		}
-		/*
-		 * Symlink code always expects an unlocked dvp.
-		 */
-		if (ndp->ni_dvp != ndp->ni_vp) {
-			VOP_UNLOCK(ndp->ni_dvp);
-			ni_dvp_unlocked = 1;
-		}
-		goto success;
-	}
+	} while ((vn_irflag_read(dp) & VIRF_MOUNTPOINT) != 0);
 
 nextname:
 	/*