summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-10-10 18:26:18 +0000
committeralc <alc@FreeBSD.org>2006-10-10 18:26:18 +0000
commit26e34ffad0d340f779d3225a5408fc8ad6779240 (patch)
tree99ed2b58166c038dddc0366bb7fd8c69437a9a1f /sys
parentc75170f4a7f8a32454b70d10dbb9106f27879cc8 (diff)
downloadFreeBSD-src-26e34ffad0d340f779d3225a5408fc8ad6779240.zip
FreeBSD-src-26e34ffad0d340f779d3225a5408fc8ad6779240.tar.gz
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
Diffstat (limited to 'sys')
-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 e683a84..b4a9bf6 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
OpenPOWER on IntegriCloud