summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authordholland <dholland@NetBSD.org>2021-06-29 22:29:59 +0000
committerdholland <dholland@NetBSD.org>2021-06-29 22:29:59 +0000
commit0de14abf82c10da4ae8db9360ff2e004792a4148 (patch)
tree18088f8ecf284699d0ad83f442a1dcd651306a16 /sys
parent36fce0ea8eeaa2f9d8ebf718b096ee32936a37d7 (diff)
Adjust namei internals to be able to make an external call to parse
the pathname. (Basically, this means change the signature of namei_getcomponent(), and thus lookup_parsepath(), to pass in the directory vnode and to allow failures.)
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_lookup.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index 0afa96c3e4f..cbe5e482ceb 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_lookup.c,v 1.226 2021/06/16 01:51:57 dholland Exp $ */
+/* $NetBSD: vfs_lookup.c,v 1.227 2021/06/29 22:29:59 dholland Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.226 2021/06/16 01:51:57 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.227 2021/06/29 22:29:59 dholland Exp $");
#ifdef _KERNEL_OPT
#include "opt_magiclinks.h"
@@ -229,16 +229,19 @@ namei_hash(const char *name, const char **ep)
* Find the end of the first path component in NAME and return its
* length.
*/
-static size_t
-namei_getcomponent(const char *name)
+static int
+namei_getcomponent(struct vnode *dvp, const char *name, size_t *ret)
{
size_t pos;
+ (void)dvp;
+
pos = 0;
while (name[pos] != '\0' && name[pos] != '/') {
pos++;
}
- return pos;
+ *ret = pos;
+ return 0;
}
////////////////////////////////////////////////////////////
@@ -840,9 +843,10 @@ namei_follow(struct namei_state *state, int inhibitmagic,
* Inspect the leading path component and update the state accordingly.
*/
static int
-lookup_parsepath(struct namei_state *state)
+lookup_parsepath(struct namei_state *state, struct vnode *searchdir)
{
const char *cp; /* pointer into pathname argument */
+ int error;
struct componentname *cnp = state->cnp;
struct nameidata *ndp = state->ndp;
@@ -861,7 +865,11 @@ lookup_parsepath(struct namei_state *state)
* is held.
*/
cnp->cn_consume = 0;
- cnp->cn_namelen = namei_getcomponent(cnp->cn_nameptr);
+ error = namei_getcomponent(searchdir, cnp->cn_nameptr,
+ &cnp->cn_namelen);
+ if (error) {
+ return error;
+ }
cp = cnp->cn_nameptr + cnp->cn_namelen;
if (cnp->cn_namelen > KERNEL_NAME_MAX) {
return ENAMETOOLONG;
@@ -1325,7 +1333,7 @@ lookup_fastforward(struct namei_state *state, struct vnode **searchdir_ret,
*/
KASSERT(cnp->cn_nameptr[0] != '/');
KASSERT(cnp->cn_nameptr[0] != '\0');
- if ((error = lookup_parsepath(state)) != 0) {
+ if ((error = lookup_parsepath(state, searchdir)) != 0) {
break;
}
@@ -1500,9 +1508,13 @@ lookup_fastforward(struct namei_state *state, struct vnode **searchdir_ret,
}
cnp->cn_nameptr = oldnameptr;
ndp->ni_pathlen = oldpathlen;
- error = lookup_parsepath(state);
- if (error == 0) {
+ if (searchdir == NULL) {
error = EOPNOTSUPP;
+ } else {
+ error = lookup_parsepath(state, searchdir);
+ if (error == 0) {
+ error = EOPNOTSUPP;
+ }
}
}
} else if (plock != NULL) {
@@ -2049,7 +2061,7 @@ lookup_for_nfsd(struct nameidata *ndp, struct vnode *forcecwd, int neverfollow)
static int
do_lookup_for_nfsd_index(struct namei_state *state)
{
- int error = 0;
+ int error;
struct componentname *cnp = state->cnp;
struct nameidata *ndp = state->ndp;
@@ -2068,7 +2080,12 @@ do_lookup_for_nfsd_index(struct namei_state *state)
ndp->ni_dvp = NULL;
cnp->cn_consume = 0;
- cnp->cn_namelen = namei_getcomponent(cnp->cn_nameptr);
+ error = namei_getcomponent(startdir, cnp->cn_nameptr,
+ &cnp->cn_namelen);
+ if (error) {
+ return error;
+ }
+
cp = cnp->cn_nameptr + cnp->cn_namelen;
KASSERT(cnp->cn_namelen <= KERNEL_NAME_MAX);
ndp->ni_pathlen -= cnp->cn_namelen;
@@ -2199,7 +2216,10 @@ relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, int d
if ((uint32_t)newhash != (uint32_t)cnp->cn_hash)
panic("relookup: bad hash");
#endif
- newlen = namei_getcomponent(cnp->cn_nameptr);
+ error = namei_getcomponent(dvp, cnp->cn_nameptr, &newlen);
+ if (error) {
+ panic("relookup: parsepath failed with error %d", error);
+ }
if (cnp->cn_namelen != newlen)
panic("relookup: bad len");
cp = cnp->cn_nameptr + cnp->cn_namelen;