git: a01bf3940271 - stable/13 - geom: add kqfilter support for geom dev
Date: Wed, 23 Feb 2022 17:42:05 UTC
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);