diff options
author | mpp <mpp@FreeBSD.org> | 2007-02-13 00:20:13 +0000 |
---|---|---|
committer | mpp <mpp@FreeBSD.org> | 2007-02-13 00:20:13 +0000 |
commit | ea6456848e763f2152267b3794cb742d2b18f2e0 (patch) | |
tree | e0acb63dccb752ad5db3b3c02a040f6eabfa1817 /sys/kern/kern_ktrace.c | |
parent | 53d0372949779ab6c304823ce666e28ada25c981 (diff) | |
download | FreeBSD-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.c | 23 |
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; } /* |