svn commit: r219800 - projects/graid/head/sys/geom/raid
Alexander Motin
mav at FreeBSD.org
Sun Mar 20 14:12:50 UTC 2011
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);
More information about the svn-src-projects
mailing list