aboutsummaryrefslogtreecommitdiff
path: root/sys/nfsclient
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2007-04-25 20:34:55 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2007-04-25 20:34:55 +0000
commita1054d5776878bc928c4bdac2e5a51240e4a6d46 (patch)
tree52b193a90456013b42312b128c3fab659710b2ec /sys/nfsclient
parent1d80d190afabc31e780df9e0f5247145c9c03667 (diff)
downloadsrc-a1054d5776878bc928c4bdac2e5a51240e4a6d46.tar.gz
src-a1054d5776878bc928c4bdac2e5a51240e4a6d46.zip
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
Notes
Notes: svn path=/head/; revision=169043
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/nfs_bio.c13
-rw-r--r--sys/nfsclient/nfs_vnops.c4
2 files changed, 11 insertions, 6 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index 445f7fdf7c5f..e42a35653116 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 55d7b3fbac0a..28de49d5c97e 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),