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' <pid>/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
This commit is contained in:
parent
2ef42c06d6
commit
2ff47c5f18
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user