diff options
author | sef <sef@FreeBSD.org> | 1997-12-12 03:33:43 +0000 |
---|---|---|
committer | sef <sef@FreeBSD.org> | 1997-12-12 03:33:43 +0000 |
commit | 9fd84ad6938a14ba3d55c68ac7e2f33f284f4b6a (patch) | |
tree | 6e03caaa5ca62fe342bb1f7802e130476b1f35eb /sys | |
parent | 52b8e9813edc79062fd4253339febac539c7bfba (diff) | |
download | FreeBSD-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().
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/procfs/procfs_subr.c | 38 | ||||
-rw-r--r-- | sys/fs/procfs/procfs_vnops.c | 12 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_subr.c | 38 | ||||
-rw-r--r-- | sys/miscfs/procfs/procfs_vnops.c | 12 |
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); } |