Module Name: src Committed By: dholland Date: Tue Jun 29 22:29:59 UTC 2021
Modified Files: src/sys/kern: vfs_lookup.c Log Message: 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.) To generate a diff of this commit: cvs rdiff -u -r1.226 -r1.227 src/sys/kern/vfs_lookup.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_lookup.c diff -u src/sys/kern/vfs_lookup.c:1.226 src/sys/kern/vfs_lookup.c:1.227 --- src/sys/kern/vfs_lookup.c:1.226 Wed Jun 16 01:51:57 2021 +++ src/sys/kern/vfs_lookup.c Tue Jun 29 22:29:59 2021 @@ -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 * 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, * 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 *sta * 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 *s */ 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 *s } 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, s 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_st 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 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;