summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_ktrace.c
diff options
context:
space:
mode:
authormpp <mpp@FreeBSD.org>2007-02-13 00:20:13 +0000
committermpp <mpp@FreeBSD.org>2007-02-13 00:20:13 +0000
commitea6456848e763f2152267b3794cb742d2b18f2e0 (patch)
treee0acb63dccb752ad5db3b3c02a040f6eabfa1817 /sys/kern/kern_ktrace.c
parent53d0372949779ab6c304823ce666e28ada25c981 (diff)
downloadFreeBSD-src-ea6456848e763f2152267b3794cb742d2b18f2e0.zip
FreeBSD-src-ea6456848e763f2152267b3794cb742d2b18f2e0.tar.gz
Do not do a vn_close for all references to the ktraced file if we are
doing a CLEARFILE option. Do a vrele instead. This prevents a panic later due to v_writecount being negative when the vnode is taken off the freelist. Submitted by: jhb
Diffstat (limited to 'sys/kern/kern_ktrace.c')
-rw-r--r--sys/kern/kern_ktrace.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 9e92e49..0f574bf 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -628,6 +628,9 @@ ktrace(td, uap)
* Clear all uses of the tracefile.
*/
if (ops == KTROP_CLEARFILE) {
+ int vrele_count;
+
+ vrele_count = 0;
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
PROC_LOCK(p);
@@ -639,20 +642,20 @@ ktrace(td, uap)
p->p_tracevp = NULL;
p->p_traceflag = 0;
mtx_unlock(&ktrace_mtx);
- PROC_UNLOCK(p);
- vfslocked = VFS_LOCK_GIANT(vp->v_mount);
- (void) vn_close(vp, FREAD|FWRITE,
- cred, td);
- VFS_UNLOCK_GIANT(vfslocked);
+ vrele_count++;
crfree(cred);
- } else {
- PROC_UNLOCK(p);
+ } else
error = EPERM;
- }
- } else
- PROC_UNLOCK(p);
+ }
+ PROC_UNLOCK(p);
}
sx_sunlock(&allproc_lock);
+ if (vrele_count > 0) {
+ vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+ while (vrele_count-- > 0)
+ vrele(vp);
+ VFS_UNLOCK_GIANT(vfslocked);
+ }
goto done;
}
/*
OpenPOWER on IntegriCloud