git: 4ef6e56ae807 - main - vfs: hoist trailing slash handling out of the loop
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 24 Mar 2022 14:36:35 UTC
The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=4ef6e56ae80782e4242cc1a32abfd5b0cd541955 commit 4ef6e56ae80782e4242cc1a32abfd5b0cd541955 Author: Mateusz Guzik <mjg@FreeBSD.org> AuthorDate: 2022-03-24 13:17:31 +0000 Commit: Mateusz Guzik <mjg@FreeBSD.org> CommitDate: 2022-03-24 14:36:31 +0000 vfs: hoist trailing slash handling out of the loop --- sys/kern/vfs_lookup.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 8b4ceecce462..71173d189ef2 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -940,6 +940,7 @@ vfs_lookup(struct nameidata *ndp) char *cp; /* pointer into pathname argument */ char *prev_ni_next; /* saved ndp->ni_next */ char *nulchar; /* location of '\0' in cn_pnbuf */ + char *lastchar; /* location of the last character */ struct vnode *dp = NULL; /* the directory we are searching */ struct vnode *tdp; /* saved dp */ struct mount *mp; /* mount table entry */ @@ -1001,6 +1002,28 @@ vfs_lookup(struct nameidata *ndp) goto bad_unlocked; } + /* + * Nul-out trailing slashes (e.g., "foo///" -> "foo"). + * + * This must be done before VOP_LOOKUP() because some fs's don't know + * about trailing slashes. Remember if there were trailing slashes to + * handle symlinks, existing non-directories and non-existing files + * that won't be directories specially later. + */ + MPASS(ndp->ni_pathlen >= 2); + lastchar = &cnp->cn_nameptr[ndp->ni_pathlen - 2]; + if (*lastchar == '/') { + while (lastchar >= cnp->cn_pnbuf) { + *lastchar = '\0'; + lastchar--; + ndp->ni_pathlen--; + if (*lastchar != '/') { + break; + } + } + cnp->cn_flags |= TRAILINGSLASH; + } + /* * We use shared locks until we hit the parent of the last cn then * we adjust based on the requesting flags. @@ -1052,23 +1075,6 @@ dirloop: prev_ni_next = ndp->ni_next; ndp->ni_next = cp; - /* - * Replace multiple slashes by a single slash and trailing slashes - * by a null. This must be done before VOP_LOOKUP() because some - * fs's don't know about trailing slashes. Remember if there were - * trailing slashes to handle symlinks, existing non-directories - * and non-existing files that won't be directories specially later. - */ - while (*cp == '/' && (cp[1] == '/' || cp[1] == '\0')) { - cp++; - ndp->ni_pathlen--; - if (*cp == '\0') { - *ndp->ni_next = '\0'; - cnp->cn_flags |= TRAILINGSLASH; - } - } - ndp->ni_next = cp; - cnp->cn_flags |= MAKEENTRY; if (*cp == '\0' && docache == 0) cnp->cn_flags &= ~MAKEENTRY;