Index: g_mirror.c =================================================================== RCS file: /usr/repo/src/sys/geom/mirror/g_mirror.c,v retrieving revision 1.67 diff -u -p -r1.67 g_mirror.c --- g_mirror.c 31 Oct 2005 15:41:22 -0000 1.67 +++ g_mirror.c 4 Nov 2005 20:40:28 -0000 @@ -509,7 +509,7 @@ g_mirror_destroy_device(struct g_mirror_ for (disk = LIST_FIRST(&sc->sc_disks); disk != NULL; disk = LIST_FIRST(&sc->sc_disks)) { disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); g_mirror_destroy_disk(disk); } while ((ep = g_mirror_event_get(sc)) != NULL) { @@ -606,7 +606,7 @@ g_mirror_write_metadata(struct g_mirror_ u_char *sector; int error = 0; - g_topology_assert(); + g_topology_assert_not(); sc = disk->d_softc; cp = disk->d_consumer; @@ -620,9 +620,7 @@ g_mirror_write_metadata(struct g_mirror_ sector = malloc((size_t)length, M_MIRROR, M_WAITOK | M_ZERO); if (md != NULL) mirror_metadata_encode(md, sector); - g_topology_unlock(); error = g_write_data(cp, offset, sector, length); - g_topology_lock(); free(sector, M_MIRROR); if (error != 0) { disk->d_softc->sc_bump_id |= G_MIRROR_BUMP_GENID; @@ -633,11 +631,14 @@ g_mirror_write_metadata(struct g_mirror_ } static int -g_mirror_clear_metadata(struct g_mirror_disk *disk) +g_mirror_clear_metadata(struct g_mirror_disk *disk, int locked) { int error; - g_topology_assert(); + if (locked) + g_topology_unlock(); + else + g_topology_assert_not(); error = g_mirror_write_metadata(disk, NULL); if (error == 0) { G_MIRROR_DEBUG(2, "Metadata on %s cleared.", @@ -647,6 +648,8 @@ g_mirror_clear_metadata(struct g_mirror_ "Cannot clear metadata on disk %s (error=%d).", g_mirror_get_diskname(disk), error); } + if (locked) + g_topology_lock(); return (error); } @@ -693,12 +696,15 @@ g_mirror_fill_metadata(struct g_mirror_s } void -g_mirror_update_metadata(struct g_mirror_disk *disk) +g_mirror_update_metadata(struct g_mirror_disk *disk, int locked) { struct g_mirror_metadata md; int error; - g_topology_assert(); + if (locked) + g_topology_unlock(); + else + g_topology_assert_not(); g_mirror_fill_metadata(disk->d_softc, disk, &md); error = g_mirror_write_metadata(disk, &md); if (error == 0) { @@ -709,6 +715,8 @@ g_mirror_update_metadata(struct g_mirror "Cannot update metadata on disk %s (error=%d).", g_mirror_get_diskname(disk), error); } + if (locked) + g_topology_lock(); } static void @@ -724,13 +732,15 @@ g_mirror_bump_syncid(struct g_mirror_sof sc->sc_syncid++; G_MIRROR_DEBUG(1, "Device %s: syncid bumped to %u.", sc->sc_name, sc->sc_syncid); + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { 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; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } } + g_topology_lock(); } static void @@ -746,13 +756,15 @@ g_mirror_bump_genid(struct g_mirror_soft sc->sc_genid++; G_MIRROR_DEBUG(1, "Device %s: genid bumped to %u.", sc->sc_name, sc->sc_genid); + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE || disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) { disk->d_genid = sc->sc_genid; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } } + g_topology_lock(); } static void @@ -763,16 +775,16 @@ g_mirror_idle(struct g_mirror_softc *sc) if (sc->sc_provider == NULL || sc->sc_provider->acw == 0) return; sc->sc_idle = 1; - g_topology_lock(); + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE) continue; G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as clean.", g_mirror_get_diskname(disk), sc->sc_name); disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } - g_topology_unlock(); + g_topology_lock(); } static void @@ -781,16 +793,16 @@ g_mirror_unidle(struct g_mirror_softc *s struct g_mirror_disk *disk; sc->sc_idle = 0; - g_topology_lock(); + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE) continue; G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as dirty.", g_mirror_get_diskname(disk), sc->sc_name); disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } - g_topology_unlock(); + g_topology_lock(); } /* @@ -1101,9 +1113,7 @@ g_mirror_sync_request(struct bio *bp) * Update offset_done on every 100 blocks. * XXX: This should be configurable. */ - g_topology_lock(); - g_mirror_update_metadata(disk); - g_topology_unlock(); + g_mirror_update_metadata(disk, 0); } return; } @@ -2197,7 +2207,7 @@ again: disk->d_sync.ds_offset = 0; disk->d_sync.ds_offset_done = 0; g_mirror_update_access(disk); - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); G_MIRROR_DEBUG(0, "Device %s: provider %s activated.", sc->sc_name, g_mirror_get_diskname(disk)); break; @@ -2228,7 +2238,7 @@ again: disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY; disk->d_state = state; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); G_MIRROR_DEBUG(0, "Device %s: provider %s is stale.", sc->sc_name, g_mirror_get_diskname(disk)); break; @@ -2253,7 +2263,7 @@ again: disk->d_state = state; if (sc->sc_provider != NULL) { g_mirror_sync_start(disk); - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); } break; case G_MIRROR_DISK_STATE_DISCONNECTED: @@ -2305,7 +2315,7 @@ again: { int error; - error = g_mirror_clear_metadata(disk); + error = g_mirror_clear_metadata(disk, 1); if (error != 0) return (error); DISK_STATE_CHANGED(); @@ -2314,9 +2324,11 @@ again: g_mirror_destroy_disk(disk); sc->sc_ndisks--; + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } + g_topology_lock(); break; } default: @@ -2470,7 +2482,7 @@ g_mirror_add_disk(struct g_mirror_softc if (md->md_version < G_MIRROR_VERSION) { G_MIRROR_DEBUG(0, "Upgrading metadata on %s (v%d->v%d).", pp->name, md->md_version, G_MIRROR_VERSION); - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); } return (0); } @@ -2498,6 +2510,7 @@ g_mirror_access(struct g_provider *pp, i else return (ENXIO); } + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE) continue; @@ -2509,15 +2522,16 @@ g_mirror_access(struct g_provider *pp, i "Disk %s (device %s) marked as dirty.", g_mirror_get_diskname(disk), sc->sc_name); disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } else if (pp->acw > 0 && dcw == 0) { G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as clean.", g_mirror_get_diskname(disk), sc->sc_name); disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } } + g_topology_lock(); return (0); } Index: g_mirror.h =================================================================== RCS file: /usr/repo/src/sys/geom/mirror/g_mirror.h,v retrieving revision 1.17 diff -u -p -r1.17 g_mirror.h --- g_mirror.h 19 Apr 2005 21:47:25 -0000 1.17 +++ g_mirror.h 4 Nov 2005 20:24:57 -0000 @@ -205,7 +205,7 @@ int g_mirror_add_disk(struct g_mirror_so int g_mirror_read_metadata(struct g_consumer *cp, struct g_mirror_metadata *md); void g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk, struct g_mirror_metadata *md); -void g_mirror_update_metadata(struct g_mirror_disk *disk); +void g_mirror_update_metadata(struct g_mirror_disk *disk, int locked); g_ctl_req_t g_mirror_config; #endif /* _KERNEL */ Index: g_mirror_ctl.c =================================================================== RCS file: /usr/repo/src/sys/geom/mirror/g_mirror_ctl.c,v retrieving revision 1.11 diff -u -p -r1.11 g_mirror_ctl.c --- g_mirror_ctl.c 25 Apr 2005 10:41:26 -0000 1.11 +++ g_mirror_ctl.c 4 Nov 2005 20:25:00 -0000 @@ -71,7 +71,6 @@ g_mirror_find_disk(struct g_mirror_softc { struct g_mirror_disk *disk; - g_topology_assert(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (disk->d_consumer == NULL) continue; @@ -187,6 +186,7 @@ g_mirror_ctl_configure(struct gctl_req * if (*noautosync) sc->sc_flags |= G_MIRROR_DEVICE_FLAG_NOAUTOSYNC; } + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { if (do_sync) { if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) @@ -196,7 +196,7 @@ g_mirror_ctl_configure(struct gctl_req * disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED; else if (*dynamic) disk->d_flags &= ~G_MIRROR_DISK_FLAG_HARDCODED; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); if (do_sync) { if (disk->d_state == G_MIRROR_DISK_STATE_STALE) { g_mirror_event_send(disk, @@ -205,6 +205,7 @@ g_mirror_ctl_configure(struct gctl_req * } } } + g_topology_lock(); } static void @@ -270,7 +271,7 @@ g_mirror_ctl_rebuild(struct gctl_req *re disk->d_sync.ds_syncid = 0; if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOAUTOSYNC) != 0) disk->d_flags |= G_MIRROR_DISK_FLAG_FORCE_SYNC; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); pp = disk->d_consumer->provider; error = g_mirror_read_metadata(disk->d_consumer, &md); g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DISCONNECTED, @@ -435,9 +436,11 @@ again: g_free(disks); return; } + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } + g_topology_lock(); /* * Release provider and wait for retaste. */ @@ -548,7 +551,7 @@ g_mirror_ctl_deactivate(struct gctl_req } disk->d_flags |= G_MIRROR_DISK_FLAG_INACTIVE; disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC; - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 1); sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID; g_mirror_event_send(disk, G_MIRROR_DISK_STATE_DISCONNECTED, G_MIRROR_EVENT_WAIT); @@ -595,9 +598,11 @@ g_mirror_ctl_forget(struct gctl_req *req continue; } sc->sc_ndisks = g_mirror_ndisks(sc, -1); + g_topology_unlock(); LIST_FOREACH(disk, &sc->sc_disks, d_next) { - g_mirror_update_metadata(disk); + g_mirror_update_metadata(disk, 0); } + g_topology_lock(); } }