Index: g_raid3.c =================================================================== RCS file: /usr/repo/src/sys/geom/raid3/g_raid3.c,v retrieving revision 1.42 diff -u -p -r1.42 g_raid3.c --- g_raid3.c 28 Oct 2005 20:25:02 -0000 1.42 +++ g_raid3.c 4 Nov 2005 20:37:25 -0000 @@ -571,7 +571,7 @@ g_raid3_destroy_device(struct g_raid3_so disk = &sc->sc_disks[n]; if (disk->d_state != G_RAID3_DISK_STATE_NODISK) { disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 1); g_raid3_destroy_disk(disk); } } @@ -628,7 +628,7 @@ g_raid3_write_metadata(struct g_raid3_di u_char *sector; int error = 0; - g_topology_assert(); + g_topology_assert_not(); sc = disk->d_softc; cp = disk->d_consumer; @@ -642,9 +642,7 @@ g_raid3_write_metadata(struct g_raid3_di sector = malloc((size_t)length, M_RAID3, M_WAITOK | M_ZERO); if (md != NULL) raid3_metadata_encode(md, sector); - g_topology_unlock(); error = g_write_data(cp, offset, sector, length); - g_topology_lock(); free(sector, M_RAID3); if (error != 0) { disk->d_softc->sc_bump_id = G_RAID3_BUMP_GENID; @@ -655,11 +653,14 @@ g_raid3_write_metadata(struct g_raid3_di } int -g_raid3_clear_metadata(struct g_raid3_disk *disk) +g_raid3_clear_metadata(struct g_raid3_disk *disk, int locked) { int error; - g_topology_assert(); + if (locked) + g_topology_unlock(); + else + g_topology_assert_not(); error = g_raid3_write_metadata(disk, NULL); if (error == 0) { G_RAID3_DEBUG(2, "Metadata on %s cleared.", @@ -669,6 +670,8 @@ g_raid3_clear_metadata(struct g_raid3_di "Cannot clear metadata on disk %s (error=%d).", g_raid3_get_diskname(disk), error); } + if (locked) + g_topology_lock(); return (error); } @@ -710,12 +713,15 @@ g_raid3_fill_metadata(struct g_raid3_dis } void -g_raid3_update_metadata(struct g_raid3_disk *disk) +g_raid3_update_metadata(struct g_raid3_disk *disk, int locked) { struct g_raid3_metadata md; int error; - g_topology_assert(); + if (locked) + g_topology_unlock(); + else + g_topology_assert_not(); g_raid3_fill_metadata(disk, &md); error = g_raid3_write_metadata(disk, &md); if (error == 0) { @@ -726,6 +732,8 @@ g_raid3_update_metadata(struct g_raid3_d "Cannot update metadata on disk %s (error=%d).", g_raid3_get_diskname(disk), error); } + if (locked) + g_topology_lock(); } static void @@ -742,14 +750,16 @@ g_raid3_bump_syncid(struct g_raid3_softc sc->sc_syncid++; G_RAID3_DEBUG(1, "Device %s: syncid bumped to %u.", sc->sc_name, sc->sc_syncid); + g_topology_unlock(); for (n = 0; n < sc->sc_ndisks; n++) { disk = &sc->sc_disks[n]; if (disk->d_state == G_RAID3_DISK_STATE_ACTIVE || disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) { disk->d_sync.ds_syncid = sc->sc_syncid; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); } } + g_topology_lock(); } static void @@ -766,14 +776,16 @@ g_raid3_bump_genid(struct g_raid3_softc sc->sc_genid++; G_RAID3_DEBUG(1, "Device %s: genid bumped to %u.", sc->sc_name, sc->sc_genid); + g_topology_unlock(); for (n = 0; n < sc->sc_ndisks; n++) { disk = &sc->sc_disks[n]; if (disk->d_state == G_RAID3_DISK_STATE_ACTIVE || disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) { disk->d_genid = sc->sc_genid; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); } } + g_topology_lock(); } static void @@ -785,7 +797,6 @@ g_raid3_idle(struct g_raid3_softc *sc) if (sc->sc_provider == NULL || sc->sc_provider->acw == 0) return; sc->sc_idle = 1; - g_topology_lock(); for (i = 0; i < sc->sc_ndisks; i++) { disk = &sc->sc_disks[i]; if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) @@ -793,9 +804,8 @@ g_raid3_idle(struct g_raid3_softc *sc) G_RAID3_DEBUG(1, "Disk %s (device %s) marked as clean.", g_raid3_get_diskname(disk), sc->sc_name); disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); } - g_topology_unlock(); } static void @@ -805,7 +815,6 @@ g_raid3_unidle(struct g_raid3_softc *sc) u_int i; sc->sc_idle = 0; - g_topology_lock(); for (i = 0; i < sc->sc_ndisks; i++) { disk = &sc->sc_disks[i]; if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) @@ -813,9 +822,8 @@ g_raid3_unidle(struct g_raid3_softc *sc) G_RAID3_DEBUG(1, "Disk %s (device %s) marked as dirty.", g_raid3_get_diskname(disk), sc->sc_name); disk->d_flags |= G_RAID3_DISK_FLAG_DIRTY; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); } - g_topology_unlock(); } /* @@ -1475,9 +1483,7 @@ g_raid3_sync_request(struct bio *bp) * Update offset_done on every 100 blocks. * XXX: This should be configurable. */ - g_topology_lock(); - g_raid3_update_metadata(disk); - g_topology_unlock(); + g_raid3_update_metadata(disk, 0); } return; } @@ -2437,7 +2443,7 @@ again: disk->d_sync.ds_offset = 0; disk->d_sync.ds_offset_done = 0; g_raid3_update_access(disk); - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 1); G_RAID3_DEBUG(0, "Device %s: provider %s activated.", sc->sc_name, g_raid3_get_diskname(disk)); break; @@ -2469,7 +2475,7 @@ again: disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; disk->d_state = state; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 1); G_RAID3_DEBUG(0, "Device %s: provider %s is stale.", sc->sc_name, g_raid3_get_diskname(disk)); break; @@ -2495,7 +2501,7 @@ again: disk->d_state = state; if (sc->sc_provider != NULL) { g_raid3_sync_start(sc); - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 1); } break; case G_RAID3_DISK_STATE_DISCONNECTED: @@ -2709,7 +2715,7 @@ g_raid3_add_disk(struct g_raid3_softc *s if (md->md_version < G_RAID3_VERSION) { G_RAID3_DEBUG(0, "Upgrading metadata on %s (v%d->v%d).", pp->name, md->md_version, G_RAID3_VERSION); - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 1); } return (0); } @@ -2739,6 +2745,7 @@ g_raid3_access(struct g_provider *pp, in else return (ENXIO); } + g_topology_unlock(); for (n = 0; n < sc->sc_ndisks; n++) { disk = &sc->sc_disks[n]; if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE) @@ -2750,14 +2757,15 @@ g_raid3_access(struct g_provider *pp, in G_RAID3_DEBUG(1, "Disk %s (device %s) marked as dirty.", g_raid3_get_diskname(disk), sc->sc_name); disk->d_flags |= G_RAID3_DISK_FLAG_DIRTY; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); } else if (pp->acw > 0 && dcw == 0) { G_RAID3_DEBUG(1, "Disk %s (device %s) marked as clean.", g_raid3_get_diskname(disk), sc->sc_name); disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); } } + g_topology_lock(); return (0); } Index: g_raid3.h =================================================================== RCS file: /usr/repo/src/sys/geom/raid3/g_raid3.h,v retrieving revision 1.12 diff -u -p -r1.12 g_raid3.h --- g_raid3.h 27 Jul 2005 09:03:51 -0000 1.12 +++ g_raid3.h 4 Nov 2005 20:35:47 -0000 @@ -217,8 +217,8 @@ int g_raid3_add_disk(struct g_raid3_soft int g_raid3_read_metadata(struct g_consumer *cp, struct g_raid3_metadata *md); void g_raid3_fill_metadata(struct g_raid3_disk *disk, struct g_raid3_metadata *md); -int g_raid3_clear_metadata(struct g_raid3_disk *disk); -void g_raid3_update_metadata(struct g_raid3_disk *disk); +int g_raid3_clear_metadata(struct g_raid3_disk *disk, int locked); +void g_raid3_update_metadata(struct g_raid3_disk *disk, int locked); g_ctl_req_t g_raid3_config; #endif /* _KERNEL */ Index: g_raid3_ctl.c =================================================================== RCS file: /usr/repo/src/sys/geom/raid3/g_raid3_ctl.c,v retrieving revision 1.11 diff -u -p -r1.11 g_raid3_ctl.c --- g_raid3_ctl.c 11 May 2005 19:36:56 -0000 1.11 +++ g_raid3_ctl.c 4 Nov 2005 20:38:23 -0000 @@ -204,13 +204,14 @@ g_raid3_ctl_configure(struct gctl_req *r */ sc->sc_flags &= ~G_RAID3_DEVICE_FLAG_ROUND_ROBIN; } + g_topology_unlock(); for (n = 0; n < sc->sc_ndisks; n++) { disk = &sc->sc_disks[n]; if (do_sync) { if (disk->d_state == G_RAID3_DISK_STATE_SYNCHRONIZING) disk->d_flags &= ~G_RAID3_DISK_FLAG_FORCE_SYNC; } - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 0); if (do_sync) { if (disk->d_state == G_RAID3_DISK_STATE_STALE) { /* @@ -223,6 +224,7 @@ g_raid3_ctl_configure(struct gctl_req *r } } } + g_topology_lock(); } static void @@ -277,7 +279,7 @@ g_raid3_ctl_rebuild(struct gctl_req *req disk->d_sync.ds_syncid = 0; if ((sc->sc_flags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0) disk->d_flags |= G_RAID3_DISK_FLAG_FORCE_SYNC; - g_raid3_update_metadata(disk); + g_raid3_update_metadata(disk, 1); pp = disk->d_consumer->provider; error = g_raid3_read_metadata(disk->d_consumer, &md); g_raid3_event_send(disk, G_RAID3_DISK_STATE_DISCONNECTED, @@ -521,7 +523,7 @@ g_raid3_ctl_remove(struct gctl_req *req, /* FALLTHROUGH */ case G_RAID3_DISK_STATE_STALE: case G_RAID3_DISK_STATE_SYNCHRONIZING: - if (g_raid3_clear_metadata(disk) != 0) { + if (g_raid3_clear_metadata(disk, 1) != 0) { gctl_error(req, "Cannot clear metadata on %s.", g_raid3_get_diskname(disk)); } else {