diff options
author | jhb <jhb@FreeBSD.org> | 2007-04-25 20:34:55 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-04-25 20:34:55 +0000 |
commit | 961de35e83c5b4522bdaaa8fe3be8b5120d0fc83 (patch) | |
tree | 52b193a90456013b42312b128c3fab659710b2ec /sys/nfsclient | |
parent | da41f93f4d93e9881420ee5d5f9db232c738c718 (diff) | |
download | FreeBSD-src-961de35e83c5b4522bdaaa8fe3be8b5120d0fc83.zip FreeBSD-src-961de35e83c5b4522bdaaa8fe3be8b5120d0fc83.tar.gz |
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
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 13 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 4 |
2 files changed, 11 insertions, 6 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 445f7fd..e42a356 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -826,13 +826,11 @@ do_sync: 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 @@ again: 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); } diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 55d7b3f..28de49d 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -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), |