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:
Sean Eric Fagan 1997-12-12 03:33:43 +00:00
parent 484b65d5d8
commit ba9d19e99b
4 changed files with 54 additions and 46 deletions

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}