Date: Sun, 7 Jan 2007 05:35:54 GMT From: Matt Jacob <mjacob@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 112634 for review Message-ID: <200701070535.l075Zs1i084543@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=112634 Change 112634 by mjacob@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701070535.l075Zs1i084543>