Index: geom_subr.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_subr.c,v retrieving revision 1.78 diff -u -p -r1.78 geom_subr.c --- geom_subr.c 9 Jul 2004 14:06:17 -0000 1.78 +++ geom_subr.c 25 Jul 2004 07:45:35 -0000 @@ -328,6 +328,29 @@ g_wither_washer() else result |= 1; } + /* + * Spoiling happens when a provider is opened for writing, but + * consumers which are configured by in-band data are attached + * (slicers for instance). Since the write might potentially + * change the in-band data, such consumers need to re-evaluate + * their existence after the writing session closes. We do this + * by (offering to) tear them down when the open for write + * happens in return for a re-taste when it closes again. + * Together with the fact that such consumers grab an 'e' bit + * whenever they are open, regardless of mode, this ends up DTRT. + */ + LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { + LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp2) { + if (!cp->spoiled) + continue; + cp->spoiled = 0; + if (cp->geom->spoiled == NULL) + continue; + cp->geom->spoiled(cp); + g_topology_assert(); + result |= 2; + } + } } return (result); } @@ -777,40 +800,6 @@ g_std_spoiled(struct g_consumer *cp) gp->flags |= G_GEOM_WITHER; } -/* - * Spoiling happens when a provider is opened for writing, but consumers - * which are configured by in-band data are attached (slicers for instance). - * Since the write might potentially change the in-band data, such consumers - * need to re-evaluate their existence after the writing session closes. - * We do this by (offering to) tear them down when the open for write happens - * in return for a re-taste when it closes again. - * Together with the fact that such consumers grab an 'e' bit whenever they - * are open, regardless of mode, this ends up DTRT. - */ - -static void -g_spoil_event(void *arg, int flag) -{ - struct g_provider *pp; - struct g_consumer *cp, *cp2; - - g_topology_assert(); - if (flag == EV_CANCEL) - return; - pp = arg; - G_VALID_PROVIDER(pp); - for (cp = LIST_FIRST(&pp->consumers); cp != NULL; cp = cp2) { - cp2 = LIST_NEXT(cp, consumers); - if (!cp->spoiled) - continue; - cp->spoiled = 0; - if (cp->geom->spoiled == NULL) - continue; - cp->geom->spoiled(cp); - g_topology_assert(); - } -} - void g_spoil(struct g_provider *pp, struct g_consumer *cp) { @@ -829,8 +818,8 @@ g_spoil(struct g_provider *pp, struct g_ */ KASSERT(cp2->ace == 0, ("spoiling cp->ace = %d", cp2->ace)); cp2->spoiled++; + g_do_wither(); } - g_post_event(g_spoil_event, pp, M_WAITOK, pp, NULL); } int