diff options
author | le <le@FreeBSD.org> | 2006-03-30 14:01:25 +0000 |
---|---|---|
committer | le <le@FreeBSD.org> | 2006-03-30 14:01:25 +0000 |
commit | 148e4e97f6a72d5d47fc4da833170bd0aeb91c52 (patch) | |
tree | d19a280a99ea2e4b5d78e9da8ea03f61a14ab2f8 /sys/geom/vinum/geom_vinum.c | |
parent | aa075cf284edd2192e4a6c6f086e2ac9edb16656 (diff) | |
download | FreeBSD-src-148e4e97f6a72d5d47fc4da833170bd0aeb91c52.zip FreeBSD-src-148e4e97f6a72d5d47fc4da833170bd0aeb91c52.tar.gz |
Protect from creating striped and RAID5 plexes with unequally sized
subdisks.
Diffstat (limited to 'sys/geom/vinum/geom_vinum.c')
-rw-r--r-- | sys/geom/vinum/geom_vinum.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/sys/geom/vinum/geom_vinum.c b/sys/geom/vinum/geom_vinum.c index 7e045d9..7ebe58f 100644 --- a/sys/geom/vinum/geom_vinum.c +++ b/sys/geom/vinum/geom_vinum.c @@ -237,13 +237,16 @@ gv_create(struct g_geom *gp, struct gctl_req *req) /* Find the volume this plex should be attached to. */ v = gv_find_vol(sc, p->volume); - if (v != NULL) { - if (v->plexcount) - p->flags |= GV_PLEX_ADDED; - p->vol_sc = v; - v->plexcount++; - LIST_INSERT_HEAD(&v->plexes, p, in_volume); + if (v == NULL) { + gctl_error(req, "volume '%s' not found", p->volume); + g_free(p); + continue; } + if (v->plexcount) + p->flags |= GV_PLEX_ADDED; + p->vol_sc = v; + v->plexcount++; + LIST_INSERT_HEAD(&v->plexes, p, in_volume); p->vinumconf = sc; p->flags |= GV_PLEX_NEWBORN; @@ -272,7 +275,7 @@ gv_create(struct g_geom *gp, struct gctl_req *req) /* drive not found - XXX */ if (d == NULL) { - printf("FOO: drive '%s' not found\n", s->drive); + gctl_error(req, "drive '%s' not found", s->drive); g_free(s); continue; } @@ -282,7 +285,7 @@ gv_create(struct g_geom *gp, struct gctl_req *req) /* plex not found - XXX */ if (p == NULL) { - printf("FOO: plex '%s' not found\n", s->plex); + gctl_error(req, "plex '%s' not found\n", s->plex); g_free(s); continue; } @@ -304,8 +307,34 @@ gv_create(struct g_geom *gp, struct gctl_req *req) */ error = gv_sd_to_plex(p, s, 1); if (error) { - printf("FOO: couldn't give sd '%s' to plex '%s'\n", - s->name, p->name); + gctl_error(req, "GEOM_VINUM: couldn't give sd '%s' " + "to plex '%s'\n", s->name, p->name); + if (s->drive_sc) + LIST_REMOVE(s, from_drive); + gv_free_sd(s); + g_free(s); + /* + * If this subdisk can't be created, we won't create + * the attached plex either, if it is also a new one. + */ + if (!(p->flags & GV_PLEX_NEWBORN)) + continue; + LIST_FOREACH_SAFE(s, &p->subdisks, in_plex, s2) { + if (s->drive_sc) + LIST_REMOVE(s, from_drive); + p->sdcount--; + LIST_REMOVE(s, in_plex); + LIST_REMOVE(s, sd); + gv_free_sd(s); + g_free(s); + } + if (p->vol_sc != NULL) { + LIST_REMOVE(p, in_volume); + p->vol_sc->plexcount--; + } + LIST_REMOVE(p, plex); + g_free(p); + continue; } s->flags |= GV_SD_NEWBORN; |