Date: Fri, 30 Jul 2021 00:09:57 GMT From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 419d406e4ee0 - main - geom_vfs: Pre-allocate event for g_vfs_destroy. Message-ID: <202107300009.16U09vhB004443@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=419d406e4ee068644218fb881bc80f79f8191970 commit 419d406e4ee068644218fb881bc80f79f8191970 Author: John Baldwin <jhb@FreeBSD.org> AuthorDate: 2021-07-30 00:09:23 +0000 Commit: John Baldwin <jhb@FreeBSD.org> CommitDate: 2021-07-30 00:09:23 +0000 geom_vfs: Pre-allocate event for g_vfs_destroy. When an active g_vfs is orphaned due to an underlying disk going away the destroy is deferred until the filesystem is unmounted in g_vfs_done(). However, g_vfs_done() is invoked from a non-sleepable context and cannot use M_WAITOK to allocate the event. Instead, allocate the event in g_vfs_orphan() and save it in the softc to be retrieved by the last call to g_vfs_done(). Reported by: Jithesh Arakkan @ Chelsio Reviewed by: imp Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D31354 --- sys/geom/geom_vfs.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c index f01765b8ee30..592062b8b12a 100644 --- a/sys/geom/geom_vfs.c +++ b/sys/geom/geom_vfs.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); struct g_vfs_softc { struct mtx sc_mtx; struct bufobj *sc_bo; + struct g_event *sc_event; int sc_active; int sc_orphaned; int sc_enxio_active; @@ -96,6 +97,7 @@ static void g_vfs_done(struct bio *bip) { struct g_consumer *cp; + struct g_event *event; struct g_vfs_softc *sc; struct buf *bp; int destroy; @@ -157,9 +159,14 @@ g_vfs_done(struct bio *bip) mtx_lock(&sc->sc_mtx); destroy = ((--sc->sc_active) == 0 && sc->sc_orphaned); + if (destroy) { + event = sc->sc_event; + sc->sc_event = NULL; + } else + event = NULL; mtx_unlock(&sc->sc_mtx); if (destroy) - g_post_event(g_vfs_destroy, cp, M_WAITOK, NULL); + g_post_event_ep(g_vfs_destroy, cp, event, NULL); bufdone(bp); } @@ -212,6 +219,7 @@ static void g_vfs_orphan(struct g_consumer *cp) { struct g_geom *gp; + struct g_event *event; struct g_vfs_softc *sc; int destroy; @@ -222,12 +230,20 @@ g_vfs_orphan(struct g_consumer *cp) sc = gp->softc; if (sc == NULL) return; + event = g_alloc_event(M_WAITOK); mtx_lock(&sc->sc_mtx); + KASSERT(sc->sc_event == NULL, ("g_vfs %p already has an event", sc)); sc->sc_orphaned = 1; destroy = (sc->sc_active == 0); + if (!destroy) { + sc->sc_event = event; + event = NULL; + } mtx_unlock(&sc->sc_mtx); - if (destroy) + if (destroy) { + g_free(event); g_vfs_destroy(cp, 0); + } /* * Do not destroy the geom. Filesystem will do that during unmount. @@ -297,5 +313,6 @@ g_vfs_close(struct g_consumer *cp) mtx_destroy(&sc->sc_mtx); if (!sc->sc_orphaned || cp->provider == NULL) g_wither_geom_close(gp, ENXIO); + KASSERT(sc->sc_event == NULL, ("g_vfs %p event is non-NULL", sc)); g_free(sc); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202107300009.16U09vhB004443>