Index: geom.h =================================================================== RCS file: /usr/repo/src/sys/geom/geom.h,v retrieving revision 1.91 diff -u -p -r1.91 geom.h --- geom.h 3 Sep 2005 11:03:10 -0000 1.91 +++ geom.h 11 Feb 2006 06:55:50 -0000 @@ -62,6 +62,7 @@ typedef void g_ctl_req_t (struct gctl_re typedef int g_ctl_create_geom_t (struct gctl_req *, struct g_class *cp, struct g_provider *pp); typedef int g_ctl_destroy_geom_t (struct gctl_req *, struct g_class *cp, struct g_geom *gp); typedef int g_ctl_config_geom_t (struct gctl_req *, struct g_geom *gp, const char *verb); +typedef void g_shutdown_t (struct g_geom *gp); typedef void g_init_t (struct g_class *mp); typedef void g_fini_t (struct g_class *mp); typedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *, int flags); @@ -94,6 +95,7 @@ struct g_class { g_init_t *init; g_fini_t *fini; g_ctl_destroy_geom_t *destroy_geom; + g_shutdown_t *shutdown; /* * Default values for geom methods */ @@ -239,6 +241,7 @@ void g_std_done(struct bio *bp); void g_std_spoiled(struct g_consumer *cp); void g_wither_geom(struct g_geom *gp, int error); void g_wither_geom_close(struct g_geom *gp, int error); +void g_shutdown_geoms(void *dummy __unused); #ifdef DIAGNOSTIC int g_valid_obj(void const *ptr); Index: geom_subr.c =================================================================== RCS file: /usr/repo/src/sys/geom/geom_subr.c,v retrieving revision 1.88 diff -u -p -r1.88 geom_subr.c --- geom_subr.c 18 Nov 2005 02:43:49 -0000 1.88 +++ geom_subr.c 11 Feb 2006 06:57:06 -0000 @@ -243,6 +243,24 @@ g_modevent(module_t mod, int type, void return (error); } +/* + * On shutdown try to destroy geoms sorted by rank#. + */ +void +g_shutdown_geoms(void *dummy __unused) +{ + struct g_geom *gp, *gp2; + + DROP_GIANT(); + g_topology_lock(); + TAILQ_FOREACH_REVERSE_SAFE(gp, &geoms, g_tailq_head, geoms, gp2) { + if (gp->class->shutdown != NULL) + gp->class->shutdown(gp); + } + g_topology_unlock(); + PICKUP_GIANT(); +} + struct g_geom * g_new_geomf(struct g_class *mp, const char *fmt, ...) { Index: geom_kern.c =================================================================== RCS file: /usr/repo/src/sys/geom/geom_kern.c,v retrieving revision 1.40 diff -u -p -r1.40 geom_kern.c --- geom_kern.c 25 Nov 2005 10:09:30 -0000 1.40 +++ geom_kern.c 11 Feb 2006 06:56:01 -0000 @@ -172,6 +172,8 @@ g_init(void) mtx_unlock(&Giant); EVENTHANDLER_REGISTER(shutdown_pre_sync, geom_shutdown, NULL, SHUTDOWN_PRI_FIRST); + EVENTHANDLER_REGISTER(shutdown_post_sync, g_shutdown_geoms, NULL, + SHUTDOWN_PRI_FIRST); } static int Index: mirror/g_mirror.c =================================================================== RCS file: /usr/repo/src/sys/geom/mirror/g_mirror.c,v retrieving revision 1.70 diff -u -p -r1.70 g_mirror.c --- mirror/g_mirror.c 1 Feb 2006 12:06:00 -0000 1.70 +++ mirror/g_mirror.c 11 Feb 2006 06:53:49 -0000 @@ -77,13 +77,10 @@ SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, G_MIRROR_DEBUG(4, "%s: Woken up %p.", __func__, (ident)); \ } while (0) -static eventhandler_tag g_mirror_ehtag = NULL; - static int g_mirror_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp); static g_taste_t g_mirror_taste; -static void g_mirror_init(struct g_class *mp); -static void g_mirror_fini(struct g_class *mp); +static void g_mirror_shutdown(struct g_geom *gp); struct g_class g_mirror_class = { .name = G_MIRROR_CLASS_NAME, @@ -91,8 +88,7 @@ struct g_class g_mirror_class = { .ctlreq = g_mirror_config, .taste = g_mirror_taste, .destroy_geom = g_mirror_destroy_geom, - .init = g_mirror_init, - .fini = g_mirror_fini + .shutdown = g_mirror_shutdown }; @@ -2839,43 +2835,15 @@ g_mirror_dumpconf(struct sbuf *sb, const } static void -g_mirror_shutdown(void *arg, int howto) -{ - struct g_class *mp; - struct g_geom *gp, *gp2; - - mp = arg; - DROP_GIANT(); - g_topology_lock(); - LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { - if (gp->softc == NULL) - continue; - g_mirror_destroy(gp->softc, 1); - } - g_topology_unlock(); - PICKUP_GIANT(); -#if 0 - tsleep(&gp, PRIBIO, "m:shutdown", hz * 20); -#endif -} - -static void -g_mirror_init(struct g_class *mp) -{ - - g_mirror_ehtag = EVENTHANDLER_REGISTER(shutdown_post_sync, - g_mirror_shutdown, mp, SHUTDOWN_PRI_FIRST); - if (g_mirror_ehtag == NULL) - G_MIRROR_DEBUG(0, "Warning! Cannot register shutdown event."); -} - -static void -g_mirror_fini(struct g_class *mp) +g_mirror_shutdown(struct g_geom *gp) { + struct g_mirror_softc *sc; - if (g_mirror_ehtag == NULL) + g_topology_assert(); + sc = gp->softc; + if (sc == NULL || gp == sc->sc_sync.ds_geom) return; - EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_mirror_ehtag); + g_mirror_destroy(sc, 1); } DECLARE_GEOM_CLASS(g_mirror_class, g_mirror); Index: raid3/g_raid3.c =================================================================== RCS file: /usr/repo/src/sys/geom/raid3/g_raid3.c,v retrieving revision 1.47 diff -u -p -r1.47 g_raid3.c --- raid3/g_raid3.c 1 Feb 2006 12:06:00 -0000 1.47 +++ raid3/g_raid3.c 11 Feb 2006 06:54:02 -0000 @@ -114,13 +114,10 @@ SYSCTL_UINT(_kern_geom_raid3_stat, OID_A G_RAID3_DEBUG(4, "%s: Woken up %p.", __func__, (ident)); \ } while (0) -static eventhandler_tag g_raid3_ehtag = NULL; - static int g_raid3_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp); static g_taste_t g_raid3_taste; -static void g_raid3_init(struct g_class *mp); -static void g_raid3_fini(struct g_class *mp); +static void g_raid3_shutdown(struct g_geom *gp); struct g_class g_raid3_class = { .name = G_RAID3_CLASS_NAME, @@ -128,8 +125,7 @@ struct g_class g_raid3_class = { .ctlreq = g_raid3_config, .taste = g_raid3_taste, .destroy_geom = g_raid3_destroy_geom, - .init = g_raid3_init, - .fini = g_raid3_fini + .shutdown = g_raid3_shutdown }; @@ -3088,43 +3084,15 @@ g_raid3_dumpconf(struct sbuf *sb, const } static void -g_raid3_shutdown(void *arg, int howto) -{ - struct g_class *mp; - struct g_geom *gp, *gp2; - - mp = arg; - DROP_GIANT(); - g_topology_lock(); - LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { - if (gp->softc == NULL) - continue; - g_raid3_destroy(gp->softc, 1); - } - g_topology_unlock(); - PICKUP_GIANT(); -#if 0 - tsleep(&gp, PRIBIO, "r3:shutdown", hz * 20); -#endif -} - -static void -g_raid3_init(struct g_class *mp) -{ - - g_raid3_ehtag = EVENTHANDLER_REGISTER(shutdown_post_sync, - g_raid3_shutdown, mp, SHUTDOWN_PRI_FIRST); - if (g_raid3_ehtag == NULL) - G_RAID3_DEBUG(0, "Warning! Cannot register shutdown event."); -} - -static void -g_raid3_fini(struct g_class *mp) +g_raid3_shutdown(struct g_geom *gp) { + struct g_raid3_softc *sc; - if (g_raid3_ehtag == NULL) + g_topology_assert(); + sc = gp->softc; + if (sc == NULL || gp == sc->sc_sync.ds_geom) return; - EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_raid3_ehtag); + g_raid3_destroy(sc, 1); } DECLARE_GEOM_CLASS(g_raid3_class, g_raid3);