nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, p)
nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, retdirp, p, kerbflag)
nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, p)	register struct nameidata *ndp;	fhandle_t *fhp;	int len;	struct nfssvc_sock *slp;	struct mbuf *nam;	struct mbuf **mdp;	caddr_t *dposp;	struct proc *p;{	register int i, rem;	register struct mbuf *md;	register char *fromcp, *tocp;	struct vnode *dp;	int error, rdonly;	struct componentname *cnp = &ndp->ni_cnd;	MALLOC(cnp->cn_pnbuf, char *, len + 1, M_NAMEI, M_WAITOK);	/*	 * Copy the name from the mbuf list to ndp->ni_pnbuf	 * and set the various ndp fields appropriately.	 */	fromcp = *dposp;	tocp = cnp->cn_pnbuf;	md = *mdp;	rem = mtod(md, caddr_t) + md->m_len - fromcp;	for (i = 0; i < len; i++) {		while (rem == 0) {			md = md->m_next;			if (md == NULL) {				error = EBADRPC;				goto out;			}			fromcp = mtod(md, caddr_t);			rem = md->m_len;		}		if (*fromcp == '\0' || *fromcp == '/') {			error = EINVAL;			goto out;		}		*tocp++ = *fromcp++;		rem--;	}	*tocp = '\0';	*mdp = md;	*dposp = fromcp;	len = nfsm_rndup(len)-len;	if (len > 0) {		if (rem >= len)			*dposp += len;		else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0)			goto out;	}	ndp->ni_pathlen = tocp - cnp->cn_pnbuf;	cnp->cn_nameptr = cnp->cn_pnbuf;	/*	 * Extract and set starting directory.	 */	error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp,			     nam, &rdonly);	if (error)		goto out;	if (dp->v_type != VDIR) {		vrele(dp);		error = ENOTDIR;		goto out;	}	ndp->ni_startdir = dp;	if (rdonly)		cnp->cn_flags |= (NOCROSSMOUNT | RDONLY);	else		cnp->cn_flags |= NOCROSSMOUNT;	/*	 * And call lookup() to do the real work	 */	cnp->cn_proc = p;	if ((error = lookup(ndp)) != 0)		goto out;	/*	 * Check for encountering a symbolic link	 */	if (cnp->cn_flags & ISSYMLINK) {		if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1)			vput(ndp->ni_dvp);		else			vrele(ndp->ni_dvp);		vput(ndp->ni_vp);		ndp->ni_vp = NULL;		error = EINVAL;		goto out;	}	/*	 * Check for saved name request	 */	if (cnp->cn_flags & (SAVENAME | SAVESTART)) {		cnp->cn_flags |= HASBUF;		return (0);	}out:	FREE(cnp->cn_pnbuf, M_NAMEI);	return (error);}