This patch adds f_modify and f_process callbacks to FIFO event filters.
The general idea is the same as with sockets, discussed in thread
"Add f_modify and f_process callbacks to socket filterops" on tech@.
I think it is best to add the callbacks now, before further changes to
socket locking.
OK?
Index: miscfs/fifofs/fifo_vnops.c
===================================================================
RCS file: src/sys/miscfs/fifofs/fifo_vnops.c,v
retrieving revision 1.79
diff -u -p -r1.79 fifo_vnops.c
--- miscfs/fifofs/fifo_vnops.c 17 Jan 2021 05:23:34 -0000 1.79
+++ miscfs/fifofs/fifo_vnops.c 11 Jul 2021 12:04:07 -0000
@@ -104,14 +104,22 @@ const struct vops fifo_vops = {
void filt_fifordetach(struct knote *kn);
int filt_fiforead(struct knote *kn, long hint);
+int filt_fiforeadmodify(struct kevent *kev, struct knote *kn);
+int filt_fiforeadprocess(struct knote *kn, struct kevent *kev);
+int filt_fiforead_common(struct knote *kn, struct socket *so);
void filt_fifowdetach(struct knote *kn);
int filt_fifowrite(struct knote *kn, long hint);
+int filt_fifowritemodify(struct kevent *kev, struct knote *kn);
+int filt_fifowriteprocess(struct knote *kn, struct kevent *kev);
+int filt_fifowrite_common(struct knote *kn, struct socket *so);
const struct filterops fiforead_filtops = {
.f_flags = FILTEROP_ISFD,
.f_attach = NULL,
.f_detach = filt_fifordetach,
.f_event = filt_fiforead,
+ .f_modify = filt_fiforeadmodify,
+ .f_process = filt_fiforeadprocess,
};
const struct filterops fifowrite_filtops = {
@@ -119,6 +127,8 @@ const struct filterops fifowrite_filtops
.f_attach = NULL,
.f_detach = filt_fifowdetach,
.f_event = filt_fifowrite,
+ .f_modify = filt_fifowritemodify,
+ .f_process = filt_fifowriteprocess,
};
/*
@@ -546,13 +556,12 @@ filt_fifordetach(struct knote *kn)
}
int
-filt_fiforead(struct knote *kn, long hint)
+filt_fiforead_common(struct knote *kn, struct socket *so)
{
- struct socket *so = (struct socket *)kn->kn_hook;
- int s, rv;
+ int rv;
+
+ soassertlocked(so);
- if ((hint & NOTE_SUBMIT) == 0)
- s = solock(so);
kn->kn_data = so->so_rcv.sb_cc;
if (so->so_state & SS_CANTRCVMORE) {
kn->kn_flags |= EV_EOF;
@@ -565,8 +574,46 @@ filt_fiforead(struct knote *kn, long hin
kn->kn_flags &= ~EV_EOF;
rv = (kn->kn_data > 0);
}
- if ((hint & NOTE_SUBMIT) == 0)
- sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_fiforead(struct knote *kn, long hint)
+{
+ struct socket *so = kn->kn_hook;
+
+ return (filt_fiforead_common(kn, so));
+}
+
+int
+filt_fiforeadmodify(struct kevent *kev, struct knote *kn)
+{
+ struct socket *so = kn->kn_hook;
+ int rv, s;
+
+ s = solock(so);
+ knote_modify(kev, kn);
+ rv = filt_fiforead_common(kn, so);
+ sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_fiforeadprocess(struct knote *kn, struct kevent *kev)
+{
+ struct socket *so = kn->kn_hook;
+ int rv, s;
+
+ s = solock(so);
+ if (kev != NULL && (kn->kn_flags & EV_ONESHOT))
+ rv = 1;
+ else
+ rv = filt_fiforead_common(kn, so);
+ if (rv != 0)
+ knote_submit(kn, kev);
+ sounlock(so, s);
return (rv);
}
@@ -580,13 +627,12 @@ filt_fifowdetach(struct knote *kn)
}
int
-filt_fifowrite(struct knote *kn, long hint)
+filt_fifowrite_common(struct knote *kn, struct socket *so)
{
- struct socket *so = (struct socket *)kn->kn_hook;
- int s, rv;
+ int rv;
+
+ soassertlocked(so);
- if ((hint & NOTE_SUBMIT) == 0)
- s = solock(so);
kn->kn_data = sbspace(so, &so->so_snd);
if (so->so_state & SS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
@@ -595,8 +641,46 @@ filt_fifowrite(struct knote *kn, long hi
kn->kn_flags &= ~EV_EOF;
rv = (kn->kn_data >= so->so_snd.sb_lowat);
}
- if ((hint & NOTE_SUBMIT) == 0)
- sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_fifowrite(struct knote *kn, long hint)
+{
+ struct socket *so = kn->kn_hook;
+
+ return (filt_fifowrite_common(kn, so));
+}
+
+int
+filt_fifowritemodify(struct kevent *kev, struct knote *kn)
+{
+ struct socket *so = kn->kn_hook;
+ int rv, s;
+
+ s = solock(so);
+ knote_modify(kev, kn);
+ rv = filt_fifowrite_common(kn, so);
+ sounlock(so, s);
+
+ return (rv);
+}
+
+int
+filt_fifowriteprocess(struct knote *kn, struct kevent *kev)
+{
+ struct socket *so = kn->kn_hook;
+ int rv, s;
+
+ s = solock(so);
+ if (kev != NULL && (kn->kn_flags & EV_ONESHOT))
+ rv = 1;
+ else
+ rv = filt_fifowrite_common(kn, so);
+ if (rv != 0)
+ knote_submit(kn, kev);
+ sounlock(so, s);
return (rv);
}