summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-10-04 14:08:16 +0000
committerkib <kib@FreeBSD.org>2008-10-04 14:08:16 +0000
commit79819484b6350a3bd87371c60d3daf8ca35dc0aa (patch)
treeb88376d7f306c922d88bb950b89873ad251e576b /sys/fs
parent766a91b7a6d62bed578f909e51629de4176bc87f (diff)
downloadFreeBSD-src-79819484b6350a3bd87371c60d3daf8ca35dc0aa.zip
FreeBSD-src-79819484b6350a3bd87371c60d3daf8ca35dc0aa.tar.gz
Change the linprocfs <pid>/maps and procfs <pid>/map handlers to use
sbuf instead of doing uiomove. This allows for reads from non-zero offsets to work. Patch is forward-ported des@' one, and was adopted to current code by dchagin@ and me. Reviewed by: des (linprocfs part) PR: kern/101453 MFC after: 1 week
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/procfs/procfs_map.c36
1 files changed, 7 insertions, 29 deletions
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index 95a4503..1a9e4aa 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -45,6 +45,7 @@
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/sbuf.h>
#include <sys/uio.h>
#include <sys/vnode.h>
@@ -81,14 +82,11 @@ extern struct sysentvec ia32_freebsd_sysvec;
int
procfs_doprocmap(PFS_FILL_ARGS)
{
- int len;
int error, vfslocked;
vm_map_t map = &p->p_vmspace->vm_map;
- vm_map_entry_t entry, tmp_entry;
+ vm_map_entry_t entry;
struct vnode *vp;
- char mebuffer[MEBUFFERSIZE];
char *fullpath, *freepath;
- unsigned int last_timestamp;
#ifdef COMPAT_IA32
int wrap32 = 0;
#endif
@@ -102,9 +100,6 @@ procfs_doprocmap(PFS_FILL_ARGS)
if (uio->uio_rw != UIO_READ)
return (EOPNOTSUPP);
- if (uio->uio_offset != 0)
- return (0);
-
#ifdef COMPAT_IA32
if (curthread->td_proc->p_sysent == &ia32_freebsd_sysvec) {
if (p->p_sysent != &ia32_freebsd_sysvec)
@@ -114,9 +109,8 @@ procfs_doprocmap(PFS_FILL_ARGS)
#endif
vm_map_lock_read(map);
- for (entry = map->header.next;
- ((uio->uio_resid > 0) && (entry != &map->header));
- entry = entry->next) {
+ for (entry = map->header.next; entry != &map->header;
+ entry = entry->next) {
vm_object_t obj, tobj, lobj;
int ref_count, shadow_count, flags;
vm_offset_t addr;
@@ -198,7 +192,7 @@ procfs_doprocmap(PFS_FILL_ARGS)
* format:
* start, end, resident, private resident, cow, access, type.
*/
- snprintf(mebuffer, sizeof mebuffer,
+ error = sbuf_printf(sb,
"0x%lx 0x%lx %d %d %p %s%s%s %d %d 0x%x %s %s %s %s\n",
(u_long)entry->start, (u_long)entry->end,
resident, privateresident,
@@ -218,25 +212,9 @@ procfs_doprocmap(PFS_FILL_ARGS)
if (freepath != NULL)
free(freepath, M_TEMP);
- len = strlen(mebuffer);
- if (len > uio->uio_resid) {
- error = EFBIG;
- break;
- }
- last_timestamp = map->timestamp;
- vm_map_unlock_read(map);
- error = uiomove(mebuffer, len, uio);
- vm_map_lock_read(map);
- if (error)
+ if (error == -1) {
+ error = 0;
break;
- if (last_timestamp + 1 != map->timestamp) {
- /*
- * Look again for the entry because the map was
- * modified while it was unlocked. Specifically,
- * the entry may have been clipped, merged, or deleted.
- */
- vm_map_lookup_entry(map, addr - 1, &tmp_entry);
- entry = tmp_entry;
}
}
vm_map_unlock_read(map);
OpenPOWER on IntegriCloud