simple_lock_init(&vp->v_uobj.vmobjlock);  vp->v_size = VSIZENOTSET;
simple_lock_init(&vp->v_uvm.u_obj.vmobjlock);
getnewvnode(tag, mp, vops, vpp)	enum vtagtype tag;	struct mount *mp;	int (**vops) __P((void *));	struct vnode **vpp;{	extern struct uvm_pagerops uvm_vnodeops;	struct uvm_object *uobj;	struct proc *p = curproc;			/* XXX */	struct freelst *listhd;	static int toggle;	struct vnode *vp;	int s;	/*	 * We must choose whether to allocate a new vnode or recycle an	 * existing one. The criterion for allocating a new one is that	 * the total number of vnodes is less than the number desired or	 * there are no vnodes on either free list. Generally we only	 * want to recycle vnodes that have no buffers associated with	 * them, so we look first on the vnode_free_list. If it is empty,	 * we next consider vnodes with referencing buffers on the	 * vnode_hold_list. The toggle ensures that half the time we	 * will use a buffer from the vnode_hold_list, and half the time	 * we will allocate a new one unless the list has grown to twice	 * the desired size. We are reticent to recycle vnodes from the	 * vnode_hold_list because we will lose the identity of all its	 * referencing buffers.	 */	toggle ^= 1;	if (numvnodes > 2 * desiredvnodes)		toggle = 0;	simple_lock(&vnode_free_list_slock);	s = splbio();	if ((numvnodes < desiredvnodes) ||	    ((TAILQ_FIRST(listhd = &vnode_free_list) == NULL) &&	    ((TAILQ_FIRST(listhd = &vnode_hold_list) == NULL) || toggle))) {		splx(s);		simple_unlock(&vnode_free_list_slock);		vp = pool_get(&vnode_pool, PR_WAITOK);		bzero(vp, sizeof *vp);		/*		 * initialize uvm_object within vnode.		 */		uobj = &vp->v_uobj;		uobj->pgops = &uvm_vnodeops;		uobj->uo_npages = 0;		TAILQ_INIT(&uobj->memq);		numvnodes++;	} else {		TAILQ_FOREACH(vp, listhd, v_freelist) {			if (simple_lock_try(&vp->v_interlock))				break;		}		/*		 * Unless this is a bad time of the month, at most		 * the first NCPUS items on the free list are		 * locked, so this is close enough to being empty.		 */		if (vp == NULL) {			splx(s);			simple_unlock(&vnode_free_list_slock);			tablefull("vnode");			*vpp = 0;			return (ENFILE);		}		if (vp->v_usecount) {			vprint("free vnode", vp);			panic("free vnode isn't");		}		TAILQ_REMOVE(listhd, vp, v_freelist);		vp->v_bioflag &= ~VBIOONFREELIST;		splx(s);		simple_unlock(&vnode_free_list_slock);		if (vp->v_type != VBAD)			vgonel(vp, p);		else			simple_unlock(&vp->v_interlock);#ifdef DIAGNOSTIC		if (vp->v_data || vp->v_uobj.uo_npages ||		    TAILQ_FIRST(&vp->v_uobj.memq)) {			vprint("cleaned vnode", vp);			panic("cleaned vnode isn't");		}		if (vp->v_numoutput)			panic("Clean vnode has pending I/O's");#endif		vp->v_flag = 0;		vp->v_socket = 0;	}	vp->v_type = VNON;	cache_purge(vp);	vp->v_tag = tag;	vp->v_op = vops;	insmntque(vp, mp);	*vpp = vp;	vp->v_usecount = 1;	vp->v_data = 0;	simple_lock_init(&vp->v_uobj.vmobjlock);	vp->v_size = VSIZENOTSET;	return (0);}