Date: Sat, 19 Mar 2011 17:14:06 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r219777 - projects/graid/head/sys/geom/raid Message-ID: <201103191714.p2JHE6oa029423@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Sat Mar 19 17:14:06 2011 New Revision: 219777 URL: http://svn.freebsd.org/changeset/base/219777 Log: Implement simple `graid label` for now, supporting only one volume per disk. Correctly implement metadata erasing. 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 Sat Mar 19 16:52:06 2011 (r219776) +++ projects/graid/head/sys/geom/raid/md_promise.c Sat Mar 19 17:14:06 2011 (r219777) @@ -395,16 +395,18 @@ promise_meta_erase(struct g_consumer *cp { struct g_provider *pp; char *buf; - int error; + int error, subdisk; pp = cp->provider; - buf = malloc(pp->sectorsize, M_MD_PROMISE, M_WAITOK | M_ZERO); - error = g_write_data(cp, - pp->mediasize - 2 * pp->sectorsize, - buf, pp->sectorsize); - if (error != 0) { - G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).", - pp->name, error); + buf = malloc(4 * pp->sectorsize, M_MD_PROMISE, M_WAITOK | M_ZERO); + for (subdisk = 0; subdisk < PROMISE_MAX_SUBDISKS; subdisk++) { + error = g_write_data(cp, pp->mediasize - pp->sectorsize * + (63 - subdisk * PROMISE_META_OFFSET), + buf, 4 * pp->sectorsize); + if (error != 0) { + G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).", + pp->name, error); + } } free(buf, M_MD_PROMISE); return (error); @@ -934,13 +936,27 @@ static int g_raid_md_create_promise(struct g_raid_md_object *md, struct g_class *mp, struct g_geom **gp) { + struct g_geom *geom; struct g_raid_softc *sc; - struct g_raid_md_promise_object *mdi; - char name[16]; - mdi = (struct g_raid_md_promise_object *)md; - snprintf(name, sizeof(name), "Promise"); - sc = g_raid_create_node(mp, name, md); + /* Search for existing node. */ + LIST_FOREACH(geom, &mp->geom, geom) { + sc = geom->softc; + if (sc == NULL) + continue; + if (sc->sc_stopping != 0) + continue; + if (sc->sc_md->mdo_class != md->mdo_class) + continue; + break; + } + if (geom != NULL) { + *gp = geom; + return (G_RAID_MD_TASTE_EXISTING); + } + + /* Create new one if not found. */ + sc = g_raid_create_node(mp, "Promise", md); if (sc == NULL) return (G_RAID_MD_TASTE_FAIL); md->mdo_softc = sc; @@ -1137,9 +1153,10 @@ g_raid_md_ctl_promise(struct g_raid_md_o struct g_raid_softc *sc; struct g_raid_volume *vol, *vol1; struct g_raid_subdisk *sd; - struct g_raid_disk *disk; + struct g_raid_disk *disk, *disks[PROMISE_MAX_DISKS]; struct g_raid_md_promise_object *mdi; struct g_raid_md_promise_perdisk *pd; + struct g_raid_md_promise_pervolume *pv; struct g_consumer *cp; struct g_provider *pp; char arg[16]; @@ -1189,6 +1206,7 @@ g_raid_md_ctl_promise(struct g_raid_md_o /* Search for disks, connect them and probe. */ size = 0x7fffffffffffffffllu; sectorsize = 0; + bzero(disks, sizeof(disks)); for (i = 0; i < numdisks; i++) { snprintf(arg, sizeof(arg), "arg%d", i + 3); diskname = gctl_get_asciiparam(req, arg); @@ -1197,31 +1215,23 @@ g_raid_md_ctl_promise(struct g_raid_md_o error = -6; break; } - if (strcmp(diskname, "NONE") == 0) { - cp = NULL; - pp = NULL; - } else { - g_topology_lock(); - cp = g_raid_open_consumer(sc, diskname); - if (cp == NULL) { - gctl_error(req, "Can't open disk '%s'.", - diskname); - g_topology_unlock(); - error = -4; - break; - } - pp = cp->provider; + if (strcmp(diskname, "NONE") == 0) + continue; + g_topology_lock(); + cp = g_raid_open_consumer(sc, diskname); + if (cp == NULL) { + gctl_error(req, "Can't open disk '%s'.", + diskname); + g_topology_unlock(); + error = -4; + break; } + pp = cp->provider; pd = malloc(sizeof(*pd), M_MD_PROMISE, M_WAITOK | M_ZERO); -// pd->pd_disk_pos = i; disk = g_raid_create_disk(sc); disk->d_md_data = (void *)pd; disk->d_consumer = cp; - if (cp == NULL) { -// pd->pd_disk_meta.id = 0xffffffff; -// pd->pd_disk_meta.flags = PROMISE_F_ASSIGNED; - continue; - } + disks[i] = disk; cp->private = disk; g_topology_unlock(); @@ -1235,19 +1245,17 @@ g_raid_md_ctl_promise(struct g_raid_md_o "Dumping not supported by %s.", cp->provider->name); -// pd->pd_disk_meta.sectors = pp->mediasize / pp->sectorsize; if (size > pp->mediasize) size = pp->mediasize; if (sectorsize < pp->sectorsize) sectorsize = pp->sectorsize; -// pd->pd_disk_meta.id = 0; -// pd->pd_disk_meta.flags = PROMISE_F_ASSIGNED | PROMISE_F_ONLINE; } if (error != 0) return (error); /* Reserve some space for metadata. */ - size -= ((4096 + sectorsize - 1) / sectorsize) * sectorsize; + size -= size % (63 * sectorsize); + size -= 63 * sectorsize; /* Handle size argument. */ len = sizeof(*sizearg); @@ -1276,10 +1284,6 @@ g_raid_md_ctl_promise(struct g_raid_md_o gctl_error(req, "Incorrect strip size."); return (-11); } - if (strip > 65535 * sectorsize) { - gctl_error(req, "Strip size too big."); - return (-12); - } strip = *striparg; } @@ -1301,18 +1305,24 @@ g_raid_md_ctl_promise(struct g_raid_md_o } /* We have all we need, create things: volume, ... */ - mdi->mdio_started = 1; + pv = malloc(sizeof(*pv), M_MD_PROMISE, M_WAITOK | M_ZERO); + arc4rand(&pv->pv_id, sizeof(pv->pv_id), 0); + pv->pv_generation = 0; + pv->pv_started = 1; vol = g_raid_create_volume(sc, volname); - vol->v_md_data = (void *)(intptr_t)0; + vol->v_md_data = pv; vol->v_raid_level = level; vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE; vol->v_strip_size = strip; vol->v_disks_count = numdisks; - if (level == G_RAID_VOLUME_RL_RAID0) + if (level == G_RAID_VOLUME_RL_RAID0 || + level == G_RAID_VOLUME_RL_CONCAT || + level == G_RAID_VOLUME_RL_SINGLE) vol->v_mediasize = size * numdisks; else if (level == G_RAID_VOLUME_RL_RAID1) vol->v_mediasize = size; - else if (level == G_RAID_VOLUME_RL_RAID5) + else if (level == G_RAID_VOLUME_RL_RAID3 || + level == G_RAID_VOLUME_RL_RAID5) vol->v_mediasize = size * (numdisks - 1); else { /* RAID1E */ vol->v_mediasize = ((size * numdisks) / strip / 2) * @@ -1322,10 +1332,10 @@ g_raid_md_ctl_promise(struct g_raid_md_o g_raid_start_volume(vol); /* , and subdisks. */ -#if 0 - TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { + for (i = 0; i < numdisks; i++) { + disk = disks[i]; pd = (struct g_raid_md_promise_perdisk *)disk->d_md_data; - sd = &vol->v_subdisks[pd->pd_disk_pos]; + sd = &vol->v_subdisks[i]; sd->sd_disk = disk; sd->sd_offset = 0; sd->sd_size = size; @@ -1341,7 +1351,6 @@ g_raid_md_ctl_promise(struct g_raid_md_o g_raid_change_disk_state(disk, G_RAID_DISK_S_OFFLINE); } } -#endif /* Write metadata based on created entities. */ G_RAID_DEBUG1(0, sc, "Array started."); @@ -1776,11 +1785,13 @@ g_raid_md_write_promise(struct g_raid_md pd = (struct g_raid_md_promise_perdisk *)disk->d_md_data; pd->pd_updated = 0; - for (i = 0; i < pd->pd_subdisks; i++) { + 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) + 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]; @@ -1840,10 +1851,7 @@ g_raid_md_write_promise(struct g_raid_md meta->cylinders = meta->total_sectors / (255 * 63) - 1; meta->heads = 254; meta->sectors = 63; - if (pv->pv_meta != NULL) - meta->volume_id = pv->pv_meta->volume_id; - else - arc4rand(&meta->volume_id, sizeof(meta->volume_id), 0); + meta->volume_id = pv->pv_id; rebuild_lba64 = UINT64_MAX; rebuild = 0; for (i = 0; i < vol->v_disks_count; i++) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103191714.p2JHE6oa029423>