aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2006-10-10 18:26:18 +0000
committerAlan Cox <alc@FreeBSD.org>2006-10-10 18:26:18 +0000
commit1de11f1af33949375730415d40ba78ef1f8b73c3 (patch)
tree99ed2b58166c038dddc0366bb7fd8c69437a9a1f /sys/vm
parent0c341cb2962f0f3e42c892b9e0313095919c50f3 (diff)
downloadsrc-1de11f1af33949375730415d40ba78ef1f8b73c3.tar.gz
src-1de11f1af33949375730415d40ba78ef1f8b73c3.zip
Distinguish between two distinct kinds of errors from VOP_BMAP() in
vnode_pager_generic_getpages(): (1) that VOP_BMAP() is unsupported by the underlying file system and (2) an error in performing the VOP_BMAP(). Previously, vnode_pager_generic_getpages() assumed that all errors were of the first type. If, in fact, the error was of the second type, the likely outcome was for the process to become permanently blocked on a busy page. MFC after: 3 weeks Reviewed by: tegge
Notes
Notes: svn path=/head/; revision=163210
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vnode_pager.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index e683a840cd83..b4a9bf6b9120 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -701,7 +701,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
int runend;
struct buf *bp;
int count;
- int error = 0;
+ int error;
object = vp->v_object;
count = bytecount / PAGE_SIZE;
@@ -724,7 +724,8 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
/*
* if we can't bmap, use old VOP code
*/
- if (VOP_BMAP(vp, foff / bsize, &bo, &reqblock, NULL, NULL)) {
+ error = VOP_BMAP(vp, foff / bsize, &bo, &reqblock, NULL, NULL);
+ if (error == EOPNOTSUPP) {
VM_OBJECT_LOCK(object);
vm_page_lock_queues();
for (i = 0; i < count; i++)
@@ -736,6 +737,15 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
error = vnode_pager_input_old(object, m[reqpage]);
VM_OBJECT_UNLOCK(object);
return (error);
+ } else if (error != 0) {
+ VM_OBJECT_LOCK(object);
+ vm_page_lock_queues();
+ for (i = 0; i < count; i++)
+ if (i != reqpage)
+ vm_page_free(m[i]);
+ vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
+ return (VM_PAGER_ERROR);
/*
* if the blocksize is smaller than a page size, then use