Index: geom.h =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom.h,v retrieving revision 1.85 diff -u -p -r1.85 geom.h --- geom.h 27 Aug 2004 14:43:11 -0000 1.85 +++ geom.h 17 Sep 2004 10:33:22 -0000 @@ -214,6 +214,7 @@ int g_waitfor_event(g_event_t *func, voi void g_cancel_event(void *ref); void g_orphan_provider(struct g_provider *pp, int error); void g_waitidle(void); +void g_waitidlelock(void); /* geom_subr.c */ int g_access(struct g_consumer *cp, int nread, int nwrite, int nexcl); Index: geom_event.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_event.c,v retrieving revision 1.50 diff -u -p -r1.50 geom_event.c --- geom_event.c 8 Jul 2004 16:17:14 -0000 1.50 +++ geom_event.c 17 Sep 2004 10:23:21 -0000 @@ -84,6 +84,18 @@ g_waitidle(void) } void +g_waitidlelock(void) +{ + + g_topology_assert(); + while (g_pending_events) { + g_topology_unlock(); + tsleep(&g_pending_events, PPAUSE, "g_waitidle", hz/5); + g_topology_lock(); + } +} + +void g_orphan_provider(struct g_provider *pp, int error) { Index: mirror/g_mirror.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/mirror/g_mirror.c,v retrieving revision 1.26 diff -u -p -r1.26 g_mirror.c --- mirror/g_mirror.c 8 Sep 2004 16:37:22 -0000 1.26 +++ mirror/g_mirror.c 17 Sep 2004 18:28:59 -0000 @@ -88,8 +88,10 @@ struct g_class g_mirror_class = { static void g_mirror_destroy_provider(struct g_mirror_softc *sc); -static int g_mirror_update_disk(struct g_mirror_disk *disk, u_int state); -static void g_mirror_update_device(struct g_mirror_softc *sc, boolean_t force); +static int g_mirror_update_disk(struct g_mirror_disk *disk, u_int state, + u_int flags); +static void g_mirror_update_device(struct g_mirror_softc *sc, boolean_t force, + u_int flags); static void g_mirror_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp); static void g_mirror_sync_stop(struct g_mirror_disk *disk, int type); @@ -683,7 +685,7 @@ g_mirror_update_metadata(struct g_mirror } static void -g_mirror_bump_syncid(struct g_mirror_softc *sc) +g_mirror_bump_syncid(struct g_mirror_softc *sc, u_int flags) { struct g_mirror_disk *disk; @@ -699,6 +701,8 @@ g_mirror_bump_syncid(struct g_mirror_sof if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE || disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) { disk->d_sync.ds_syncid = sc->sc_syncid; + if ((flags & G_MIRROR_EVENT_DONTWAIT) != 0) + g_waitidlelock(); g_mirror_update_metadata(disk); } } @@ -980,6 +984,7 @@ g_mirror_sync_request(struct bio *bp) * XXX: This should be configurable. */ g_topology_lock(); + g_waitidlelock(); g_mirror_update_metadata(disk); g_topology_unlock(); } @@ -1269,7 +1274,7 @@ g_mirror_register_request(struct bio *bp if (sc->sc_bump_syncid == G_MIRROR_BUMP_ON_FIRST_WRITE) { sc->sc_bump_syncid = 0; g_topology_lock(); - g_mirror_bump_syncid(sc); + g_mirror_bump_syncid(sc, G_MIRROR_EVENT_DONTWAIT); g_topology_unlock(); } return; @@ -1362,15 +1367,17 @@ g_mirror_worker(void *arg) "Running event for device %s.", sc->sc_name); ep->e_error = 0; - g_mirror_update_device(sc, 1); + g_mirror_update_device(sc, 1, ep->e_flags); } else { /* Update disk status. */ G_MIRROR_DEBUG(3, "Running event for disk %s.", g_mirror_get_diskname(ep->e_disk)); ep->e_error = g_mirror_update_disk(ep->e_disk, - ep->e_state); - if (ep->e_error == 0) - g_mirror_update_device(sc, 0); + ep->e_state, ep->e_flags); + if (ep->e_error == 0) { + g_mirror_update_device(sc, 0, + ep->e_flags); + } } g_topology_unlock(); if ((ep->e_flags & G_MIRROR_EVENT_DONTWAIT) != 0) { @@ -1733,7 +1740,7 @@ g_mirror_determine_state(struct g_mirror * Update device state. */ static void -g_mirror_update_device(struct g_mirror_softc *sc, boolean_t force) +g_mirror_update_device(struct g_mirror_softc *sc, boolean_t force, u_int flags) { struct g_mirror_disk *disk; u_int state; @@ -1930,7 +1937,7 @@ g_mirror_update_device(struct g_mirror_s */ if (sc->sc_bump_syncid == G_MIRROR_BUMP_IMMEDIATELY) { sc->sc_bump_syncid = 0; - g_mirror_bump_syncid(sc); + g_mirror_bump_syncid(sc, flags); } break; default: @@ -1949,7 +1956,7 @@ g_mirror_update_device(struct g_mirror_s g_mirror_disk_state2str(disk->d_state), \ g_mirror_disk_state2str(state), sc->sc_name) static int -g_mirror_update_disk(struct g_mirror_disk *disk, u_int state) +g_mirror_update_disk(struct g_mirror_disk *disk, u_int state, u_int flags) { struct g_mirror_softc *sc; @@ -2031,6 +2038,8 @@ again: disk->d_state = state; disk->d_sync.ds_offset = 0; disk->d_sync.ds_offset_done = 0; + if ((flags & G_MIRROR_EVENT_DONTWAIT) != 0) + g_waitidlelock(); g_mirror_update_access(disk); g_mirror_update_metadata(disk); G_MIRROR_DEBUG(0, "Device %s: provider %s activated.", @@ -2063,6 +2072,8 @@ again: disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY; disk->d_state = state; + if ((flags & G_MIRROR_EVENT_DONTWAIT) != 0) + g_waitidlelock(); g_mirror_update_metadata(disk); G_MIRROR_DEBUG(0, "Device %s: provider %s is stale.", sc->sc_name, g_mirror_get_diskname(disk)); @@ -2087,6 +2098,8 @@ again: disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY; disk->d_state = state; if (sc->sc_provider != NULL) { + if ((flags & G_MIRROR_EVENT_DONTWAIT) != 0) + g_waitidlelock(); g_mirror_sync_start(disk); g_mirror_update_metadata(disk); } @@ -2150,6 +2163,8 @@ again: g_mirror_destroy_disk(disk); sc->sc_ndisks--; LIST_FOREACH(disk, &sc->sc_disks, d_next) { + if ((flags & G_MIRROR_EVENT_DONTWAIT) != 0) + g_waitidlelock(); g_mirror_update_metadata(disk); } break;