Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 7 Jan 2007 05:13:23 GMT
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 112630 for review
Message-ID:  <200701070513.l075DNbu081063@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=112630

Change 112630 by mjacob@mjexp on 2007/01/07 05:12:26

	Some more cleanups to catch a race between orphan and I/O failure
	decommissioning actions.

Affected files ...

.. //depot/projects/mjexp/sys/geom/multipath/g_multipath.c#11 edit

Differences ...

==== //depot/projects/mjexp/sys/geom/multipath/g_multipath.c#11 (text+ko) ====

@@ -70,13 +70,36 @@
 	.destroy_geom = g_multipath_destroy_geom
 };
 
+#define	MP_BAD		0x1
+#define	MP_POSTED	0x2
+
+static void
+g_mpd(void *arg, int flags __unused)
+{
+	struct g_consumer *cp;
+
+	g_topology_assert();
+	cp = arg;
+	if (cp->acr > 0 || cp->acw > 0 || cp->ace > 0) {
+		g_access(cp, -cp->acr, -cp->acw, -cp->ace);
+	}
+	if (cp->provider) {
+		printf("GEOM_MULTIPATH: %s removed from %s\n",
+		    cp->provider->name, cp->geom->name);
+		g_detach(cp);
+	}
+	g_destroy_consumer(cp);
+}
 
 static void
 g_multipath_orphan(struct g_consumer *cp)
 {
-printf("%s called on %s\n", __FUNCTION__, cp->provider? cp->provider->name : "none");
-	g_topology_assert();
-	g_multipath_destroy(cp->geom);
+	if ((cp->index & MP_POSTED) == 0) {
+		cp->index |= MP_POSTED;
+		printf("GEOM_MULTIPATH: %s orphaned in %s\n",
+		    cp->provider->name, cp->geom->name);
+		g_mpd(cp, 0);
+	}
 }
 
 static void
@@ -105,17 +128,6 @@
 }
 
 static void
-g_mpd(void *arg, int flags __unused)
-{
-	struct g_consumer *cp;
-        g_topology_assert();
-	cp = arg;
-	g_access(cp, -cp->acr, -cp->acw, -cp->ace);
-	g_detach(cp);
-	g_destroy_consumer(cp);
-}
-
-static void
 g_multipath_done(struct bio *bp)
 {
 	struct bio *pbp = bp->bio_parent;
@@ -127,16 +139,6 @@
 
 	if (bp->bio_error == ENXIO || bp->bio_error == EIO) {
 		dofail = 1;
-#if	0
-	} else if (bp->bio_error == 0) {
-		static uint8_t inject = 0;
-		if (++inject == 0) {
-			bp->bio_error = ENXIO;
-			dofail = 1;
-		} else {
-			dofail = 0;
-		}
-#endif
 	} else {
 		dofail = 0;
 	}
@@ -154,13 +156,17 @@
 		 * to the next available consumer.
 		 */
 		g_topology_lock();
+		cp->index |= MP_BAD;
+		if (cp->nend == cp->nstart && pp->nend == pp->nstart) {
+			cp->index |= MP_POSTED;
+			g_post_event(g_mpd, cp, M_NOWAIT, NULL);
+		}
 		if (cp == sc->cp_active) {
-			printf("GEOM_MULTIPATH: I/O failure terminates use of "
-			    "%s in %s\n", cp->provider->name, gp->name);
-			cp->index = 1;
+			printf("GEOM_MULTIPATH: %s failed in %s\n",
+			    pp->name, sc->sc_name);
 			sc->cp_active = NULL;
 			LIST_FOREACH(lcp, &gp->consumer, consumer) {
-				if (lcp->index == 0) {
+				if ((lcp->index & MP_BAD) == 0) {
 					sc->cp_active = lcp;
 					break;
 				}
@@ -170,15 +176,10 @@
 				g_topology_unlock();
 				goto out;
 			}
-			printf("GEOM_MULTIPATH: switching to provider %s\n",
-			    sc->cp_active->provider->name);
+			printf("GEOM_MULTIPATH: %s now active path in %s\n",
+			    sc->cp_active->provider->name, sc->sc_name);
 		}
 		g_topology_unlock();
-		if (cp->nend == cp->nstart && pp->nend == pp->nstart) {
-			printf("GEOM_MULTIPATH: old provider %s is now quiet\n",
-			    pp->name);
-			g_post_event(g_mpd, cp, M_NOWAIT, NULL);
-		}
 
 		/*
 		 * If we can fruitfully restart the I/O, do so.
@@ -318,12 +319,13 @@
 			return (error);
 		}
 	}
+	printf("GEOM_MULTIPATH: adding %s to %s/%s\n",
+	    pp->name, sc->sc_name, sc->sc_uuid);
 	if (sc->cp_active == NULL) {
 		sc->cp_active = cp;
-		printf("GEOM_MULTIPATH: activating %s/%s\n",
-		    sc->sc_name, sc->sc_uuid);
+		printf("GEOM_MULTIPATH: %s now active path in %s\n",
+		    pp->name, sc->sc_name);
 	}
-	printf("GEOM_MULTIPATH: adding %s to %s\n", pp->name, sc->sc_name);
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701070513.l075DNbu081063>