I forgot to pass the -x flag to git cherry pick on this one. This commit was cherry picked from a50e92cc203c1e3dd2cca03410b568f76694895c
On Wed, Feb 23, 2022 at 8:42 AM Robert Wing <r...@freebsd.org> wrote: > The branch stable/13 has been updated by rew: > > URL: > https://cgit.FreeBSD.org/src/commit/?id=a01bf3940271fa118d6fa306d80f44fc534f58b5 > > commit a01bf3940271fa118d6fa306d80f44fc534f58b5 > Author: Robert Wing <r...@freebsd.org> > AuthorDate: 2022-01-18 19:54:59 +0000 > Commit: Robert Wing <r...@freebsd.org> > CommitDate: 2022-02-23 17:26:49 +0000 > > geom: add kqfilter support for geom dev > > The only event hooked up is NOTE_ATTRIB, which is triggered when the > device is resized. Support for other NOTE_* events to follow. > > Reviewed by: kib, jhb > Differential Revision: https://reviews.freebsd.org/D33402 > --- > sys/geom/geom_dev.c | 59 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 59 insertions(+) > > diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c > index 24ab14e90c1b..b94df9fcda67 100644 > --- a/sys/geom/geom_dev.c > +++ b/sys/geom/geom_dev.c > @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/disk.h> > #include <sys/fcntl.h> > #include <sys/limits.h> > +#include <sys/selinfo.h> > #include <sys/sysctl.h> > #include <geom/geom.h> > #include <geom/geom_int.h> > @@ -65,6 +66,7 @@ struct g_dev_softc { > struct cdev *sc_alias; > int sc_open; > u_int sc_active; > + struct selinfo sc_selinfo; > #define SC_A_DESTROY (1 << 31) > #define SC_A_OPEN (1 << 30) > #define SC_A_ACTIVE (SC_A_OPEN - 1) > @@ -74,6 +76,16 @@ static d_open_t g_dev_open; > static d_close_t g_dev_close; > static d_strategy_t g_dev_strategy; > static d_ioctl_t g_dev_ioctl; > +static d_kqfilter_t g_dev_kqfilter; > + > +static void gdev_filter_detach(struct knote *kn); > +static int gdev_filter_vnode(struct knote *kn, long hint); > + > +static struct filterops gdev_filterops_vnode = { > + .f_isfd = 1, > + .f_detach = gdev_filter_detach, > + .f_event = gdev_filter_vnode, > +}; > > static struct cdevsw g_dev_cdevsw = { > .d_version = D_VERSION, > @@ -85,6 +97,7 @@ static struct cdevsw g_dev_cdevsw = { > .d_strategy = g_dev_strategy, > .d_name = "g_dev", > .d_flags = D_DISK | D_TRACKCLOSE, > + .d_kqfilter = g_dev_kqfilter, > }; > > static g_init_t g_dev_init; > @@ -214,6 +227,8 @@ g_dev_destroy(void *arg, int flags __unused) > g_trace(G_T_TOPOLOGY, "g_dev_destroy(%p(%s))", cp, gp->name); > snprintf(buf, sizeof(buf), "cdev=%s", gp->name); > devctl_notify("GEOM", "DEV", "DESTROY", buf); > + knlist_clear(&sc->sc_selinfo.si_note, 0); > + knlist_destroy(&sc->sc_selinfo.si_note); > if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) > g_access(cp, -cp->acr, -cp->acw, -cp->ace); > g_detach(cp); > @@ -305,8 +320,12 @@ g_dev_attrchanged(struct g_consumer *cp, const char > *attr) > static void > g_dev_resize(struct g_consumer *cp) > { > + struct g_dev_softc *sc; > char buf[SPECNAMELEN + 6]; > > + sc = cp->private; > + KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, NOTE_ATTRIB); > + > snprintf(buf, sizeof(buf), "cdev=%s", cp->provider->name); > devctl_notify("GEOM", "DEV", "SIZECHANGE", buf); > } > @@ -378,6 +397,7 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, > int insist __unused) > dev = sc->sc_dev; > dev->si_flags |= SI_UNMAPPED; > dev->si_iosize_max = maxphys; > + knlist_init_mtx(&sc->sc_selinfo.si_note, &sc->sc_mtx); > error = init_dumpdev(dev); > if (error != 0) > printf("%s: init_dumpdev() failed (gp->name=%s, > error=%d)\n", > @@ -883,4 +903,43 @@ g_dev_orphan(struct g_consumer *cp) > destroy_dev_sched_cb(dev, g_dev_callback, cp); > } > > +static void > +gdev_filter_detach(struct knote *kn) > +{ > + struct g_dev_softc *sc; > + > + sc = kn->kn_hook; > + > + knlist_remove(&sc->sc_selinfo.si_note, kn, 0); > +} > + > +static int > +gdev_filter_vnode(struct knote *kn, long hint) > +{ > + kn->kn_fflags |= kn->kn_sfflags & hint; > + > + return (kn->kn_fflags != 0); > +} > + > +static int > +g_dev_kqfilter(struct cdev *dev, struct knote *kn) > +{ > + struct g_dev_softc *sc; > + > + sc = dev->si_drv1; > + > + if (kn->kn_filter != EVFILT_VNODE) > + return (EINVAL); > + > + /* XXX: extend support for other NOTE_* events */ > + if (kn->kn_sfflags != NOTE_ATTRIB) > + return (EINVAL); > + > + kn->kn_fop = &gdev_filterops_vnode; > + kn->kn_hook = sc; > + knlist_add(&sc->sc_selinfo.si_note, kn, 0); > + > + return (0); > +} > + > DECLARE_GEOM_CLASS(g_dev_class, g_dev); >