summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_acct.c
diff options
context:
space:
mode:
authorarr <arr@FreeBSD.org>2002-09-12 05:00:32 +0000
committerarr <arr@FreeBSD.org>2002-09-12 05:00:32 +0000
commitb9413512b7d3d91dfc23f8d92b13d05f78c009d5 (patch)
tree39ca4867e830f07dd5ed5d445df4f7507de535b6 /sys/kern/kern_acct.c
parent20e15ff61d8946fded44787e99633937ae069043 (diff)
downloadFreeBSD-src-b9413512b7d3d91dfc23f8d92b13d05f78c009d5.zip
FreeBSD-src-b9413512b7d3d91dfc23f8d92b13d05f78c009d5.tar.gz
- Fix two obvious locking bugs; 1) returning with lock held when it needed
to be dropped, 2) attempting to lock acct_mtx while already holding it. Sorry to those who experienced pain. - Added two comments referring to two areas in which acct_mtx is held over vnode operations that might sleep. Patch in the works for this.
Diffstat (limited to 'sys/kern/kern_acct.c')
-rw-r--r--sys/kern/kern_acct.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index 3f07881..9a54df8 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -157,6 +157,10 @@ acct(td, uap)
* close the file, and (if no new file was specified, leave).
*/
+ /*
+ * XXX arr: Should not hold lock over vnode operation.
+ */
+
mtx_lock(&acct_mtx);
if (acctp != NULLVP || savacctp != NULLVP) {
callout_stop(&acctwatch_callout);
@@ -167,8 +171,10 @@ acct(td, uap)
crfree(acctcred != NOCRED ? acctcred : savacctcred);
acctcred = savacctcred = NOCRED;
}
- if (SCARG(uap, path) == NULL)
+ if (SCARG(uap, path) == NULL) {
+ mtx_unlock(&acct_mtx);
goto done2;
+ }
/*
* Save the new accounting file vnode, and schedule the new
@@ -178,9 +184,9 @@ acct(td, uap)
acctcred = crhold(td->td_ucred);
acctflags = flags;
callout_init(&acctwatch_callout, 0);
+ mtx_unlock(&acct_mtx);
acctwatch(NULL);
done2:
- mtx_unlock(&acct_mtx);
mtx_unlock(&Giant);
return (error);
}
@@ -342,6 +348,11 @@ acctwatch(a)
mtx_lock(&acct_mtx);
+ /*
+ * XXX arr: Need to fix the issue of holding acct_mtx over
+ * the below vnode operations.
+ */
+
if (savacctp != NULLVP) {
if (savacctp->v_type == VBAD) {
(void) vn_close(savacctp, savacctflags, savacctcred,
@@ -361,8 +372,10 @@ acctwatch(a)
log(LOG_NOTICE, "Accounting resumed\n");
}
} else {
- if (acctp == NULLVP)
+ if (acctp == NULLVP) {
+ mtx_unlock(&acct_mtx);
return;
+ }
if (acctp->v_type == VBAD) {
(void) vn_close(acctp, acctflags, acctcred, NULL);
acctp = NULLVP;
OpenPOWER on IntegriCloud