Page MenuHomeFreeBSD

D20390.id58333.diff
No OneTemporary

D20390.id58333.diff

Index: sys/kern/kern_proc.c
===================================================================
--- sys/kern/kern_proc.c
+++ sys/kern/kern_proc.c
@@ -62,6 +62,7 @@
#include <sys/sbuf.h>
#include <sys/sysent.h>
#include <sys/sched.h>
+#include <sys/shm.h>
#include <sys/smp.h>
#include <sys/stack.h>
#include <sys/stat.h>
@@ -2444,6 +2445,27 @@
PA_UNLOCK_COND(locked_pa);
}
+/*
+ * Build the pseudo-path for SysV and POSIX shm, if appropriate.
+ */
+static void
+get_fullpath(char *path, size_t size, vm_object_t object)
+{
+ void *data;
+
+ switch (vm_object_path_info(object, &data)) {
+ case OBJPATH_NONE:
+ case OBJPATH_VNODE:
+ break;
+ case OBJPATH_SHMP:
+ shm_fullpath(path, size, data);
+ break;
+ case OBJPATH_SHMS:
+ sysvshm_fullpath(path, size, data);
+ break;
+ }
+}
+
/*
* Must be called with the process locked and will return unlocked.
*/
@@ -2536,12 +2558,14 @@
last_timestamp = map->timestamp;
vm_map_unlock_read(map);
- freepath = NULL;
- fullpath = "";
+ kve->kve_path[0] = '\0';
if (lobj != NULL) {
kve->kve_type = vm_object_kvme_type(lobj, &vp);
if (vp != NULL)
vref(vp);
+ else get_fullpath(kve->kve_path,
+ sizeof(kve->kve_path),
+ lobj);
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
@@ -2549,6 +2573,8 @@
kve->kve_shadow_count = obj->shadow_count;
VM_OBJECT_RUNLOCK(obj);
if (vp != NULL) {
+ freepath = NULL;
+ fullpath = "";
vn_fullpath(curthread, vp, &fullpath,
&freepath);
kve->kve_vn_type = vntype_to_kinfo(vp->v_type);
@@ -2568,6 +2594,9 @@
kve->kve_status = KF_ATTR_VALID;
}
vput(vp);
+ strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path));
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
}
} else {
kve->kve_type = KVME_TYPE_NONE;
@@ -2575,10 +2604,6 @@
kve->kve_shadow_count = 0;
}
- strlcpy(kve->kve_path, fullpath, sizeof(kve->kve_path));
- if (freepath != NULL)
- free(freepath, M_TEMP);
-
/* Pack record size down */
if ((flags & KERN_VMMAP_PACK_KINFO) != 0)
kve->kve_structsize =
Index: sys/kern/sysv_shm.c
===================================================================
--- sys/kern/sysv_shm.c
+++ sys/kern/sysv_shm.c
@@ -755,6 +755,7 @@
VM_OBJECT_WLOCK(shm_object);
vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shm_object, OBJ_COLORED | OBJ_NOSPLIT);
+ vm_object_set_path_info(shm_object, OBJPATH_SHMS, shmseg);
VM_OBJECT_WUNLOCK(shm_object);
shmseg->object = shm_object;
@@ -779,6 +780,17 @@
return (0);
}
+void
+sysvshm_fullpath(char *path, size_t size, void *data)
+{
+ struct shmid_kernel *shmseg;
+
+ shmseg = (struct shmid_kernel *) data;
+
+ if (shmseg != NULL && shmseg->u.shm_perm.key != IPC_PRIVATE)
+ snprintf(path, size, "%ld", shmseg->u.shm_perm.key);
+}
+
#ifndef _SYS_SYSPROTO_H_
struct shmget_args {
key_t key;
Index: sys/kern/uipc_shm.c
===================================================================
--- sys/kern/uipc_shm.c
+++ sys/kern/uipc_shm.c
@@ -558,6 +558,7 @@
KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate"));
shmfd->shm_object->pg_color = 0;
VM_OBJECT_WLOCK(shmfd->shm_object);
+ vm_object_set_path_info(shmfd->shm_object, OBJPATH_SHMP, shmfd);
vm_object_clear_flag(shmfd->shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shmfd->shm_object, OBJ_COLORED | OBJ_NOSPLIT);
VM_OBJECT_WUNLOCK(shmfd->shm_object);
@@ -686,6 +687,10 @@
FREAD | FWRITE);
if (error)
return (error);
+ VM_OBJECT_WLOCK(map->sm_shmfd->shm_object);
+ vm_object_set_path_info(map->sm_shmfd->shm_object,
+ OBJPATH_NONE, NULL);
+ VM_OBJECT_WUNLOCK(map->sm_shmfd->shm_object);
map->sm_shmfd->shm_path = NULL;
LIST_REMOVE(map, sm_link);
shm_drop(map->sm_shmfd);
@@ -1095,6 +1100,17 @@
return (0);
}
+void
+shm_fullpath(char *path, size_t size, void *data)
+{
+ struct shmfd *shmfd = (struct shmfd *) data;
+
+ if (shmfd->shm_path == NULL)
+ strlcpy(path, "", size);
+ else
+ strlcpy(path, shmfd->shm_path, size);
+}
+
static int
shm_fill_kinfo_locked(struct shmfd *shmfd, struct kinfo_file *kif, bool list)
{
Index: sys/sys/mman.h
===================================================================
--- sys/sys/mman.h
+++ sys/sys/mman.h
@@ -242,6 +242,7 @@
struct shmfd *shm_hold(struct shmfd *shmfd);
void shm_drop(struct shmfd *shmfd);
int shm_dotruncate(struct shmfd *shmfd, off_t length);
+void shm_fullpath(char *path, size_t size, void *data);
extern struct fileops shm_ops;
#else /* !_KERNEL */
Index: sys/sys/shm.h
===================================================================
--- sys/sys/shm.h
+++ sys/sys/shm.h
@@ -155,6 +155,7 @@
void shmexit(struct vmspace *);
void shmfork(struct proc *, struct proc *);
+void sysvshm_fullpath(char *path, size_t size, void *data);
#else /* !_KERNEL */
Index: sys/vm/vm_object.h
===================================================================
--- sys/vm/vm_object.h
+++ sys/vm/vm_object.h
@@ -168,6 +168,15 @@
void *swp_tmpfs;
struct pctrie swp_blks;
} swp;
+
+ /*
+ * For OBJT_PHYS (no pager), OBJT_DEFAULT and OBJT_SWAP if
+ * not OBJ_TMPFS, we can store a back pointer that can be
+ * used to genenrate a path for procstat.
+ */
+ struct {
+ void *data;
+ } path_info;
} un_pager;
struct ucred *cred;
vm_ooffset_t charge;
@@ -193,6 +202,18 @@
#define OBJ_DISCONNECTWNT 0x4000 /* disconnect from vnode wanted */
#define OBJ_TMPFS 0x8000 /* has tmpfs vnode allocated */
+/*
+ * If the OBJ_TMPFS flag is not set, we overload the OBJ_TMPS_DIRTY flag to
+ * select between SysV and POSIX shm path_info.
+ */
+#define OBJ_SYSV_SHM OBJ_TMPFS_DIRTY
+
+/* Values returned by vm_object_path_info. */
+#define OBJPATH_NONE 0x0 /* no path info available */
+#define OBJPATH_VNODE 0x1 /* use vn_fullpath on vnode */
+#define OBJPATH_SHMS 0x2 /* use sysvshm_fullpath */
+#define OBJPATH_SHMP 0x3 /* use shm_fullpath */
+
/*
* Helpers to perform conversion between vm_object page indexes and offsets.
* IDX_TO_OFF() converts an index into an offset.
@@ -324,6 +345,9 @@
void vm_object_set_writeable_dirty (vm_object_t);
void vm_object_init (void);
int vm_object_kvme_type(vm_object_t object, struct vnode **vpp);
+int vm_object_path_info(vm_object_t object, void **data);
+void vm_object_set_path_info(vm_object_t object, int path_info_type,
+ void *data);
void vm_object_madvise(vm_object_t, vm_pindex_t, vm_pindex_t, int);
boolean_t vm_object_page_clean(vm_object_t object, vm_ooffset_t start,
vm_ooffset_t end, int flags);
Index: sys/vm/vm_object.c
===================================================================
--- sys/vm/vm_object.c
+++ sys/vm/vm_object.c
@@ -256,6 +256,7 @@
case OBJT_DEFAULT:
case OBJT_SWAP:
object->flags = OBJ_ONEMAPPING;
+ object->un_pager.path_info.data = NULL;
break;
case OBJT_DEVICE:
case OBJT_SG:
@@ -266,6 +267,7 @@
break;
case OBJT_PHYS:
object->flags = OBJ_UNMANAGED;
+ object->un_pager.path_info.data = NULL;
break;
case OBJT_VNODE:
object->flags = 0;
@@ -2343,6 +2345,54 @@
}
}
+/*
+ * Return the type of the path info pointer. If data is not NULL,
+ * set it to the path info pointer or NULL. The return value
+ * indicates which function can be used to convert the path info
+ * pointer to a path.
+ */
+int
+vm_object_path_info(vm_object_t object, void **data)
+{
+ VM_OBJECT_ASSERT_LOCKED(object);
+ if (data != NULL)
+ *data = object->un_pager.path_info.data;
+ if (object->type != OBJT_DEFAULT &&
+ object->type != OBJT_SWAP &&
+ object->type != OBJT_PHYS)
+ return (OBJPATH_NONE);
+ if (object->un_pager.path_info.data == NULL)
+ return (OBJPATH_NONE);
+ if ((object->flags & OBJ_TMPFS) != 0)
+ return (OBJPATH_NONE);
+ if ((object->flags & OBJ_SYSV_SHM) != 0)
+ return (OBJPATH_SHMS);
+ else
+ return (OBJPATH_SHMP);
+}
+
+void
+vm_object_set_path_info(vm_object_t object, int path_info_type,
+ void *data)
+{
+ VM_OBJECT_ASSERT_LOCKED(object);
+ KASSERT(object->type == OBJT_DEFAULT ||
+ object->type == OBJT_SWAP ||
+ object->type == OBJT_PHYS,
+ ("cannot set path info for object type %d", object->type));
+ KASSERT((object->flags & OBJ_TMPFS) == 0,
+ ("cannot set path info for tmpfs object"));
+ KASSERT(path_info_type == OBJPATH_SHMS ||
+ path_info_type == OBJPATH_SHMP ||
+ path_info_type == OBJPATH_NONE,
+ ("unknown path info type"));
+ object->un_pager.path_info.data = data;
+ if (path_info_type == OBJPATH_SHMS)
+ vm_object_set_flag(object, OBJ_SYSV_SHM);
+ else
+ vm_object_clear_flag(object, OBJ_SYSV_SHM);
+}
+
static int
sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
{

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 10, 6:58 AM (21 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23518954
Default Alt Text
D20390.id58333.diff (8 KB)

Event Timeline