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