summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-06-01 21:00:28 +0000
committerkib <kib@FreeBSD.org>2011-06-01 21:00:28 +0000
commitad5bd0652340908efab201a5a95766c83a96160a (patch)
tree07e1defe92d7e0b4f536a6246e42367ce49158b2 /sys/fs
parentfa6dbdd4a2c067d514a8442f406a37ad52fb9be7 (diff)
downloadFreeBSD-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.c15
-rw-r--r--sys/fs/nwfs/nwfs_io.c11
-rw-r--r--sys/fs/smbfs/smbfs_io.c11
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 */
}
OpenPOWER on IntegriCloud