Re: git: a01bf3940271 - stable/13 - geom: add kqfilter support for geom dev

From: Rob Wing <rew_at_freebsd.org>
Date: Wed, 23 Feb 2022 19:06:40 UTC
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 <rew@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 <rew@FreeBSD.org>
> AuthorDate: 2022-01-18 19:54:59 +0000
> Commit:     Robert Wing <rew@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);
>