diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c index 0b697560ccd9..aecf3905b517 100644 --- a/sys/fs/nwfs/nwfs_io.c +++ b/sys/fs/nwfs/nwfs_io.c @@ -611,6 +611,13 @@ nwfs_vinvalbuf(vp, td) return EINTR; } np->n_flag |= NFLUSHINPROG; + + if (vp->v_bufobj.bo_object != NULL) { + VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); + VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + } + error = vinvalbuf(vp, V_SAVE, td, PCATCH, 0); while (error) { if (error == ERESTART || error == EINTR) { diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index a5161945c923..f9a129dee553 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -683,6 +683,13 @@ smbfs_vinvalbuf(struct vnode *vp, struct thread *td) return EINTR; } np->n_flag |= NFLUSHINPROG; + + if (vp->v_bufobj.bo_object != NULL) { + VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); + VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + } + error = vinvalbuf(vp, V_SAVE, td, PCATCH, 0); while (error) { if (error == ERESTART || error == EINTR) { diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 04e4d78962fb..e1d8a3a2add4 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1162,7 +1162,7 @@ flushbuflist(bufv, flags, bo, slpflag, slptimeo) return (EAGAIN); /* XXX: why not loop ? */ } bremfree(bp); - bp->b_flags |= (B_INVAL | B_NOCACHE | B_RELBUF); + bp->b_flags |= (B_INVAL | B_RELBUF); bp->b_flags &= ~B_ASYNC; brelse(bp); BO_LOCK(bo); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index e1850af63a68..4d10374e39e3 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -1314,6 +1314,19 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg) /* * Now, flush as required. */ + if ((flags & V_SAVE) && (vp->v_bufobj.bo_object != NULL)) { + VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); + VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + /* + * If the page clean was interrupted, fail the invalidation. + * Not doing so, we run the risk of losing dirty pages in the + * vinvalbuf() call below. + */ + if (intrflg && (error = nfs_sigintr(nmp, NULL, td))) + goto out; + } + error = vinvalbuf(vp, flags, td, slpflag, 0); while (error) { if (intrflg && (error = nfs_sigintr(nmp, NULL, td)))