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);
 }
 

Reply via email to