Make tmpfs_getpages behave as genfs_getpages by ignoring the input pages
array's contents and returning all the requested pages. Otherwise there are problems (accessing invalid memory) when the a_m vector is passed uninitialized as the NFS server code does. Fixes PR kern/34959. Note that this is not a "real" fix. While this makes tmpfs's getpages operation consistent with the behavior of other file systems, it does not resolve the different semantics between uvn_get and uao_get as described in PR kern/32166. I'm adding a comment in the code mentioning exactly this so that it can be reviewed when this last problem is addressed.
This commit is contained in:
parent
8e03013027
commit
51634dfd25
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tmpfs_vnops.c,v 1.27 2006/10/30 15:23:20 jmmv Exp $ */
|
||||
/* $NetBSD: tmpfs_vnops.c,v 1.28 2006/11/02 15:35:25 jmmv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.27 2006/10/30 15:23:20 jmmv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.28 2006/11/02 15:35:25 jmmv Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dirent.h>
|
||||
|
@ -1383,6 +1383,7 @@ tmpfs_getpages(void *v)
|
|||
int flags = ((struct vop_getpages_args *)v)->a_flags;
|
||||
|
||||
int error;
|
||||
int i;
|
||||
struct tmpfs_node *node;
|
||||
struct uvm_object *uobj;
|
||||
int npages = *count;
|
||||
|
@ -1418,9 +1419,31 @@ tmpfs_getpages(void *v)
|
|||
|
||||
simple_unlock(&vp->v_interlock);
|
||||
|
||||
/*
|
||||
* Make sure that the array on which we will store the
|
||||
* gotten pages is clean. Otherwise uao_get (pointed to by
|
||||
* the pgo_get below) gets confused and does not return the
|
||||
* appropriate pages.
|
||||
*
|
||||
* XXX This shall be revisited when kern/32166 is addressed
|
||||
* because the loop to clean m[i] will most likely be redundant
|
||||
* as well as the PGO_ALLPAGES flag.
|
||||
*/
|
||||
if (m != NULL)
|
||||
for (i = 0; i < npages; i++)
|
||||
m[i] = NULL;
|
||||
simple_lock(&uobj->vmobjlock);
|
||||
error = (*uobj->pgops->pgo_get)(uobj, offset, m, &npages, centeridx,
|
||||
access_type, advice, flags);
|
||||
access_type, advice, flags | PGO_ALLPAGES);
|
||||
#if defined(DEBUG)
|
||||
{
|
||||
/* Make sure that all the pages we return are valid. */
|
||||
int dbgi;
|
||||
if (error == 0 && m != NULL)
|
||||
for (dbgi = 0; dbgi < npages; dbgi++)
|
||||
KASSERT(m[dbgi] != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue