diff options
author | kib <kib@FreeBSD.org> | 2011-06-01 21:00:28 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2011-06-01 21:00:28 +0000 |
commit | ad5bd0652340908efab201a5a95766c83a96160a (patch) | |
tree | 07e1defe92d7e0b4f536a6246e42367ce49158b2 /sys/fs | |
parent | fa6dbdd4a2c067d514a8442f406a37ad52fb9be7 (diff) | |
download | FreeBSD-src-ad5bd0652340908efab201a5a95766c83a96160a.zip FreeBSD-src-ad5bd0652340908efab201a5a95766c83a96160a.tar.gz |
In the VOP_PUTPAGES() implementations, change the default error from
VM_PAGER_AGAIN to VM_PAGER_ERROR for the uwritten pages. Return
VM_PAGER_AGAIN for the partially written page. Always forward at least
one page in the loop of vm_object_page_clean().
VM_PAGER_ERROR causes the page reactivation and does not clear the
page dirty state, so the write is not lost.
The change fixes an infinite loop in vm_object_page_clean() when the
filesystem returns permanent errors for some page writes.
Reported and tested by: gavin
Reviewed by: alc, rmacklem
MFC after: 1 week
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/nfsclient/nfs_clbio.c | 15 | ||||
-rw-r--r-- | sys/fs/nwfs/nwfs_io.c | 11 | ||||
-rw-r--r-- | sys/fs/smbfs/smbfs_io.c | 11 |
3 files changed, 10 insertions, 27 deletions
diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index fee8b05..95138ec 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -302,7 +302,7 @@ ncl_putpages(struct vop_putpages_args *ap) } for (i = 0; i < npages; i++) - rtvals[i] = VM_PAGER_AGAIN; + rtvals[i] = VM_PAGER_ERROR; /* * When putting pages, do not extend file past EOF. @@ -345,16 +345,9 @@ ncl_putpages(struct vop_putpages_args *ap) pmap_qremove(kva, npages); relpbuf(bp, &ncl_pbuf_freecnt); - if (!error) { - int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; - for (i = 0; i < nwritten; i++) { - rtvals[i] = VM_PAGER_OK; - vm_page_undirty(pages[i]); - } - if (must_commit) { - ncl_clearcommit(vp->v_mount); - } - } + vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid); + if (must_commit) + ncl_clearcommit(vp->v_mount); return rtvals[0]; } diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c index 141c52e..d764f79 100644 --- a/sys/fs/nwfs/nwfs_io.c +++ b/sys/fs/nwfs/nwfs_io.c @@ -544,7 +544,7 @@ nwfs_putpages(ap) npages = btoc(count); for (i = 0; i < npages; i++) { - rtvals[i] = VM_PAGER_AGAIN; + rtvals[i] = VM_PAGER_ERROR; } bp = getpbuf(&nwfs_pbuf_freecnt); @@ -569,13 +569,8 @@ nwfs_putpages(ap) pmap_qremove(kva, npages); relpbuf(bp, &nwfs_pbuf_freecnt); - if (!error) { - int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; - for (i = 0; i < nwritten; i++) { - rtvals[i] = VM_PAGER_OK; - vm_page_undirty(pages[i]); - } - } + if (!error) + vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid); return rtvals[0]; #endif /* NWFS_RWCACHE */ } diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index 6c02fc6..4599a6f 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -609,7 +609,7 @@ smbfs_putpages(ap) npages = btoc(count); for (i = 0; i < npages; i++) { - rtvals[i] = VM_PAGER_AGAIN; + rtvals[i] = VM_PAGER_ERROR; } bp = getpbuf(&smbfs_pbuf_freecnt); @@ -639,13 +639,8 @@ smbfs_putpages(ap) relpbuf(bp, &smbfs_pbuf_freecnt); - if (!error) { - int nwritten = round_page(count - uio.uio_resid) / PAGE_SIZE; - for (i = 0; i < nwritten; i++) { - rtvals[i] = VM_PAGER_OK; - vm_page_undirty(pages[i]); - } - } + if (!error) + vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid); return rtvals[0]; #endif /* SMBFS_RWGENERIC */ } |