Various fixes to the NFS Directio support.

- Fix for a bug where a close would not wait for all (directio)
  dirty buffers to drain. The nfsnode was not marked NMODIFIED
  when there were directio dirtied buffers pending, causing this.
- No reason to vhold/vrele the vp when enqueueing DirectIO requests
  for the nfsiods. The vnode can't really go way since the close
  has to wait for these requests to drain.

MFC after:	1 week
Submitted by:	mohans
This commit is contained in:
John Baldwin 2007-04-25 20:34:55 +00:00
parent 1d80d190af
commit a1054d5776
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169043
2 changed files with 11 additions and 6 deletions

View File

@ -826,13 +826,11 @@ nfs_directio_write(vp, uiop, cred, ioflag)
bp->b_wcred = NOCRED;
bp->b_caller1 = (void *)t_uio;
bp->b_vp = vp;
vhold(vp);
error = nfs_asyncio(nmp, bp, NOCRED, td);
if (error) {
free(t_iov->iov_base, M_NFSDIRECTIO);
free(t_iov, M_NFSDIRECTIO);
free(t_uio, M_NFSDIRECTIO);
vdrop(bp->b_vp);
bp->b_vp = NULL;
relpbuf(bp, &nfs_pbuf_freecnt);
if (error == EINTR)
@ -1470,6 +1468,7 @@ nfs_asyncio(struct nfsmount *nmp, struct buf *bp, struct ucred *cred, struct thr
nmp->nm_bufqlen++;
if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) {
mtx_lock(&(VTONFS(bp->b_vp))->n_mtx);
VTONFS(bp->b_vp)->n_flag |= NMODIFIED;
VTONFS(bp->b_vp)->n_directio_asyncwr++;
mtx_unlock(&(VTONFS(bp->b_vp))->n_mtx);
}
@ -1506,13 +1505,15 @@ nfs_doio_directwrite(struct buf *bp)
struct nfsnode *np = VTONFS(bp->b_vp);
mtx_lock(&np->n_mtx);
np->n_directio_asyncwr--;
if ((np->n_flag & NFSYNCWAIT) && np->n_directio_asyncwr == 0) {
np->n_flag &= ~NFSYNCWAIT;
wakeup((caddr_t)&np->n_directio_asyncwr);
if (np->n_directio_asyncwr == 0) {
VTONFS(bp->b_vp)->n_flag &= ~NMODIFIED;
if ((np->n_flag & NFSYNCWAIT)) {
np->n_flag &= ~NFSYNCWAIT;
wakeup((caddr_t)&np->n_directio_asyncwr);
}
}
mtx_unlock(&np->n_mtx);
}
vdrop(bp->b_vp);
bp->b_vp = NULL;
relpbuf(bp, &nfs_pbuf_freecnt);
}

View File

@ -603,6 +603,10 @@ nfs_close(struct vop_close_args *ap)
}
mtx_unlock(&np->n_mtx);
}
if (nfs_directio_enable)
KASSERT((np->n_directio_asyncwr == 0),
("nfs_close: dirty unflushed (%d) directio buffers\n",
np->n_directio_asyncwr));
if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) {
mtx_lock(&np->n_mtx);
KASSERT((np->n_directio_opens > 0),