Handle files with a large number of mappings gracefully. Reported by Nicholas

Joly.
This commit is contained in:
christos 2008-07-25 17:40:24 +00:00
parent 0dca08adcb
commit 3bccc0f766
1 changed files with 16 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: procfs_map.c,v 1.34 2007/12/15 23:52:00 christos Exp $ */
/* $NetBSD: procfs_map.c,v 1.35 2008/07/25 17:40:24 christos Exp $ */
/*
* Copyright (c) 1993
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: procfs_map.c,v 1.34 2007/12/15 23:52:00 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: procfs_map.c,v 1.35 2008/07/25 17:40:24 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -92,6 +92,7 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_map.c,v 1.34 2007/12/15 23:52:00 christos Exp
#include <uvm/uvm.h>
#define BUFFERSIZE (64 * 1024)
#define MAXBUFFERSIZE (256 * 1024)
/*
* The map entries can *almost* be read with programs like cat. However,
@ -111,7 +112,8 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
struct vmspace *vm;
struct vm_map *map;
struct vm_map_entry *entry;
char *buffer;
char *buffer = NULL;
size_t bufsize = BUFFERSIZE;
char *path;
struct vnode *vp;
struct vattr va;
@ -133,7 +135,6 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
error = 0;
buffer = malloc(BUFFERSIZE, M_TEMP, M_WAITOK);
if (linuxmode != 0)
path = malloc(MAXPATHLEN * 4, M_TEMP, M_WAITOK);
else
@ -145,6 +146,8 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
map = &vm->vm_map;
vm_map_lock_read(map);
again:
buffer = malloc(bufsize, M_TEMP, M_WAITOK);
pos = 0;
for (entry = map->header.next; entry != &map->header;
entry = entry->next) {
@ -195,6 +198,15 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
entry->inheritance, entry->wired_count,
entry->advice);
}
if (pos >= bufsize) {
bufsize <<= 1;
if (bufsize > MAXBUFFERSIZE) {
error = ENOMEM;
goto out;
}
free(buffer, M_TEMP);
goto again;
}
}
vm_map_unlock_read(map);