Fix clearing of ktrace points:

- need deep compare of open files, not a shallow pointer compare.
 - reorder fdrelease()/FILE_UNUSE() invocations so fdrelease doesn't
block waiting for something which can't happen until after it returns.
This commit is contained in:
sommerfeld 2000-05-29 22:04:11 +00:00
parent dfe35a4788
commit 879eaa480a
1 changed files with 20 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_ktrace.c,v 1.43 2000/05/28 15:27:51 sommerfeld Exp $ */
/* $NetBSD: kern_ktrace.c,v 1.44 2000/05/29 22:04:11 sommerfeld Exp $ */
/*
* Copyright (c) 1989, 1993
@ -61,6 +61,22 @@ int ktrsetchildren __P((struct proc *, struct proc *, int, int,
struct file *));
int ktrwrite __P((struct proc *, struct ktr_header *));
int ktrcanset __P((struct proc *, struct proc *));
int ktrsamefile __P((struct file *, struct file *));
/*
* "deep" compare of two files for the purposes of clearing a trace.
* Returns true if they're the same open file, or if they point at the
* same underlying vnode/socket.
*/
int
ktrsamefile (f1, f2)
struct file *f1, *f2;
{
return ((f1 == f2) ||
((f1->f_type == f2->f_type) &&
(f1->f_data == f2->f_data)));
}
void
ktrderef(p)
@ -311,7 +327,7 @@ ktrace_common (curp, ops, facs, pid, fp)
proclist_lock_read();
for (p = LIST_FIRST(&allproc); p != NULL;
p = LIST_NEXT(p, p_list)) {
if (p->p_tracep == fp) {
if (ktrsamefile(p->p_tracep, fp)) {
if (ktrcanset(curp, p))
ktrderef(p);
else
@ -476,8 +492,8 @@ done:
if (vp != NULL)
(void) vn_close(vp, FWRITE, curp->p_ucred, curp);
if (fp != NULL) {
fdrelease(curp, fd); /* release fd table slot */
FILE_UNUSE(fp, curp); /* release file */
fdrelease(curp, fd); /* release fd table slot */
}
return (error);
}
@ -606,7 +622,7 @@ ktrwrite(p, kth)
error);
proclist_lock_read();
for (p = LIST_FIRST(&allproc); p != NULL; p = LIST_NEXT(p, p_list)) {
if (p->p_tracep == fp)
if (ktrsamefile(p->p_tracep, fp))
ktrderef(p);
}
proclist_unlock_read();