Handle files with a large number of mappings gracefully. Reported by Nicholas
Joly.
This commit is contained in:
parent
0dca08adcb
commit
3bccc0f766
|
@ -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
|
* Copyright (c) 1993
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.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>
|
#include <uvm/uvm.h>
|
||||||
|
|
||||||
#define BUFFERSIZE (64 * 1024)
|
#define BUFFERSIZE (64 * 1024)
|
||||||
|
#define MAXBUFFERSIZE (256 * 1024)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The map entries can *almost* be read with programs like cat. However,
|
* 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 vmspace *vm;
|
||||||
struct vm_map *map;
|
struct vm_map *map;
|
||||||
struct vm_map_entry *entry;
|
struct vm_map_entry *entry;
|
||||||
char *buffer;
|
char *buffer = NULL;
|
||||||
|
size_t bufsize = BUFFERSIZE;
|
||||||
char *path;
|
char *path;
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct vattr va;
|
struct vattr va;
|
||||||
|
@ -133,7 +135,6 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
buffer = malloc(BUFFERSIZE, M_TEMP, M_WAITOK);
|
|
||||||
if (linuxmode != 0)
|
if (linuxmode != 0)
|
||||||
path = malloc(MAXPATHLEN * 4, M_TEMP, M_WAITOK);
|
path = malloc(MAXPATHLEN * 4, M_TEMP, M_WAITOK);
|
||||||
else
|
else
|
||||||
|
@ -145,6 +146,8 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
|
||||||
map = &vm->vm_map;
|
map = &vm->vm_map;
|
||||||
vm_map_lock_read(map);
|
vm_map_lock_read(map);
|
||||||
|
|
||||||
|
again:
|
||||||
|
buffer = malloc(bufsize, M_TEMP, M_WAITOK);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
for (entry = map->header.next; entry != &map->header;
|
for (entry = map->header.next; entry != &map->header;
|
||||||
entry = entry->next) {
|
entry = entry->next) {
|
||||||
|
@ -195,6 +198,15 @@ procfs_domap(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
|
||||||
entry->inheritance, entry->wired_count,
|
entry->inheritance, entry->wired_count,
|
||||||
entry->advice);
|
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);
|
vm_map_unlock_read(map);
|
||||||
|
|
Loading…
Reference in New Issue