Fix a problem with procfs_exit() that resulted in missing some procfs
nodes; this also apparantly caused a panic in some circumstances. Also, since procfs_exit() is getting rid of the nodes when a process exits, don't bother checking for the process' existance in procfs_inactive().
This commit is contained in:
parent
484b65d5d8
commit
ba9d19e99b
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
|
||||
*
|
||||
* $Id: procfs_subr.c,v 1.19 1997/12/08 01:06:22 sef Exp $
|
||||
* $Id: procfs_subr.c,v 1.20 1997/12/09 05:03:41 sef Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -358,16 +358,30 @@ procfs_exit(struct proc *p)
|
||||
struct pfsnode *pfs;
|
||||
pid_t pid = p->p_pid;
|
||||
|
||||
for (pfs = pfshead; pfs ; pfs = pfs->pfs_next) {
|
||||
struct vnode *vp = PFSTOV(pfs);
|
||||
/*
|
||||
* XXX - this is probably over-paranoid here --
|
||||
* for some reason, occasionally the v_tag is
|
||||
* not VT_PROCFS; this results in a panic. I'm
|
||||
* not sure *why* that is happening.
|
||||
*/
|
||||
if (pfs->pfs_pid == pid && vp->v_usecount &&
|
||||
vp->v_tag == VT_PROCFS)
|
||||
vgone(vp);
|
||||
/*
|
||||
* The reason for this loop is not obvious -- basicly,
|
||||
* procfs_freevp(), which is called via vgone() (eventually),
|
||||
* removes the specified procfs node from the pfshead list.
|
||||
* It does this by *pfsp = pfs->pfs_next, meaning that it
|
||||
* overwrites the node. So when we do pfs = pfs->next, we
|
||||
* end up skipping the node that replaces the one that was
|
||||
* vgone'd. Since it may have been the last one on the list,
|
||||
* it may also have been set to null -- but *our* pfs pointer,
|
||||
* here, doesn't see this. So the loop starts from the beginning
|
||||
* again.
|
||||
*
|
||||
* This is not a for() loop because the final event
|
||||
* would be "pfs = pfs->pfs_next"; in the case where
|
||||
* pfs is set to pfshead again, that would mean that
|
||||
* pfshead is skipped over.
|
||||
*
|
||||
*/
|
||||
pfs = pfshead;
|
||||
while (pfs) {
|
||||
if (pfs->pfs_pid == pid) {
|
||||
vgone(PFSTOV(pfs));
|
||||
pfs = pfshead;
|
||||
} else
|
||||
pfs = pfs->pfs_next;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.45 1997/12/07 04:01:03 sef Exp $
|
||||
* $Id: procfs_vnops.c,v 1.46 1997/12/08 22:09:24 sef Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -324,13 +324,6 @@ procfs_bmap(ap)
|
||||
* list, so to get it back vget() must be
|
||||
* used.
|
||||
*
|
||||
* for procfs, check if the process is still
|
||||
* alive and if it isn't then just throw away
|
||||
* the vnode by calling vgone(). this may
|
||||
* be overkill and a waste of time since the
|
||||
* chances are that the process will still be
|
||||
* there and PFIND is not free.
|
||||
*
|
||||
* (vp) is locked on entry, but must be unlocked on exit.
|
||||
*/
|
||||
static int
|
||||
@ -340,11 +333,8 @@ procfs_inactive(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct pfsnode *pfs = VTOPFS(vp);
|
||||
|
||||
VOP_UNLOCK(vp, 0, ap->a_p);
|
||||
if (PFIND(pfs->pfs_pid) == 0)
|
||||
vgone(vp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
|
||||
*
|
||||
* $Id: procfs_subr.c,v 1.19 1997/12/08 01:06:22 sef Exp $
|
||||
* $Id: procfs_subr.c,v 1.20 1997/12/09 05:03:41 sef Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -358,16 +358,30 @@ procfs_exit(struct proc *p)
|
||||
struct pfsnode *pfs;
|
||||
pid_t pid = p->p_pid;
|
||||
|
||||
for (pfs = pfshead; pfs ; pfs = pfs->pfs_next) {
|
||||
struct vnode *vp = PFSTOV(pfs);
|
||||
/*
|
||||
* XXX - this is probably over-paranoid here --
|
||||
* for some reason, occasionally the v_tag is
|
||||
* not VT_PROCFS; this results in a panic. I'm
|
||||
* not sure *why* that is happening.
|
||||
*/
|
||||
if (pfs->pfs_pid == pid && vp->v_usecount &&
|
||||
vp->v_tag == VT_PROCFS)
|
||||
vgone(vp);
|
||||
/*
|
||||
* The reason for this loop is not obvious -- basicly,
|
||||
* procfs_freevp(), which is called via vgone() (eventually),
|
||||
* removes the specified procfs node from the pfshead list.
|
||||
* It does this by *pfsp = pfs->pfs_next, meaning that it
|
||||
* overwrites the node. So when we do pfs = pfs->next, we
|
||||
* end up skipping the node that replaces the one that was
|
||||
* vgone'd. Since it may have been the last one on the list,
|
||||
* it may also have been set to null -- but *our* pfs pointer,
|
||||
* here, doesn't see this. So the loop starts from the beginning
|
||||
* again.
|
||||
*
|
||||
* This is not a for() loop because the final event
|
||||
* would be "pfs = pfs->pfs_next"; in the case where
|
||||
* pfs is set to pfshead again, that would mean that
|
||||
* pfshead is skipped over.
|
||||
*
|
||||
*/
|
||||
pfs = pfshead;
|
||||
while (pfs) {
|
||||
if (pfs->pfs_pid == pid) {
|
||||
vgone(PFSTOV(pfs));
|
||||
pfs = pfshead;
|
||||
} else
|
||||
pfs = pfs->pfs_next;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
||||
*
|
||||
* $Id: procfs_vnops.c,v 1.45 1997/12/07 04:01:03 sef Exp $
|
||||
* $Id: procfs_vnops.c,v 1.46 1997/12/08 22:09:24 sef Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -324,13 +324,6 @@ procfs_bmap(ap)
|
||||
* list, so to get it back vget() must be
|
||||
* used.
|
||||
*
|
||||
* for procfs, check if the process is still
|
||||
* alive and if it isn't then just throw away
|
||||
* the vnode by calling vgone(). this may
|
||||
* be overkill and a waste of time since the
|
||||
* chances are that the process will still be
|
||||
* there and PFIND is not free.
|
||||
*
|
||||
* (vp) is locked on entry, but must be unlocked on exit.
|
||||
*/
|
||||
static int
|
||||
@ -340,11 +333,8 @@ procfs_inactive(ap)
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct pfsnode *pfs = VTOPFS(vp);
|
||||
|
||||
VOP_UNLOCK(vp, 0, ap->a_p);
|
||||
if (PFIND(pfs->pfs_pid) == 0)
|
||||
vgone(vp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user