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 MFC after: 2 weeks Reviewed by: jhb Approved by: kib (mentor)
This commit is contained in:
parent
b7a728aaba
commit
63e4c6cdf9
@ -1025,20 +1025,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);
|
||||
|
@ -1655,7 +1655,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);
|
||||
@ -1667,7 +1668,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);
|
||||
@ -1690,7 +1691,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);
|
||||
|
@ -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)
|
||||
|
@ -2113,7 +2113,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;
|
||||
@ -2339,7 +2347,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;
|
||||
|
@ -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)
|
||||
|
@ -2287,6 +2287,18 @@ vm_object_unwire(vm_object_t object, vm_ooffset_t offset, vm_size_t length,
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -322,6 +322,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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user