if (!error && uiop->uio_resid) {
if (!error) { bp->b_validoff = 0; if (uiop->uio_resid) {
nfs_doio(bp, p)	struct buf *bp;	struct proc *p;{	register struct uio *uiop;	register struct vnode *vp;	struct nfsnode *np;	struct nfsmount *nmp;	int error = 0, diff, len, iomode, must_commit = 0;	struct uio uio;	struct iovec io;	vp = bp->b_vp;	np = VTONFS(vp);	nmp = VFSTONFS(vp->v_mount);	uiop = &uio;	uiop->uio_iov = &io;	uiop->uio_iovcnt = 1;	uiop->uio_segflg = UIO_SYSSPACE;	uiop->uio_procp = p;	/*	 * Historically, paging was done with physio, but no more...	 */	if (bp->b_flags & B_PHYS) {	    /*	     * ...though reading /dev/drum still gets us here.	     */	    io.iov_len = uiop->uio_resid = bp->b_bcount;	    /* mapping was done by vmapbuf() */	    io.iov_base = bp->b_data;	    uiop->uio_offset = ((off_t)bp->b_blkno) << DEV_BSHIFT;	    if (bp->b_flags & B_READ) {		uiop->uio_rw = UIO_READ;		nfsstats.read_physios++;		error = nfs_readrpc(vp, uiop);	    } else {		iomode = NFSV3WRITE_DATASYNC;		uiop->uio_rw = UIO_WRITE;		nfsstats.write_physios++;		error = nfs_writerpc(vp, uiop, &iomode, &must_commit);	    }	    if (error) {		bp->b_flags |= B_ERROR;		bp->b_error = error;	    }	} else if (bp->b_flags & B_READ) {	    io.iov_len = uiop->uio_resid = bp->b_bcount;	    io.iov_base = bp->b_data;	    uiop->uio_rw = UIO_READ;	    switch (vp->v_type) {	    case VREG:		uiop->uio_offset = ((off_t)bp->b_blkno) << DEV_BSHIFT;		nfsstats.read_bios++;		error = nfs_readrpc(vp, uiop);		if (!error && uiop->uio_resid) {			/*			 * If len > 0, there is a hole in the file and			 * no writes after the hole have been pushed to			 * the server yet.			 * Just zero fill the rest of the valid area.			 */			diff = bp->b_bcount - uiop->uio_resid;			len = np->n_size - ((((off_t)bp->b_blkno) << DEV_BSHIFT)				+ diff);			if (len > 0) {				len = MIN(len, uiop->uio_resid);				memset((char *)bp->b_data + diff, 0, len);			}		}		if (p && (vp->v_flag & VTEXT) &&		    (np->n_mtime != np->n_vattr.va_mtime.tv_sec)) {			uprintf("Process killed due to text file modification\n");			psignal(p, SIGKILL);			p->p_holdcnt++;		}		break;	    case VLNK:		uiop->uio_offset = (off_t)0;		nfsstats.readlink_bios++;		error = nfs_readlinkrpc(vp, uiop, curproc->p_ucred);		break;	    default:		printf("nfs_doio:  type %x unexpected\n",vp->v_type);		break;	    }	    if (error) {		bp->b_flags |= B_ERROR;		bp->b_error = error;	    }	} else {	    io.iov_base = bp->b_data;	    io.iov_len = uiop->uio_resid = bp->b_bcount;	    uiop->uio_offset = ((off_t)bp->b_blkno) << DEV_BSHIFT;	    uiop->uio_rw = UIO_WRITE;	    nfsstats.write_bios++;	    iomode = NFSV3WRITE_UNSTABLE;	    error = nfs_writerpc(vp, uiop, &iomode, &must_commit);	}	bp->b_resid = uiop->uio_resid;	if (must_commit)		nfs_clearcommit(vp->v_mount);	biodone(bp);	return (error);}