Date: Sun, 20 Mar 2011 14:12:50 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r219800 - projects/graid/head/sys/geom/raid Message-ID: <201103201412.p2KECohu081015@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Sun Mar 20 14:12:50 2011 New Revision: 219800 URL: http://svn.freebsd.org/changeset/base/219800 Log: Destroy volume on last disk leave and destroy disk on last volume leave. This makes `graid delete` and `graid remove` really work for Promise. Modified: projects/graid/head/sys/geom/raid/md_promise.c Modified: projects/graid/head/sys/geom/raid/md_promise.c ============================================================================== --- projects/graid/head/sys/geom/raid/md_promise.c Sun Mar 20 13:01:57 2011 (r219799) +++ projects/graid/head/sys/geom/raid/md_promise.c Sun Mar 20 14:12:50 2011 (r219800) @@ -448,6 +448,70 @@ g_raid_md_promise_get_volume(struct g_ra } static int +g_raid_md_promise_purge_volumes(struct g_raid_softc *sc) +{ + struct g_raid_volume *vol, *tvol; + struct g_raid_md_promise_pervolume *pv; + int i, res; + + res = 0; + TAILQ_FOREACH_SAFE(vol, &sc->sc_volumes, v_next, tvol) { + pv = vol->v_md_data; + if (!pv->pv_started || vol->v_stopping) + continue; + for (i = 0; i < vol->v_disks_count; i++) { + if (vol->v_subdisks[i].sd_state != G_RAID_SUBDISK_S_NONE) + break; + } + if (i >= vol->v_disks_count) { + g_raid_destroy_volume(vol); + res = 1; + } + } + return (res); +} + +static int +g_raid_md_promise_purge_disks(struct g_raid_softc *sc) +{ + struct g_raid_disk *disk, *tdisk; + struct g_raid_volume *vol; + struct g_raid_md_promise_perdisk *pd; + int i, j, res; + + res = 0; + TAILQ_FOREACH_SAFE(disk, &sc->sc_disks, d_next, tdisk) { + if (disk->d_state == G_RAID_DISK_S_SPARE) + continue; + pd = (struct g_raid_md_promise_perdisk *)disk->d_md_data; + + /* Scan for deleted volumes. */ + for (i = 0; i < pd->pd_subdisks; ) { + vol = g_raid_md_promise_get_volume(sc, + pd->pd_meta[i]->volume_id); + if (vol != NULL && !vol->v_stopping) { + i++; + continue; + } + free(pd->pd_meta[i], M_MD_PROMISE); + for (j = i; j < pd->pd_subdisks - 1; j++) + pd->pd_meta[j] = pd->pd_meta[j + 1]; + pd->pd_meta[PROMISE_MAX_SUBDISKS - 1] = NULL; + pd->pd_subdisks--; + pd->pd_updated = 1; + } + + /* If there is no metadata left - erase and delete disk. */ + if (pd->pd_subdisks == 0) { + promise_meta_erase(disk->d_consumer); + g_raid_destroy_disk(disk); + res = 1; + } + } + return (res); +} + +static int g_raid_md_promise_supported(int level, int qual, int disks, int force) { @@ -1113,6 +1177,7 @@ g_raid_md_event_promise(struct g_raid_md /* Delete disk. */ g_raid_change_disk_state(disk, G_RAID_DISK_S_NONE); g_raid_destroy_disk(disk); + g_raid_md_promise_purge_volumes(sc); /* Write updated metadata to all disks. */ g_raid_md_write_promise(md, NULL, NULL, NULL); @@ -1598,6 +1663,7 @@ g_raid_md_ctl_promise(struct g_raid_md_o i++; if (i >= 2) { g_raid_destroy_volume(vol); + g_raid_md_promise_purge_disks(sc); g_raid_md_write_promise(md, NULL, NULL, NULL); } else { TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { @@ -1650,6 +1716,7 @@ g_raid_md_ctl_promise(struct g_raid_md_o promise_meta_erase(disk->d_consumer); g_raid_destroy_disk(disk); } + g_raid_md_promise_purge_volumes(sc); /* Write updated metadata to remaining disks. */ g_raid_md_write_promise(md, NULL, NULL, NULL); @@ -1756,27 +1823,6 @@ g_raid_md_write_promise(struct g_raid_md if (sc->sc_stopping == G_RAID_DESTROY_HARD) return (0); - /* Clear "updated" flags and scan for deleted volumes. */ - TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { - pd = (struct g_raid_md_promise_perdisk *)disk->d_md_data; - pd->pd_updated = 0; - - for (i = 0; i < pd->pd_subdisks; ) { - vol = g_raid_md_promise_get_volume(sc, - pd->pd_meta[i]->volume_id); - if (vol != NULL && !vol->v_stopping) { - i++; - continue; - } - free(pd->pd_meta[i], M_MD_PROMISE); - for (j = i; j < pd->pd_subdisks - 1; j++) - pd->pd_meta[j] = pd->pd_meta[j + 1]; - pd->pd_meta[PROMISE_MAX_SUBDISKS - 1] = NULL; - pd->pd_subdisks--; - pd->pd_updated = 1; - } - } - /* Generate new per-volume metadata for affected volumes. */ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) { if (vol->v_stopping) @@ -1953,6 +1999,7 @@ g_raid_md_write_promise(struct g_raid_md g_raid_md_promise_print(pd->pd_meta[i]); promise_meta_write(disk->d_consumer, pd->pd_meta, pd->pd_subdisks); + pd->pd_updated = 0; } return (0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103201412.p2KECohu081015>