error = vget(vdp, 1);
nfs_lookup(v)	void *v;{	struct vop_lookup_args /* {		struct vnodeop_desc *a_desc;		struct vnode *a_dvp;		struct vnode **a_vpp;		struct componentname *a_cnp;	} */ *ap = v;	register struct componentname *cnp = ap->a_cnp;	register struct vnode *dvp = ap->a_dvp;	register struct vnode **vpp = ap->a_vpp;	register int flags = cnp->cn_flags;	register struct vnode *vdp;	register u_int32_t *tl;	register caddr_t cp;	register int32_t t1, t2;	struct nfsmount *nmp;	caddr_t bpos, dpos, cp2;	time_t reqtime = 0;	struct mbuf *mreq, *mrep, *md, *mb, *mb2;	struct vnode *newvp;	long len;	nfsv2fh_t *fhp;	struct nfsnode *np;	int lockparent, wantparent, error = 0;	int nqlflag = 0, cachable = 0;	u_quad_t frev;	*vpp = NULL;	if (dvp->v_type != VDIR)		return (ENOTDIR);	lockparent = flags & LOCKPARENT;	wantparent = flags & (LOCKPARENT|WANTPARENT);	nmp = VFSTONFS(dvp->v_mount);	np = VTONFS(dvp);	if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) {		struct vattr vattr;		int vpid;		vdp = *vpp;		vpid = vdp->v_id;		/*		 * See the comment starting `Step through' in ufs/ufs_lookup.c		 * for an explanation of the locking protocol		 */		if (dvp == vdp) {			VREF(vdp);			error = 0;		} else			error = vget(vdp, 1);		if (!error) {			if (vpid == vdp->v_id) {			   if (nmp->nm_flag & NFSMNT_NQNFS) {				if ((nmp->nm_flag & NFSMNT_NQLOOKLEASE) == 0) {				cachehit:					nfsstats.lookupcache_hits++;					if (cnp->cn_nameiop != LOOKUP &&					    (flags & ISLASTCN))						cnp->cn_flags |= SAVENAME;					return (0);			        } else if (NQNFS_CKCACHABLE(dvp, NQL_READ)) {					if (np->n_lrev != np->n_brev ||					    (np->n_flag & NMODIFIED)) {						np->n_direofoffset = 0;						cache_purge(dvp);						error = nfs_vinvalbuf(dvp, 0,						    cnp->cn_cred, cnp->cn_proc,						    1);						if (error == EINTR)							return (error);						np->n_brev = np->n_lrev;					} else						goto cachehit;				}			   } else if (!VOP_GETATTR(vdp, &vattr, cnp->cn_cred, cnp->cn_proc) &&			       vattr.va_ctime.tv_sec == VTONFS(vdp)->n_ctime)				goto cachehit;			   cache_purge(vdp);			}			vrele(vdp);		}		*vpp = NULLVP;	}	error = 0;	nfsstats.lookupcache_misses++;	nfsstats.rpccnt[NFSPROC_LOOKUP]++;	len = cnp->cn_namelen;	nfsm_reqhead(dvp, NFSPROC_LOOKUP, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(len));	/*	 * For nqnfs optionally piggyback a getlease request for the name	 * being looked up.	 */	if (nmp->nm_flag & NFSMNT_NQNFS) {		nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED);		if ((nmp->nm_flag & NFSMNT_NQLOOKLEASE) &&		    ((cnp->cn_flags & MAKEENTRY) &&		    (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))))			*tl = txdr_unsigned(nmp->nm_leaseterm);		else			*tl = 0;	}	nfsm_fhtom(dvp);	nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);	reqtime = time.tv_sec;	nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_proc, cnp->cn_cred);nfsmout:	if (error) {		if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&		    (flags & ISLASTCN) && error == ENOENT)			error = EJUSTRETURN;		if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))			cnp->cn_flags |= SAVENAME;		return (error);	}	if (nmp->nm_flag & NFSMNT_NQNFS) {		nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);		if (*tl) {			nqlflag = fxdr_unsigned(int, *tl);			nfsm_dissect(tl, u_int32_t *, 4*NFSX_UNSIGNED);			cachable = fxdr_unsigned(int, *tl++);			reqtime += fxdr_unsigned(int, *tl++);			fxdr_hyper(tl, &frev);		} else			nqlflag = 0;	}	nfsm_dissect(fhp, nfsv2fh_t *, NFSX_FH);	/*	 * Handle RENAME case...	 */	if (cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN)) {		if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {			m_freem(mrep);			return (EISDIR);		}		if ((error = nfs_nget(dvp->v_mount, fhp, &np)) != 0) {			m_freem(mrep);			return (error);		}		newvp = NFSTOV(np);		error = nfs_loadattrcache(&newvp, &md, &dpos, NULL);		if (error) {			vrele(newvp);			m_freem(mrep);			return (error);		}		*vpp = newvp;		m_freem(mrep);		cnp->cn_flags |= SAVENAME;		return (0);	}	if (!bcmp(np->n_fh.fh_bytes, (caddr_t)fhp, NFSX_FH)) {		VREF(dvp);		newvp = dvp;	} else {		if ((error = nfs_nget(dvp->v_mount, fhp, &np)) != 0) {			m_freem(mrep);			return (error);		}		newvp = NFSTOV(np);	}	error = nfs_loadattrcache(&newvp, &md, &dpos, (struct vattr *)0);	if (error) {		vrele(newvp);		m_freem(mrep);		return (error);	}	m_freem(mrep);	*vpp = newvp;	if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))		cnp->cn_flags |= SAVENAME;	if ((cnp->cn_flags & MAKEENTRY) &&	    (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) {		if ((nmp->nm_flag & NFSMNT_NQNFS) == 0)			np->n_ctime = np->n_vattr.va_ctime.tv_sec;		else if (nqlflag && reqtime > time.tv_sec)			nqnfs_clientlease(nmp, np, nqlflag, cachable, reqtime,				frev);		cache_enter(dvp, *vpp, cnp);	}	return (0);}