Index: geom_subr.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_subr.c,v retrieving revision 1.75 diff -u -p -r1.75 geom_subr.c --- geom_subr.c 18 Mar 2004 07:17:10 -0000 1.75 +++ geom_subr.c 28 Jun 2004 11:52:25 -0000 @@ -62,6 +62,21 @@ struct g_hh00 { int error; }; +static int +g_spoiled(struct g_provider *pp) +{ + struct g_consumer *cp; + int spoiled = 0; + + LIST_FOREACH(cp, &pp->geom->consumer, consumer) { + if (cp->provider != NULL && cp->spoiled) { + spoiled = 1; + break; + } + } + return (spoiled); +} + /* * This event offers a new class a chance to taste all preexisting providers. */ @@ -103,6 +118,11 @@ g_load_class(void *arg, int flag) continue; LIST_FOREACH(gp, &mp2->geom, geom) { LIST_FOREACH(pp, &gp->provider, provider) { + /* + * Nobody wants to taste spoiled provider. + */ + if (g_spoiled(pp)) + continue; mp->taste(mp, pp, 0); g_topology_assert(); } @@ -289,7 +309,8 @@ g_wither_geom(struct g_geom *gp, int err cp2 = LIST_NEXT(cp, consumer); if (cp->acr || cp->acw || cp->ace) continue; - g_detach(cp); + if (cp->provider != NULL) + g_detach(cp); g_destroy_consumer(cp); } if (LIST_EMPTY(&gp->provider) && LIST_EMPTY(&gp->consumer)) @@ -364,7 +385,13 @@ g_new_provider_event(void *arg, int flag i = 0; if (!i) continue; + /* + * Nobody wants to taste spoiled provider. + */ + if (g_spoiled(pp)) + break; mp->taste(mp, pp, 0); + G_VALID_PROVIDER(pp); g_topology_assert(); } } @@ -440,6 +467,7 @@ g_destroy_provider(struct g_provider *pp g_topology_assert(); G_VALID_PROVIDER(pp); + g_trace(G_T_TOPOLOGY, "g_destroy_provider(%p(%s))", pp, pp->name); KASSERT(LIST_EMPTY(&pp->consumers), ("g_destroy_provider but attached")); KASSERT (pp->acr == 0, ("g_destroy_provider with acr"));