filt_pipedetach() can be simplified a bit by using kn_hook to point
to the pipe. This additionally lets the system fully remove elements
from the knote lists. Previously, the write-side list just vanished
when the peer was closed.
OK?
Index: kern/sys_pipe.c
===================================================================
RCS file: src/sys/kern/sys_pipe.c,v
retrieving revision 1.123
diff -u -p -r1.123 sys_pipe.c
--- kern/sys_pipe.c 29 Jun 2020 18:23:18 -0000 1.123
+++ kern/sys_pipe.c 10 Dec 2020 16:21:51 -0000
@@ -886,6 +886,7 @@ pipe_kqfilter(struct file *fp, struct kn
switch (kn->kn_filter) {
case EVFILT_READ:
kn->kn_fop = &pipe_rfiltops;
+ kn->kn_hook = rpipe;
klist_insert(&rpipe->pipe_sel.si_note, kn);
break;
case EVFILT_WRITE:
@@ -895,6 +896,7 @@ pipe_kqfilter(struct file *fp, struct kn
break;
}
kn->kn_fop = &pipe_wfiltops;
+ kn->kn_hook = wpipe;
klist_insert(&wpipe->pipe_sel.si_note, kn);
break;
default:
@@ -909,23 +911,11 @@ pipe_kqfilter(struct file *fp, struct kn
void
filt_pipedetach(struct knote *kn)
{
- struct pipe *rpipe = kn->kn_fp->f_data, *wpipe;
- struct rwlock *lock = rpipe->pipe_lock;
+ struct pipe *cpipe = kn->kn_hook;
+ struct rwlock *lock = cpipe->pipe_lock;
rw_enter_write(lock);
- wpipe = pipe_peer(rpipe);
-
- switch (kn->kn_filter) {
- case EVFILT_READ:
- klist_remove(&rpipe->pipe_sel.si_note, kn);
- break;
- case EVFILT_WRITE:
- if (wpipe == NULL)
- break;
- klist_remove(&wpipe->pipe_sel.si_note, kn);
- break;
- }
-
+ klist_remove(&cpipe->pipe_sel.si_note, kn);
rw_exit_write(lock);
}