Keep track of the number of in-progress async direct IO writes in the nfsnode.
Make fsync/close wait until all of these drain. Add a check to nfs_getpage() and nfs_putpage().
This commit is contained in:
parent
37b791151f
commit
5ef7d50da5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157557
@ -105,7 +105,8 @@ nfs_getpages(struct vop_getpages_args *ap)
|
||||
return VM_PAGER_ERROR;
|
||||
}
|
||||
|
||||
if (!nfs_directio_allow_mmap && (np->n_flag & NNONCACHE) &&
|
||||
if (nfs_directio_enable && !nfs_directio_allow_mmap &&
|
||||
(np->n_flag & NNONCACHE) &&
|
||||
(vp->v_type == VREG)) {
|
||||
printf("nfs_getpages: called on non-cacheable vnode??\n");
|
||||
return VM_PAGER_ERROR;
|
||||
@ -287,8 +288,8 @@ nfs_putpages(struct vop_putpages_args *ap)
|
||||
(void)nfs_fsinfo(nmp, vp, cred, td);
|
||||
}
|
||||
|
||||
if (!nfs_directio_allow_mmap && (np->n_flag & NNONCACHE) &&
|
||||
(vp->v_type == VREG))
|
||||
if (nfs_directio_enable && !nfs_directio_allow_mmap &&
|
||||
(np->n_flag & NNONCACHE) && (vp->v_type == VREG))
|
||||
printf("nfs_putpages: called on noncache-able vnode??\n");
|
||||
|
||||
for (i = 0; i < npages; i++)
|
||||
@ -1246,7 +1247,8 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg)
|
||||
goto out;
|
||||
error = vinvalbuf(vp, flags, td, 0, slptimeo);
|
||||
}
|
||||
np->n_flag &= ~NMODIFIED;
|
||||
if (np->n_directio_asyncwr == 0)
|
||||
np->n_flag &= ~NMODIFIED;
|
||||
out:
|
||||
if (old_lock != LK_EXCLUSIVE) {
|
||||
if (old_lock == LK_SHARED) {
|
||||
@ -1383,6 +1385,8 @@ nfs_asyncio(struct nfsmount *nmp, struct buf *bp, struct ucred *cred, struct thr
|
||||
BUF_KERNPROC(bp);
|
||||
TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist);
|
||||
nmp->nm_bufqlen++;
|
||||
if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE)
|
||||
VTONFS(bp->b_vp)->n_directio_asyncwr++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1409,6 +1413,15 @@ nfs_doio_directwrite(struct buf *bp)
|
||||
free(iov_base, M_NFSDIRECTIO);
|
||||
free(uiop->uio_iov, M_NFSDIRECTIO);
|
||||
free(uiop, M_NFSDIRECTIO);
|
||||
if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) {
|
||||
struct nfsnode *np = VTONFS(bp->b_vp);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
vdrop(bp->b_vp);
|
||||
bp->b_vp = NULL;
|
||||
relpbuf(bp, &nfs_pbuf_freecnt);
|
||||
|
@ -2880,6 +2880,21 @@ nfs_flush(struct vnode *vp, int waitfor, struct thread *td,
|
||||
VI_UNLOCK(vp);
|
||||
goto loop;
|
||||
}
|
||||
/*
|
||||
* Wait for all the async IO requests to drain
|
||||
*/
|
||||
while (np->n_directio_asyncwr > 0) {
|
||||
np->n_flag |= NFSYNCWAIT;
|
||||
error = nfs_tsleep(td, (caddr_t)&np->n_directio_asyncwr,
|
||||
slpflag | (PRIBIO + 1), "nfsfsync", 0);
|
||||
if (error) {
|
||||
if (nfs_sigintr(nmp, (struct nfsreq *)0, td)) {
|
||||
error = EINTR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
VI_UNLOCK(vp);
|
||||
if (np->n_flag & NWRITEERR) {
|
||||
@ -2887,7 +2902,7 @@ nfs_flush(struct vnode *vp, int waitfor, struct thread *td,
|
||||
np->n_flag &= ~NWRITEERR;
|
||||
}
|
||||
if (commit && vp->v_bufobj.bo_dirty.bv_cnt == 0 &&
|
||||
vp->v_bufobj.bo_numoutput == 0)
|
||||
vp->v_bufobj.bo_numoutput == 0 && np->n_directio_asyncwr == 0)
|
||||
np->n_flag &= ~NMODIFIED;
|
||||
done:
|
||||
if (bvec != NULL && bvec != bvec_on_stack)
|
||||
|
@ -126,6 +126,7 @@ struct nfsnode {
|
||||
uint32_t n_namelen;
|
||||
daddr_t ra_expect_lbn;
|
||||
int n_directio_opens;
|
||||
int n_directio_asyncwr;
|
||||
};
|
||||
|
||||
#define n_atim n_un1.nf_atim
|
||||
@ -149,6 +150,8 @@ struct nfsnode {
|
||||
#define NTRUNCATE 0x1000 /* Opened by nfs_setattr() */
|
||||
#define NSIZECHANGED 0x2000 /* File size has changed: need cache inval */
|
||||
#define NNONCACHE 0x4000 /* Node marked as noncacheable */
|
||||
#define NFSYNCWAIT 0x8000 /* fsync waiting for all directio async writes
|
||||
to drain */
|
||||
|
||||
/*
|
||||
* Convert between nfsnode pointers and vnode pointers
|
||||
|
Loading…
Reference in New Issue
Block a user