Subject: genfs_getpages and MAX_READ_AHEAD
To: None <tech-kern@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-kern
Date: 06/11/2003 10:36:09
currently, genfs_getpages has a limit of number of pages.
it's annoying because a caller should consider filesystem's block size
to avoid assertion failure.

how about following patch?
although using alloca here is ...yucky,
there're already variable-sized arrays around.

YAMAMOTO Takashi


Index: genfs_vnops.c
===================================================================
--- genfs_vnops.c	(revision 84)
+++ genfs_vnops.c	(working copy)
@@ -479,7 +479,8 @@
 	struct vnode *devvp;
 	struct genfs_node *gp = VTOG(vp);
 	struct uvm_object *uobj = &vp->v_uobj;
-	struct vm_page *pg, *pgs[MAX_READ_AHEAD];
+	struct vm_page *pg, **pgs;
+	int pgs_size;
 	struct ucred *cred = curproc->p_ucred;		/* XXXUBC curlwp */
 	boolean_t async = (flags & PGO_SYNCIO) == 0;
 	boolean_t write = (ap->a_access_type & VM_PROT_WRITE) != 0;
@@ -563,10 +564,16 @@
 	endoffset = MIN(endoffset, round_page(memeof));
 	ridx = (origoffset - startoffset) >> PAGE_SHIFT;
 
-	memset(pgs, 0, sizeof(pgs));
+	pgs_size = sizeof(struct vm_page *) *
+	    ((endoffset - startoffset) >> PAGE_SHIFT);
+	pgs = alloca(pgs_size);
+	if (pgs == NULL) {
+		simple_unlock(&uobj->vmobjlock);
+		return (ENOMEM);
+	}
+	memset(pgs, 0, pgs_size);
 	UVMHIST_LOG(ubchist, "ridx %d npages %d startoff %ld endoff %ld",
 	    ridx, npages, startoffset, endoffset);
-	KASSERT(&pgs[ridx + npages] <= &pgs[MAX_READ_AHEAD]);
 	if (uvn_findpages(uobj, origoffset, &npages, &pgs[ridx],
 	    async ? UFP_NOWAIT : UFP_ALL) != orignpages) {
 		KASSERT(async != 0);
@@ -626,7 +633,7 @@
 		 */
 
 		genfs_rel_pages(&pgs[ridx], orignpages);
-		memset(pgs, 0, sizeof(pgs));
+		memset(pgs, 0, pgs_size);
 
 		UVMHIST_LOG(ubchist, "reset npages start 0x%x end 0x%x",
 		    startoffset, endoffset, 0,0);