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: /*