git: f7833196bd6b - main - vfs_lookup(): Minor performance optimizations
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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:
/*