Eliminate a couple of reference count and mutex leaks.
This commit is contained in:
parent
6fa495aa59
commit
c18c0d2eaa
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: procfs_vnops.c,v 1.145 2007/02/09 21:55:36 ad Exp $ */
|
/* $NetBSD: procfs_vnops.c,v 1.146 2007/02/11 17:16:08 ad Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.145 2007/02/09 21:55:36 ad Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.146 2007/02/11 17:16:08 ad Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -647,7 +647,7 @@ procfs_getattr(v)
|
||||||
case PFSexe:
|
case PFSexe:
|
||||||
MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP,
|
MALLOC(path, char *, MAXPATHLEN + 4, M_TEMP,
|
||||||
M_WAITOK|M_CANFAIL);
|
M_WAITOK|M_CANFAIL);
|
||||||
if (path == NULL) {
|
if (path == NULL && procp != NULL) {
|
||||||
procfs_proc_unlock(procp);
|
procfs_proc_unlock(procp);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
|
@ -660,8 +660,10 @@ procfs_getattr(v)
|
||||||
|
|
||||||
if (procp != NULL) {
|
if (procp != NULL) {
|
||||||
mutex_enter(&procp->p_mutex);
|
mutex_enter(&procp->p_mutex);
|
||||||
if (kauth_authorize_process(kauth_cred_get(),
|
error = kauth_authorize_process(kauth_cred_get(),
|
||||||
KAUTH_PROCESS_CANSEE, procp, NULL, NULL, NULL) != 0) {
|
KAUTH_PROCESS_CANSEE, procp, NULL, NULL, NULL);
|
||||||
|
mutex_exit(&procp->p_mutex);
|
||||||
|
if (error != 0) {
|
||||||
procfs_proc_unlock(procp);
|
procfs_proc_unlock(procp);
|
||||||
if (path != NULL)
|
if (path != NULL)
|
||||||
free(path, M_TEMP);
|
free(path, M_TEMP);
|
||||||
|
@ -880,11 +882,8 @@ procfs_getattr(v)
|
||||||
panic("procfs_getattr");
|
panic("procfs_getattr");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (procp != NULL) {
|
if (procp != NULL)
|
||||||
mutex_exit(&procp->p_mutex);
|
|
||||||
procfs_proc_unlock(procp);
|
procfs_proc_unlock(procp);
|
||||||
}
|
|
||||||
|
|
||||||
if (path != NULL)
|
if (path != NULL)
|
||||||
free(path, M_TEMP);
|
free(path, M_TEMP);
|
||||||
|
|
||||||
|
@ -971,11 +970,12 @@ procfs_lookup(v)
|
||||||
const char *pname = cnp->cn_nameptr;
|
const char *pname = cnp->cn_nameptr;
|
||||||
const struct proc_target *pt = NULL;
|
const struct proc_target *pt = NULL;
|
||||||
struct vnode *fvp;
|
struct vnode *fvp;
|
||||||
pid_t pid;
|
pid_t pid, vnpid;
|
||||||
struct pfsnode *pfs;
|
struct pfsnode *pfs;
|
||||||
struct proc *p = NULL;
|
struct proc *p = NULL;
|
||||||
struct lwp *l = NULL;
|
struct lwp *l = NULL;
|
||||||
int i, error, iscurproc = 0, isself = 0;
|
int i, error;
|
||||||
|
pfstype type;
|
||||||
|
|
||||||
*vpp = NULL;
|
*vpp = NULL;
|
||||||
|
|
||||||
|
@ -997,15 +997,6 @@ procfs_lookup(v)
|
||||||
if (cnp->cn_flags & ISDOTDOT)
|
if (cnp->cn_flags & ISDOTDOT)
|
||||||
return (EIO);
|
return (EIO);
|
||||||
|
|
||||||
iscurproc = CNEQ(cnp, "curproc", 7);
|
|
||||||
isself = CNEQ(cnp, "self", 4);
|
|
||||||
|
|
||||||
if (iscurproc || isself) {
|
|
||||||
error = procfs_allocvp(dvp->v_mount, vpp, 0,
|
|
||||||
iscurproc ? PFScurproc : PFSself, -1, NULL);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nproc_root_targets; i++) {
|
for (i = 0; i < nproc_root_targets; i++) {
|
||||||
pt = &proc_root_targets[i];
|
pt = &proc_root_targets[i];
|
||||||
if (cnp->cn_namelen == pt->pt_namlen &&
|
if (cnp->cn_namelen == pt->pt_namlen &&
|
||||||
|
@ -1021,12 +1012,23 @@ procfs_lookup(v)
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = (pid_t)atoi(pname, cnp->cn_namelen);
|
if (CNEQ(cnp, "curproc", 7)) {
|
||||||
|
pid = curproc->p_pid;
|
||||||
|
vnpid = 0;
|
||||||
|
type = PFScurproc;
|
||||||
|
} else if (CNEQ(cnp, "self", 4)) {
|
||||||
|
pid = curproc->p_pid;
|
||||||
|
vnpid = 0;
|
||||||
|
type = PFSself;
|
||||||
|
} else {
|
||||||
|
pid = (pid_t)atoi(pname, cnp->cn_namelen);
|
||||||
|
vnpid = pid;
|
||||||
|
type = PFSproc;
|
||||||
|
}
|
||||||
|
|
||||||
if (procfs_proc_lock(pid, &p, ESRCH) != 0)
|
if (procfs_proc_lock(pid, &p, ESRCH) != 0)
|
||||||
break;
|
break;
|
||||||
|
error = procfs_allocvp(dvp->v_mount, vpp, vnpid, type, -1, p);
|
||||||
error = procfs_allocvp(dvp->v_mount, vpp, pid, PFSproc, -1, p);
|
|
||||||
procfs_proc_unlock(p);
|
procfs_proc_unlock(p);
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
|
@ -1054,14 +1056,17 @@ procfs_lookup(v)
|
||||||
(*pt->pt_valid)(cnp->cn_lwp, dvp->v_mount)))
|
(*pt->pt_valid)(cnp->cn_lwp, dvp->v_mount)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == nproc_targets)
|
if (i == nproc_targets) {
|
||||||
|
procfs_proc_unlock(p);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (pt->pt_pfstype == PFSfile) {
|
if (pt->pt_pfstype == PFSfile) {
|
||||||
fvp = p->p_textvp;
|
fvp = p->p_textvp;
|
||||||
/* We already checked that it exists. */
|
/* We already checked that it exists. */
|
||||||
VREF(fvp);
|
VREF(fvp);
|
||||||
vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
*vpp = fvp;
|
*vpp = fvp;
|
||||||
|
procfs_proc_unlock(p);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1086,8 +1091,8 @@ procfs_lookup(v)
|
||||||
VOP_UNLOCK(dvp, 0);
|
VOP_UNLOCK(dvp, 0);
|
||||||
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
|
error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
|
||||||
PFSproc, -1, p);
|
PFSproc, -1, p);
|
||||||
procfs_proc_unlock(p);
|
|
||||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
|
procfs_proc_unlock(p);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
fd = atoi(pname, cnp->cn_namelen);
|
fd = atoi(pname, cnp->cn_namelen);
|
||||||
|
|
Loading…
Reference in New Issue