svn commit: r356586 - stable/12/sys/geom/virstor

Alexander Motin mav at FreeBSD.org
Fri Jan 10 00:47:38 UTC 2020


Author: mav
Date: Fri Jan 10 00:47:37 2020
New Revision: 356586
URL: https://svnweb.freebsd.org/changeset/base/356586

Log:
  MFC r356181: Fix GEOM_VIRSTOR orphanization.
  
  Previous code closed and destroyed consumer even with I/O in progress.
  This patch postpones the destruction till the last close.

Modified:
  stable/12/sys/geom/virstor/g_virstor.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/geom/virstor/g_virstor.c
==============================================================================
--- stable/12/sys/geom/virstor/g_virstor.c	Fri Jan 10 00:46:59 2020	(r356585)
+++ stable/12/sys/geom/virstor/g_virstor.c	Fri Jan 10 00:47:37 2020	(r356586)
@@ -908,7 +908,7 @@ remove_component(struct g_virstor_softc *sc, struct g_
 	}
 
 	if (c->acr > 0 || c->acw > 0 || c->ace > 0)
-		g_access(c, -c->acr, -c->acw, -c->ace);
+		return;
 	if (delay) {
 		/* Destroy consumer after it's tasted */
 		g_post_event(delay_destroy_consumer, c, M_WAITOK, NULL);
@@ -1399,7 +1399,7 @@ g_virstor_orphan(struct g_consumer *cp)
 	KASSERT(comp != NULL, ("%s: No component in private part of consumer",
 	    __func__));
 	remove_component(sc, comp, FALSE);
-	if (virstor_valid_components(sc) == 0)
+	if (LIST_EMPTY(&gp->consumer))
 		virstor_geom_destroy(sc, TRUE, FALSE);
 }
 
@@ -1409,7 +1409,7 @@ g_virstor_orphan(struct g_consumer *cp)
 static int
 g_virstor_access(struct g_provider *pp, int dr, int dw, int de)
 {
-	struct g_consumer *c;
+	struct g_consumer *c, *c2, *tmp;
 	struct g_virstor_softc *sc;
 	struct g_geom *gp;
 	int error;
@@ -1419,46 +1419,40 @@ g_virstor_access(struct g_provider *pp, int dr, int dw
 	KASSERT(gp != NULL, ("%s: NULL geom", __func__));
 	sc = gp->softc;
 
-	if (sc == NULL) {
-		/* It seems that .access can be called with negative dr,dw,dx
-		 * in this case but I want to check for myself */
-		LOG_MSG(LVL_WARNING, "access(%d, %d, %d) for %s",
-		    dr, dw, de, pp->name);
-		/* This should only happen when geom is withered so
-		 * allow only negative requests */
-		KASSERT(dr <= 0 && dw <= 0 && de <= 0,
-		    ("%s: Positive access for %s", __func__, pp->name));
-		if (pp->acr + dr == 0 && pp->acw + dw == 0 && pp->ace + de == 0)
-			LOG_MSG(LVL_DEBUG, "Device %s definitely destroyed",
-			    pp->name);
-		return (0);
-	}
-
 	/* Grab an exclusive bit to propagate on our consumers on first open */
 	if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0)
 		de++;
 	/* ... drop it on close */
 	if (pp->acr + dr == 0 && pp->acw + dw == 0 && pp->ace + de == 0) {
 		de--;
-		update_metadata(sc);	/* Writes statistical information */
+		if (sc != NULL)
+			update_metadata(sc);
 	}
 
 	error = ENXIO;
-	LIST_FOREACH(c, &gp->consumer, consumer) {
-		KASSERT(c != NULL, ("%s: consumer is NULL", __func__));
+	LIST_FOREACH_SAFE(c, &gp->consumer, consumer, tmp) {
 		error = g_access(c, dr, dw, de);
-		if (error != 0) {
-			struct g_consumer *c2;
-
-			/* Backout earlier changes */
-			LIST_FOREACH(c2, &gp->consumer, consumer) {
-				if (c2 == c) /* all eariler components fixed */
-					return (error);
-				g_access(c2, -dr, -dw, -de);
-			}
+		if (error != 0)
+			goto fail;
+		if (c->acr == 0 && c->acw == 0 && c->ace == 0 &&
+		    c->flags & G_CF_ORPHAN) {
+			g_detach(c);
+			g_destroy_consumer(c);
 		}
 	}
 
+	if (sc != NULL && LIST_EMPTY(&gp->consumer))
+		virstor_geom_destroy(sc, TRUE, FALSE);
+
+	return (error);
+
+fail:
+	/* Backout earlier changes */
+	LIST_FOREACH(c2, &gp->consumer, consumer) {
+		if (c2 == c)
+			break;
+		g_access(c2, -dr, -dw, -de);
+	}
 	return (error);
 }
 


More information about the svn-src-all mailing list