Index: sys/sys/ktrace.h =================================================================== --- sys/sys/ktrace.h (revision 194813) +++ sys/sys/ktrace.h (working copy) @@ -207,6 +207,8 @@ void ktrstruct(const char *, size_t, voi ktrstruct("sockaddr", 8, (s), ((struct sockaddr *)(s))->sa_len) #define ktrstat(s) \ ktrstruct("stat", 4, (s), sizeof(struct stat)) +void ktrvref(struct vnode *); +void ktrvrele(struct vnode *); #else Index: sys/kern/kern_ktrace.c =================================================================== --- sys/kern/kern_ktrace.c (revision 194813) +++ sys/kern/kern_ktrace.c (working copy) @@ -616,6 +616,26 @@ ktrstruct(name, namelen, data, datalen) req->ktr_header.ktr_len = buflen; ktr_submitrequest(curthread, req); } + +void +ktrvref(struct vnode *vp) +{ + + VREF(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + vp->v_writecount++; + VOP_UNLOCK(vp, 0); +} + +void +ktrvrele(struct vnode *vp) +{ + + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + vp->v_writecount--; + VOP_UNLOCK(vp, 0); + vrele(vp); +} #endif /* KTRACE */ /* Interface and common routines */ @@ -706,7 +726,7 @@ ktrace(td, uap) if (vrele_count > 0) { vfslocked = VFS_LOCK_GIANT(vp->v_mount); while (vrele_count-- > 0) - vrele(vp); + ktrvrele(vp); VFS_UNLOCK_GIANT(vfslocked); } goto done; @@ -849,7 +869,7 @@ ktrops(td, p, ops, facs, vp) * if trace file already in use, relinquish below */ tracevp = p->p_tracevp; - VREF(vp); + ktrvref(vp); p->p_tracevp = vp; } if (p->p_tracecred != td->td_ucred) { @@ -876,7 +896,7 @@ ktrops(td, p, ops, facs, vp) int vfslocked; vfslocked = VFS_LOCK_GIANT(tracevp->v_mount); - vrele(tracevp); + ktrvrele(tracevp); VFS_UNLOCK_GIANT(vfslocked); } if (tracecred != NULL) @@ -953,7 +973,7 @@ ktr_writerequest(struct thread *td, stru mtx_unlock(&ktrace_mtx); return; } - VREF(vp); + ktrvref(vp); KASSERT(cred != NULL, ("ktr_writerequest: cred == NULL")); crhold(cred); mtx_unlock(&ktrace_mtx); @@ -1000,7 +1020,7 @@ ktr_writerequest(struct thread *td, stru vn_finished_write(mp); crfree(cred); if (!error) { - vrele(vp); + ktrvrele(vp); VFS_UNLOCK_GIANT(vfslocked); return; } @@ -1053,7 +1073,7 @@ ktr_writerequest(struct thread *td, stru */ vfslocked = VFS_LOCK_GIANT(vp->v_mount); while (vrele_count-- > 0) - vrele(vp); + ktrvrele(vp); VFS_UNLOCK_GIANT(vfslocked); } Index: sys/kern/kern_exit.c =================================================================== --- sys/kern/kern_exit.c (revision 194813) +++ sys/kern/kern_exit.c (working copy) @@ -371,7 +371,7 @@ exit1(struct thread *td, int rv) PROC_UNLOCK(p); if (tracevp != NULL) { locked = VFS_LOCK_GIANT(tracevp->v_mount); - vrele(tracevp); + ktrvrele(tracevp); VFS_UNLOCK_GIANT(locked); } if (tracecred != NULL) Index: sys/kern/kern_exec.c =================================================================== --- sys/kern/kern_exec.c (revision 194813) +++ sys/kern/kern_exec.c (working copy) @@ -836,7 +836,7 @@ done1: int tvfslocked; tvfslocked = VFS_LOCK_GIANT(tracevp->v_mount); - vrele(tracevp); + ktrvrele(tracevp); VFS_UNLOCK_GIANT(tvfslocked); } if (tracecred != NULL) Index: sys/kern/kern_fork.c =================================================================== --- sys/kern/kern_fork.c (revision 194813) +++ sys/kern/kern_fork.c (working copy) @@ -652,7 +652,7 @@ again: if (p1->p_traceflag & KTRFAC_INHERIT) { p2->p_traceflag = p1->p_traceflag; if ((p2->p_tracevp = p1->p_tracevp) != NULL) { - VREF(p2->p_tracevp); + ktrvref(p2->p_tracevp); KASSERT(p1->p_tracecred != NULL, ("ktrace vnode with no cred")); p2->p_tracecred = crhold(p1->p_tracecred);