This is similar to the socket & kqueue diff I just sent.

Check for NOTE_SUBMIT hint in order to protect `so_state', `so_snd'
and `so_rcv'.

ok?

Index: miscfs//fifofs/fifo_vnops.c
===================================================================
RCS file: /cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v
retrieving revision 1.54
diff -u -p -r1.54 fifo_vnops.c
--- miscfs//fifofs/fifo_vnops.c 26 Jun 2017 09:32:31 -0000      1.54
+++ miscfs//fifofs/fifo_vnops.c 26 Jun 2017 14:07:29 -0000
@@ -527,14 +527,22 @@ int
 filt_fiforead(struct knote *kn, long hint)
 {
        struct socket *so = (struct socket *)kn->kn_hook;
+       int s, rv;
 
+       if (!(hint & NOTE_SUBMIT))
+               s = solock(so);
        kn->kn_data = so->so_rcv.sb_cc;
        if (so->so_state & SS_CANTRCVMORE) {
                kn->kn_flags |= EV_EOF;
-               return (1);
+               rv = 1;
+       } else {
+               kn->kn_flags &= ~EV_EOF;
+               rv = (kn->kn_data > 0);
        }
-       kn->kn_flags &= ~EV_EOF;
-       return (kn->kn_data > 0);
+       if (!(hint & NOTE_SUBMIT))
+               sounlock(s);
+
+       return (rv);
 }
 
 void
@@ -551,12 +559,20 @@ int
 filt_fifowrite(struct knote *kn, long hint)
 {
        struct socket *so = (struct socket *)kn->kn_hook;
+       int s, rv;
 
+       if (!(hint & NOTE_SUBMIT))
+               s = solock(so);
        kn->kn_data = sbspace(so, &so->so_snd);
        if (so->so_state & SS_CANTSENDMORE) {
                kn->kn_flags |= EV_EOF;
-               return (1);
+               rv = 1;
+       } else {
+               kn->kn_flags &= ~EV_EOF;
+               rv = (kn->kn_data >= so->so_snd.sb_lowat);
        }
-       kn->kn_flags &= ~EV_EOF;
-       return (kn->kn_data >= so->so_snd.sb_lowat);
+       if (!(hint & NOTE_SUBMIT))
+               sounlock(s);
+
+       return (rv);
 }

Reply via email to