Module Name:    src
Committed By:   pooka
Date:           Mon Sep  6 21:33:07 UTC 2010

Modified Files:
        src/sys/rump/librump/rumpvfs: vm_vfs.c

Log Message:
Make the pager loops more resilient against the aobj pager which is
lazy and doesn't like to return anything except the bare minimum.
(forgot to commit this earlier)


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/rump/librump/rumpvfs/vm_vfs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpvfs/vm_vfs.c
diff -u src/sys/rump/librump/rumpvfs/vm_vfs.c:1.19 src/sys/rump/librump/rumpvfs/vm_vfs.c:1.20
--- src/sys/rump/librump/rumpvfs/vm_vfs.c:1.19	Mon Sep  6 17:56:56 2010
+++ src/sys/rump/librump/rumpvfs/vm_vfs.c	Mon Sep  6 21:33:07 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_vfs.c,v 1.19 2010/09/06 17:56:56 pooka Exp $	*/
+/*	$NetBSD: vm_vfs.c,v 1.20 2010/09/06 21:33:07 pooka Exp $	*/
 
 /*
  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.19 2010/09/06 17:56:56 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_vfs.c,v 1.20 2010/09/06 21:33:07 pooka Exp $");
 
 #include <sys/param.h>
 
@@ -102,7 +102,7 @@
 	if (maxpages == 0)
 		return;
 
-	pgs = kmem_zalloc(maxpages * sizeof(pgs), KM_SLEEP);
+	pgs = kmem_alloc(maxpages * sizeof(pgs), KM_SLEEP);
 	while (len) {
 		npages = MIN(maxpages, round_page(len) >> PAGE_SHIFT);
 		memset(pgs, 0, npages * sizeof(struct vm_page *));
@@ -113,15 +113,20 @@
 		KASSERT(npages > 0);
 
 		for (i = 0; i < npages; i++) {
+			struct vm_page *pg;
 			uint8_t *start;
 			size_t chunkoff, chunklen;
 
+			pg = pgs[i];
+			if (pg == NULL)
+				break;
+
 			chunkoff = off & PAGE_MASK;
 			chunklen = MIN(PAGE_SIZE - chunkoff, len);
-			start = (uint8_t *)pgs[i]->uanon + chunkoff;
+			start = (uint8_t *)pg->uanon + chunkoff;
 
 			memset(start, 0, chunklen);
-			pgs[i]->flags &= ~PG_CLEAN;
+			pg->flags &= ~PG_CLEAN;
 
 			off += chunklen;
 			len -= chunklen;
@@ -146,7 +151,7 @@
 	int i, rv, pagerflags;
 
 	pgalloc = npages * sizeof(pgs);
-	pgs = kmem_zalloc(pgalloc, KM_SLEEP);
+	pgs = kmem_alloc(pgalloc, KM_SLEEP);
 
 	pagerflags = PAGERFLAGS;
 	if (flags & UBC_WRITE)
@@ -155,24 +160,31 @@
 		pagerflags |= PGO_OVERWRITE;
 
 	do {
+		npages = len2npages(uio->uio_offset, todo);
+		memset(pgs, 0, pgalloc);
 		mutex_enter(&uobj->vmobjlock);
-		rv = uobj->pgops->pgo_get(uobj, uio->uio_offset & ~PAGE_MASK,
+		rv = uobj->pgops->pgo_get(uobj, trunc_page(uio->uio_offset),
 		    pgs, &npages, 0, VM_PROT_READ | VM_PROT_WRITE, 0,
 		    pagerflags);
 		if (rv)
 			goto out;
 
 		for (i = 0; i < npages; i++) {
+			struct vm_page *pg;
 			size_t xfersize;
 			off_t pageoff;
 
+			pg = pgs[i];
+			if (pg == NULL)
+				break;
+
 			pageoff = uio->uio_offset & PAGE_MASK;
 			xfersize = MIN(MIN(todo, PAGE_SIZE), PAGE_SIZE-pageoff);
 			KASSERT(xfersize > 0);
-			uiomove((uint8_t *)pgs[i]->uanon + pageoff,
+			uiomove((uint8_t *)pg->uanon + pageoff,
 			    xfersize, uio);
 			if (uio->uio_rw == UIO_WRITE)
-				pgs[i]->flags &= ~(PG_CLEAN | PG_FAKE);
+				pg->flags &= ~(PG_CLEAN | PG_FAKE);
 			todo -= xfersize;
 		}
 		uvm_page_unbusy(pgs, npages);

Reply via email to