summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsef <sef@FreeBSD.org>1997-12-12 03:33:43 +0000
committersef <sef@FreeBSD.org>1997-12-12 03:33:43 +0000
commit9fd84ad6938a14ba3d55c68ac7e2f33f284f4b6a (patch)
tree6e03caaa5ca62fe342bb1f7802e130476b1f35eb
parent52b8e9813edc79062fd4253339febac539c7bfba (diff)
downloadFreeBSD-src-9fd84ad6938a14ba3d55c68ac7e2f33f284f4b6a.zip
FreeBSD-src-9fd84ad6938a14ba3d55c68ac7e2f33f284f4b6a.tar.gz
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().
-rw-r--r--sys/fs/procfs/procfs_subr.c38
-rw-r--r--sys/fs/procfs/procfs_vnops.c12
-rw-r--r--sys/miscfs/procfs/procfs_subr.c38
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c12
4 files changed, 54 insertions, 46 deletions
diff --git a/sys/fs/procfs/procfs_subr.c b/sys/fs/procfs/procfs_subr.c
index e13e425..2156b12 100644
--- a/sys/fs/procfs/procfs_subr.c
+++ b/sys/fs/procfs/procfs_subr.c
@@ -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;
}
}
diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c
index f0c1bfb..f660f3a 100644
--- a/sys/fs/procfs/procfs_vnops.c
+++ b/sys/fs/procfs/procfs_vnops.c
@@ -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);
}
diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c
index e13e425..2156b12 100644
--- a/sys/miscfs/procfs/procfs_subr.c
+++ b/sys/miscfs/procfs/procfs_subr.c
@@ -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;
}
}
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
index f0c1bfb..f660f3a 100644
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ b/sys/miscfs/procfs/procfs_vnops.c
@@ -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);
}
OpenPOWER on IntegriCloud