From 2ff47c5f181b6ccf2ad64d3552687e28781eab5a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 4 Nov 2008 19:04:01 +0000 Subject: Remove unnecessary locking around vn_fullpath(). The vnode lock for the vnode in question does not need to be held. All the data structures used during the name lookup are protected by the global name cache lock. Instead, the caller merely needs to ensure a reference is held on the vnode (such as vhold()) to keep it from being freed. In the case of procfs' /file entry, grab the process lock while we gain a new reference (via vhold()) on p_textvp to fully close races with execve(2). For the kern.proc.vmmap sysctl handler, use a shared vnode lock around the call to VOP_GETATTR() rather than an exclusive lock. MFC after: 1 month --- sys/dev/hwpmc/hwpmc_mod.c | 2 -- sys/fs/procfs/procfs.c | 12 ++++-------- sys/fs/procfs/procfs_map.c | 5 ++--- sys/kern/kern_descrip.c | 10 ++++------ sys/kern/kern_proc.c | 4 ++-- 5 files changed, 12 insertions(+), 21 deletions(-) (limited to 'sys') diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index f750d46e409d1..61c07350d4a5f 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -680,9 +680,7 @@ pmc_getfilename(struct vnode *v, char **fullpath, char **freepath) *fullpath = "unknown"; *freepath = NULL; - vn_lock(v, LK_CANRECURSE | LK_EXCLUSIVE | LK_RETRY); vn_fullpath(curthread, v, fullpath, freepath); - VOP_UNLOCK(v, 0); } /* diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c index bc0efdaa2f61a..26bd18532f8e2 100644 --- a/sys/fs/procfs/procfs.c +++ b/sys/fs/procfs/procfs.c @@ -70,17 +70,13 @@ procfs_doprocfile(PFS_FILL_ARGS) char *fullpath = "unknown"; char *freepath = NULL; struct vnode *textvp; - int err; + PROC_LOCK(p); textvp = p->p_textvp; - VI_LOCK(textvp); - vholdl(textvp); - err = vn_lock(textvp, LK_EXCLUSIVE | LK_INTERLOCK); - vdrop(textvp); - if (err) - return (err); + vhold(textvp); + PROC_UNLOCK(p); vn_fullpath(td, textvp, &fullpath, &freepath); - VOP_UNLOCK(textvp, 0); + vdrop(textvp); sbuf_printf(sb, "%s", fullpath); if (freepath) free(freepath, M_TEMP); diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c index 1a9e4aaa8b804..0c671b4c286cd 100644 --- a/sys/fs/procfs/procfs_map.c +++ b/sys/fs/procfs/procfs_map.c @@ -175,10 +175,9 @@ procfs_doprocmap(PFS_FILL_ARGS) shadow_count = obj->shadow_count; VM_OBJECT_UNLOCK(obj); if (vp != NULL) { - vfslocked = VFS_LOCK_GIANT(vp->v_mount); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vn_fullpath(td, vp, &fullpath, &freepath); - vput(vp); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); VFS_UNLOCK_GIANT(vfslocked); } } else { diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index df92aca1fdf88..833aa2c4e04cf 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2537,10 +2537,9 @@ export_vnode_for_sysctl(struct vnode *vp, int type, freepath = NULL; fullpath = "-"; FILEDESC_SUNLOCK(fdp); - vfslocked = VFS_LOCK_GIANT(vp->v_mount); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vn_fullpath(curthread, vp, &fullpath, &freepath); - vput(vp); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); VFS_UNLOCK_GIANT(vfslocked); strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path)); if (freepath != NULL) @@ -2708,10 +2707,9 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) freepath = NULL; fullpath = "-"; FILEDESC_SUNLOCK(fdp); - vfslocked = VFS_LOCK_GIANT(vp->v_mount); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vn_fullpath(curthread, vp, &fullpath, &freepath); - vput(vp); + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vrele(vp); VFS_UNLOCK_GIANT(vfslocked); strlcpy(kif->kf_path, fullpath, sizeof(kif->kf_path)); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index aa48bd596d5c7..f8f639c04e47f 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1440,11 +1440,11 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) kve->kve_shadow_count = obj->shadow_count; VM_OBJECT_UNLOCK(obj); if (vp != NULL) { - vfslocked = VFS_LOCK_GIANT(vp->v_mount); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vn_fullpath(curthread, vp, &fullpath, &freepath); cred = curthread->td_ucred; + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + vn_lock(vp, LK_SHARED | LK_RETRY); if (VOP_GETATTR(vp, &va, cred) == 0) { kve->kve_fileid = va.va_fileid; kve->kve_fsid = va.va_fsid; -- cgit v1.3