Re: git: a01bf3940271 - stable/13 - geom: add kqfilter support for geom dev
- In reply to: Robert Wing : "git: a01bf3940271 - stable/13 - geom: add kqfilter support for geom dev"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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);
>