MFC: Do not set B_NOCACHE on buffers when releasing them in flushbuflist().
If B_NOCACHE is set the pages of vm backed buffers will be invalidated. However clean buffers can be backed by dirty VM pages so invalidating them can lead to data loss. Add support for flush dirty page in the data invalidation function of some network file systems. This fixes data losses during vnode recycling (and other code paths using invalbuf(*,V_SAVE,*,*)) for data written using an mmaped file.
This commit is contained in:
parent
f1e13c4788
commit
cb722c46dc
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user