if (vp->v_type == VREG && uvn_attach(vp, fmode & FWRITE ? VM_PROT_WRITE : 0) == NULL) { error = EIO; goto bad; }
vn_open(ndp, fmode, cmode)	register struct nameidata *ndp;	int fmode, cmode;{	register struct vnode *vp;	register struct proc *p = ndp->ni_cnd.cn_proc;	register struct ucred *cred = p->p_ucred;	struct vattr va;	int error;	if ((fmode & (FREAD|FWRITE)) == 0)		return (EINVAL);	if ((fmode & (O_TRUNC | FWRITE)) == O_TRUNC)		return (EINVAL);	if (fmode & O_CREAT) {		ndp->ni_cnd.cn_nameiop = CREATE;		ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;		if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)			ndp->ni_cnd.cn_flags |= FOLLOW;		if ((error = namei(ndp)) != 0)			return (error);		if (ndp->ni_vp == NULL) {			VATTR_NULL(&va);			va.va_type = VREG;			va.va_mode = cmode;			VOP_LEASE(ndp->ni_dvp, p, cred, LEASE_WRITE);			error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,					   &ndp->ni_cnd, &va);			if (error)				return (error);			fmode &= ~O_TRUNC;			vp = ndp->ni_vp;		} else {			VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);			if (ndp->ni_dvp == ndp->ni_vp)				vrele(ndp->ni_dvp);			else				vput(ndp->ni_dvp);			ndp->ni_dvp = NULL;			vp = ndp->ni_vp;			if (fmode & O_EXCL) {				error = EEXIST;				goto bad;			}			fmode &= ~O_CREAT;		}	} else {		ndp->ni_cnd.cn_nameiop = LOOKUP;		ndp->ni_cnd.cn_flags =		    ((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKLEAF;		if ((error = namei(ndp)) != 0)			return (error);		vp = ndp->ni_vp;	}	if (vp->v_type == VSOCK) {		error = EOPNOTSUPP;		goto bad;	}	if (vp->v_type == VLNK) {		error = EMLINK;		goto bad;	}	if ((fmode & O_CREAT) == 0) {		if (fmode & FREAD) {			if ((error = VOP_ACCESS(vp, VREAD, cred, p)) != 0)				goto bad;		}		if (fmode & FWRITE) {			if (vp->v_type == VDIR) {				error = EISDIR;				goto bad;			}			if ((error = vn_writechk(vp)) != 0 ||			    (error = VOP_ACCESS(vp, VWRITE, cred, p)) != 0)				goto bad;		}	}	if ((fmode & O_TRUNC) && vp->v_type == VREG) {		VOP_UNLOCK(vp, 0, p);				/* XXX */		VOP_LEASE(vp, p, cred, LEASE_WRITE);		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);	/* XXX */		VATTR_NULL(&va);		va.va_size = 0;		if ((error = VOP_SETATTR(vp, &va, cred, p)) != 0)			goto bad;	}	if ((error = VOP_OPEN(vp, fmode, cred, p)) != 0)		goto bad;	if (vp->v_type == VREG &&	    uvn_attach(vp, fmode & FWRITE ? VM_PROT_WRITE : 0) == NULL) {		error = EIO;		goto bad;	}	if (fmode & FWRITE)		vp->v_writecount++;	return (0);bad:	vput(vp);	return (error);}