Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Apr 2022 20:54:54 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 506fac3fb303 - stable/13 - geom_vfs: Pre-allocate event for g_vfs_destroy.
Message-ID:  <202204292054.23TKssEF054915@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=506fac3fb303eef89df8ec7845228a33a010a3fe

commit 506fac3fb303eef89df8ec7845228a33a010a3fe
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2021-07-30 00:09:23 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-04-29 20:50:03 +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
    
    (cherry picked from commit 419d406e4ee068644218fb881bc80f79f8191970)
---
 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?202204292054.23TKssEF054915>