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;