struct vnode *vp = ap->a_vp;
register struct vnode *vp = ap->a_vp;
nfs_write(v)	void *v;{	struct vop_write_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap = v;	int biosize;	struct uio *uio = ap->a_uio;	struct proc *p = uio->uio_procp;	struct vnode *vp = ap->a_vp;	struct nfsnode *np = VTONFS(vp);	struct ucred *cred = ap->a_cred;	int ioflag = ap->a_ioflag;	struct vattr vattr;	struct nfsmount *nmp = VFSTONFS(vp->v_mount);	int error = 0;	int rv;#ifdef DIAGNOSTIC	if (uio->uio_rw != UIO_WRITE)		panic("nfs_write mode");	if (uio->uio_segflg == UIO_USERSPACE && uio->uio_procp != curproc)		panic("nfs_write proc");#endif	if (vp->v_type != VREG)		return (EIO);	if (np->n_flag & NWRITEERR) {		np->n_flag &= ~NWRITEERR;		return (np->n_error);	}	if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3)		(void)nfs_fsinfo(nmp, vp, cred, p);	if (ioflag & (IO_APPEND | IO_SYNC)) {		if (np->n_flag & NMODIFIED) {			np->n_attrstamp = 0;			error = nfs_vinvalbuf(vp, V_SAVE, cred, p, 1);			if (error)				return (error);		}		if (ioflag & IO_APPEND) {			np->n_attrstamp = 0;			error = VOP_GETATTR(vp, &vattr, cred, p);			if (error)				return (error);			uio->uio_offset = np->n_size;		}	}	if (uio->uio_offset < 0)		return (EINVAL);	if (uio->uio_resid == 0)		return (0);	/*	 * Maybe this should be above the vnode op call, but so long as	 * file servers have no limits, i don't think it matters	 */	if (p && uio->uio_offset + uio->uio_resid >	      p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {		psignal(p, SIGXFSZ);		return (EFBIG);	}	/*	 * update the cache write creds for this node.	 */	if (np->n_wcred)		crfree(np->n_wcred);	np->n_wcred = cred;	crhold(cred);	/*	 * I use nm_rsize, not nm_wsize so that all buffer cache blocks	 * will be the same size within a filesystem. nfs_writerpc will	 * still use nm_wsize when sizing the rpc's.	 */	biosize = nmp->nm_rsize;	do {		void *win;		voff_t oldoff = uio->uio_offset;		vsize_t bytelen;		/*		 * XXXART - workaround for compiler bug on 68k. Wieee!		 */		 *((volatile vsize_t *)&bytelen) = uio->uio_resid;		nfsstats.biocache_writes++;		np->n_flag |= NMODIFIED;		if (np->n_size < uio->uio_offset + bytelen) {			np->n_size = uio->uio_offset + bytelen;			uvm_vnp_setsize(vp, np->n_size);		}		win = ubc_alloc(&vp->v_uobj, uio->uio_offset, &bytelen,				UBC_WRITE);		error = uiomove(win, bytelen, uio);		ubc_release(win, 0);		rv = 1;		if ((ioflag & IO_SYNC)) {			simple_lock(&vp->v_uobj.vmobjlock);			rv = vp->v_uobj.pgops->pgo_flush(			    &vp->v_uobj,			    oldoff & ~(nmp->nm_wsize - 1),			    uio->uio_offset & ~(nmp->nm_wsize - 1),			    PGO_CLEANIT|PGO_SYNCIO);			simple_unlock(&vp->v_uobj.vmobjlock);		} else if ((oldoff & ~(nmp->nm_wsize - 1)) !=		    (uio->uio_offset & ~(nmp->nm_wsize - 1))) {			simple_lock(&vp->v_uobj.vmobjlock);			rv = vp->v_uobj.pgops->pgo_flush(			    &vp->v_uobj,			    oldoff & ~(nmp->nm_wsize - 1),			    uio->uio_offset & ~(nmp->nm_wsize - 1),			    PGO_CLEANIT|PGO_WEAK);			simple_unlock(&vp->v_uobj.vmobjlock);		}		if (!rv) {			error = EIO;		}		if (error) {			break;		}	} while (uio->uio_resid > 0);	return (error);}