summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvangyzen <vangyzen@FreeBSD.org>2015-10-02 14:36:41 +0000
committervangyzen <vangyzen@FreeBSD.org>2015-10-02 14:36:41 +0000
commit8f32d0c83ec420d8944fbdbd6a323756c04c1546 (patch)
tree50f81cbd9709385229eb7c8ec9c23fe0614e7b02
parent7b3b15b30002adb4bfb1e6836e4a76225fff3d6f (diff)
downloadFreeBSD-src-8f32d0c83ec420d8944fbdbd6a323756c04c1546.zip
FreeBSD-src-8f32d0c83ec420d8944fbdbd6a323756c04c1546.tar.gz
MFC r283924
Provide vnode in memory map info for files on tmpfs When providing memory map information to userland, populate the vnode pointer for tmpfs files. Set the memory mapping to appear as a vnode type, to match FreeBSD 9 behavior. This fixes the use of tmpfs files with the dtrace pid provider, procstat -v, procfs, linprocfs, pmc (pmcstat), and ptrace (PT_VM_ENTRY). Submitted by: Eric Badger <eric@badgerio.us> (initial revision) Obtained from: Dell Inc. PR: 198431
-rw-r--r--sys/compat/linprocfs/linprocfs.c12
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c6
-rw-r--r--sys/fs/procfs/procfs_map.c14
-rw-r--r--sys/kern/kern_proc.c20
-rw-r--r--sys/kern/sys_process.c2
-rw-r--r--sys/vm/vm_object.c12
-rw-r--r--sys/vm/vm_object.h1
7 files changed, 49 insertions, 18 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 714b864..47bb13b 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -1042,20 +1042,16 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
ino = 0;
if (lobj) {
off = IDX_TO_OFF(lobj->size);
- if (lobj->type == OBJT_VNODE) {
- vp = lobj->handle;
- if (vp)
- vref(vp);
- }
- else
- vp = NULL;
+ vp = vm_object_vnode(lobj);
+ if (vp != NULL)
+ vref(vp);
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
flags = obj->flags;
ref_count = obj->ref_count;
shadow_count = obj->shadow_count;
VM_OBJECT_RUNLOCK(obj);
- if (vp) {
+ if (vp != NULL) {
vn_fullpath(td, vp, &name, &freename);
vn_lock(vp, LK_SHARED | LK_RETRY);
VOP_GETATTR(vp, &vat, td->td_ucred);
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 9e369fe..10f9304 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -1660,7 +1660,8 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
continue;
}
- if (lobj->type != OBJT_VNODE || lobj->handle == NULL) {
+ vp = vm_object_vnode(lobj);
+ if (vp == NULL) {
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
VM_OBJECT_RUNLOCK(obj);
@@ -1672,7 +1673,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
* vnode, so we don't emit redundant MAP-IN
* directives.
*/
- if (entry->start == last_end && lobj->handle == last_vp) {
+ if (entry->start == last_end && vp == last_vp) {
last_end = entry->end;
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
@@ -1695,7 +1696,6 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
last_timestamp = map->timestamp;
vm_map_unlock_read(map);
- vp = lobj->handle;
vref(vp);
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index eae70229..b00aac3 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -159,11 +159,11 @@ procfs_doprocmap(PFS_FILL_ARGS)
freepath = NULL;
fullpath = "-";
if (lobj) {
+ vp = NULL;
switch (lobj->type) {
default:
case OBJT_DEFAULT:
type = "default";
- vp = NULL;
break;
case OBJT_VNODE:
type = "vnode";
@@ -171,13 +171,19 @@ procfs_doprocmap(PFS_FILL_ARGS)
vref(vp);
break;
case OBJT_SWAP:
- type = "swap";
- vp = NULL;
+ if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
+ type = "vnode";
+ if ((lobj->flags & OBJ_TMPFS) != 0) {
+ vp = lobj->un_pager.swp.swp_tmpfs;
+ vref(vp);
+ }
+ } else {
+ type = "swap";
+ }
break;
case OBJT_SG:
case OBJT_DEVICE:
type = "device";
- vp = NULL;
break;
}
if (lobj != obj)
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 63ecf0f..a8580a5 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2074,7 +2074,15 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
vref(vp);
break;
case OBJT_SWAP:
- kve->kve_type = KVME_TYPE_SWAP;
+ if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
+ kve->kve_type = KVME_TYPE_VNODE;
+ if ((lobj->flags & OBJ_TMPFS) != 0) {
+ vp = lobj->un_pager.swp.swp_tmpfs;
+ vref(vp);
+ }
+ } else {
+ kve->kve_type = KVME_TYPE_SWAP;
+ }
break;
case OBJT_DEVICE:
kve->kve_type = KVME_TYPE_DEVICE;
@@ -2300,7 +2308,15 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb)
vref(vp);
break;
case OBJT_SWAP:
- kve->kve_type = KVME_TYPE_SWAP;
+ if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
+ kve->kve_type = KVME_TYPE_VNODE;
+ if ((lobj->flags & OBJ_TMPFS) != 0) {
+ vp = lobj->un_pager.swp.swp_tmpfs;
+ vref(vp);
+ }
+ } else {
+ kve->kve_type = KVME_TYPE_SWAP;
+ }
break;
case OBJT_DEVICE:
kve->kve_type = KVME_TYPE_DEVICE;
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 6ad4694..123dd10 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -402,7 +402,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
lobj = tobj;
pve->pve_offset += tobj->backing_object_offset;
}
- vp = (lobj->type == OBJT_VNODE) ? lobj->handle : NULL;
+ vp = vm_object_vnode(lobj);
if (vp != NULL)
vref(vp);
if (lobj != obj)
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 54741ba..9d08714 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -2270,6 +2270,18 @@ next_page:
}
}
+struct vnode *
+vm_object_vnode(vm_object_t object)
+{
+
+ VM_OBJECT_ASSERT_LOCKED(object);
+ if (object->type == OBJT_VNODE)
+ return (object->handle);
+ if (object->type == OBJT_SWAP && (object->flags & OBJ_TMPFS) != 0)
+ return (object->un_pager.swp.swp_tmpfs);
+ return (NULL);
+}
+
static int
sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index 06111a1..ac8feae 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -297,6 +297,7 @@ boolean_t vm_object_sync(vm_object_t, vm_ooffset_t, vm_size_t, boolean_t,
boolean_t);
void vm_object_unwire(vm_object_t object, vm_ooffset_t offset,
vm_size_t length, uint8_t queue);
+struct vnode *vm_object_vnode(vm_object_t object);
#endif /* _KERNEL */
#endif /* _VM_OBJECT_ */
OpenPOWER on IntegriCloud