summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-12-14 20:48:40 +0000
committerphk <phk@FreeBSD.org>2004-12-14 20:48:40 +0000
commiteab55e158905b42bd76bba4164b30ab5db8d0d86 (patch)
tree25bd69d8ef4773a8dd5da2b06a6b0b6fb6434422 /sys/kern/kern_descrip.c
parentef590407757a212568b3a5f9265dad4c8f3c98a6 (diff)
downloadFreeBSD-src-eab55e158905b42bd76bba4164b30ab5db8d0d86.zip
FreeBSD-src-eab55e158905b42bd76bba4164b30ab5db8d0d86.tar.gz
Fix a deadlock I introduced this morning.
Mostly from: tegge
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index f988a41..659c4c5 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1607,12 +1607,11 @@ fdfree(struct thread *td)
if (fdtol != NULL)
FREE(fdtol, M_FILEDESC_TO_LEADER);
}
- FILEDESC_LOCK(fdp);
- if (--fdp->fd_refcnt > 0) {
- FILEDESC_UNLOCK(fdp);
+ FILEDESC_LOCK_FAST(fdp);
+ i = --fdp->fd_refcnt;
+ FILEDESC_UNLOCK_FAST(fdp);
+ if (i > 0)
return;
- }
-
/*
* We are the last reference to the structure, so we can
* safely assume it will not change out from under us.
@@ -1622,6 +1621,7 @@ fdfree(struct thread *td)
if (*fpp)
(void) closef(*fpp, td);
}
+ FILEDESC_LOCK(fdp);
/* XXX This should happen earlier. */
mtx_lock(&fdesc_mtx);
@@ -2324,6 +2324,7 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
nrele++;
}
FILEDESC_UNLOCK_FAST(fdp);
+ fddrop(fdp);
while (nrele--)
vrele(olddp);
}
@@ -2418,7 +2419,7 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
if (fdp == NULL)
continue;
FILEDESC_LOCK_FAST(fdp);
- for (n = 0; n < fdp->fd_nfiles; ++n) {
+ for (n = 0; fdp->fd_refcnt > 0 && n < fdp->fd_nfiles; ++n) {
if ((fp = fdp->fd_ofiles[n]) == NULL)
continue;
xf.xf_fd = n;
OpenPOWER on IntegriCloud