PERFORCE change 112634 for review

Matt Jacob mjacob at FreeBSD.org
Sat Jan 6 21:35:55 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=112634

Change 112634 by mjacob at mjexp_6 on 2007/01/07 05:35:25

	Some more cleanups to catch a race between orphan and I/O failure
	       decommissioning actions.
	
	Make sure we don't add the same disk twice. Note when
	       we destroy a multipath geom.

Affected files ...

.. //depot/projects/mjexp_6/sys/geom/multipath/g_multipath.c#6 edit

Differences ...

==== //depot/projects/mjexp_6/sys/geom/multipath/g_multipath.c#6 (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.
@@ -290,6 +291,19 @@
 	sc = gp->softc;
 	KASSERT(sc, ("no softc"));
 
+	/*
+	 * Make sure that the passed provider isn't already attached
+	 */
+	LIST_FOREACH(cp, &gp->consumer, consumer) {
+		if (cp->provider == pp) {
+			break;
+		}
+	}
+	if (cp) {
+		printf("GEOM_MULTIPATH: provider %s already attached to %s\n",
+		    pp->name, gp->name);
+		return (EEXIST);
+	}
 	nxtcp = LIST_FIRST(&gp->consumer);
 	cp = g_new_consumer(gp);
 	if (cp == NULL) {
@@ -318,12 +332,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);
 }
 
@@ -340,6 +355,7 @@
 	if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
 		return (EBUSY);
 	}
+	printf("GEOM_MULTIPATH: destroying %s\n", gp->name);
 	g_free(gp->softc);
 	gp->softc = NULL;
 	g_wither_geom(gp, ENXIO);


More information about the p4-projects mailing list