NQNFS_CKINVALID(vp, np, NQL_READ) &&
NQNFS_CKINVALID(vp, np, ND_READ) &&
nfs_doio(bp, cr, p)	register struct buf *bp;	struct ucred *cr;	struct proc *p;{	register struct uio *uiop;	register struct vnode *vp;	struct nfsnode *np;	struct nfsmount *nmp;	int error = 0, diff, len;	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 = bp->b_blkno * DEV_BSIZE;	    if (bp->b_flags & B_READ) {		uiop->uio_rw = UIO_READ;		nfsstats.read_physios++;		error = nfs_readrpc(vp, uiop, cr);	    } else {		uiop->uio_rw = UIO_WRITE;		nfsstats.write_physios++;		error = nfs_writerpc(vp, uiop, cr, 0);	    }	    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 = bp->b_blkno * DEV_BSIZE;		nfsstats.read_bios++;		error = nfs_readrpc(vp, uiop, cr);		if (!error) {		    bp->b_validoff = 0;		    if (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 - (bp->b_blkno * DEV_BSIZE				+ diff);			if (len > 0) {			    len = min(len, uiop->uio_resid);			    bzero((char *)bp->b_data + diff, len);			    bp->b_validend = diff + len;			} else			    bp->b_validend = diff;		    } else			bp->b_validend = bp->b_bcount;		}		if (p && (vp->v_flag & VTEXT) &&			(((nmp->nm_flag & NFSMNT_NQNFS) &&			  NQNFS_CKINVALID(vp, np, NQL_READ) &&			  np->n_lrev != np->n_brev) ||			 (!(nmp->nm_flag & NFSMNT_NQNFS) &&			  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 = 0;		nfsstats.readlink_bios++;		error = nfs_readlinkrpc(vp, uiop, cr);		break;	    case VDIR:		uiop->uio_offset = bp->b_lblkno;		nfsstats.readdir_bios++;		if (VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NQNFS)		    error = nfs_readdirlookrpc(vp, uiop, cr);		else		    error = nfs_readdirrpc(vp, uiop, cr);		/*		 * Save offset cookie in b_blkno.		 */		bp->b_blkno = uiop->uio_offset;		break;	    case VNON:	    case VBLK:	    case VCHR:	    case VFIFO:	    case VBAD:	    case VSOCK:	    };	    if (error) {		bp->b_flags |= B_ERROR;		bp->b_error = error;	    }	} else {	    io.iov_len = uiop->uio_resid = bp->b_dirtyend		- bp->b_dirtyoff;	    uiop->uio_offset = (bp->b_blkno * DEV_BSIZE)		+ bp->b_dirtyoff;	    io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;	    uiop->uio_rw = UIO_WRITE;	    nfsstats.write_bios++;	    if (bp->b_flags & B_APPENDWRITE)		error = nfs_writerpc(vp, uiop, cr, IO_APPEND);	    else		error = nfs_writerpc(vp, uiop, cr, 0);	    bp->b_flags &= ~(B_WRITEINPROG | B_APPENDWRITE);	    /*	     * For an interrupted write, the buffer is still valid and the	     * write hasn't been pushed to the server yet, so we can't set	     * B_ERROR and report the interruption by setting B_EINTR. For	     * the B_ASYNC case, B_EINTR is not relevant, so the rpc attempt	     * is essentially a noop.	     */	    if (error == EINTR) {		bp->b_flags &= ~B_INVAL;		bp->b_flags |= B_DELWRI;		/*		 * Since for the B_ASYNC case, nfs_bwrite() has reassigned the		 * buffer to the clean list, we have to reassign it back to the		 * dirty one. Ugh.		 */		if (bp->b_flags & B_ASYNC)		    reassignbuf(bp, vp);		else		    bp->b_flags |= B_EINTR;	    } else {		if (error) {		    bp->b_flags |= B_ERROR;		    bp->b_error = np->n_error = error;		    np->n_flag |= NWRITEERR;		}		bp->b_dirtyoff = bp->b_dirtyend = 0;	    }	}	bp->b_resid = uiop->uio_resid;	biodone(bp);	return (error);}