vfs: hoist trailing slash handling out of the loop

This commit is contained in:
Mateusz Guzik 2022-03-24 13:17:31 +00:00
parent 18f71c9b27
commit 4ef6e56ae8

View File

@ -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;