PERFORCE change 124188 for review
Ulf Lilleengen
lulf at FreeBSD.org
Fri Jul 27 15:05:34 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=124188
Change 124188 by lulf at lulf_carrot on 2007/07/27 15:05:25
- Prevent from getting a bogus sd name that crashes vinum when not
specified in config. Generate a new name if not given.
- Remove checking of sdnum (sdname.plexnum.sdnum) to be the same in
rename... it shouldn't have to be the same.
- Modify gv_plex_smallest sd to not take initial arg but look for it in
the plex itself.
- Modify the remainder check code in gv_sd_to_plex to make sure all
subdisks are the same size in striped plexes (stripe and raid5).
Reduce size of other subdisks (only when newborn plex) or the subdisk
that is added. Prevents possibility of getting unequal subdisk-sizes
as well as giving space that is not needed back to the drive.
- Remove old debug printfs.
Affected files ...
.. //depot/projects/soc2007/lulf/gvinum_fixup/sbin/gvinum/gvinum.c#13 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_rename.c#3 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_subr.c#21 edit
Differences ...
==== //depot/projects/soc2007/lulf/gvinum_fixup/sbin/gvinum/gvinum.c#13 (text+ko) ====
@@ -170,9 +170,9 @@
struct gv_volume *v;
FILE *tmp;
int drives, errors, fd, line, plexes, plex_in_volume;
- int sd_in_plex, status, subdisks, tokens, volumes;
+ int sd_in_plex, status, subdisks, tokens, undeffd, volumes;
const char *errstr;
- char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *ed;
+ char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *ed, *sdname;
char original[BUFSIZ], tmpfile[20], *token[GV_MAXARGS];
char plex[GV_MAXPLEXNAME], volume[GV_MAXVOLNAME];
@@ -218,7 +218,8 @@
gctl_ro_param(req, "verb", -1, "create");
drives = volumes = plexes = subdisks = 0;
- plex_in_volume = sd_in_plex = 0;
+ plex_in_volume = sd_in_plex = undeffd = 0;
+ plex[0] = '\0';
errors = 0;
line = 1;
while ((fgets(buf, BUFSIZ, tmp)) != NULL) {
@@ -319,8 +320,16 @@
/* Default name. */
if (strlen(s->name) == 0) {
- snprintf(s->name, GV_MAXSDNAME, "%s.s%d",
- plex, sd_in_plex++);
+ if (strlen(plex) == 0) {
+ sdname = find_name("gvinumsubdisk.p",
+ GV_TYPE_SD, GV_MAXSDNAME);
+ snprintf(s->name, GV_MAXSDNAME,
+ "%s.s%d", sdname, undeffd++);
+ free(sdname);
+ } else {
+ snprintf(s->name, GV_MAXSDNAME,
+ "%s.s%d",plex, sd_in_plex++);
+ }
}
/* Default plex. */
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_rename.c#3 (text+ko) ====
@@ -273,12 +273,13 @@
err = GV_ERR_INVNAME;
goto fail;
}
- if (strcmp(newp, oldp)) {
+ /* XXX: Uhm, why is this important?. */
+/* if (strcmp(newp, oldp)) {
printf("VINUM: current and proposed sd numbers (%s, %s) do "
"not match\n", oldp, newp);
err = GV_ERR_INVNAME;
goto fail;
- }
+ }*/
strncpy(s->name, newname, GV_MAXSDNAME);
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_subr.c#21 (text+ko) ====
@@ -56,7 +56,7 @@
#include <geom/vinum/geom_vinum_share.h>
int gv_drive_is_newer(struct gv_softc *);
-static off_t gv_plex_smallest_sd(struct gv_plex *, off_t);
+static off_t gv_plex_smallest_sd(struct gv_plex *);
void
gv_parse_config(struct gv_softc *sc, char *buf)
@@ -232,12 +232,17 @@
}
static off_t
-gv_plex_smallest_sd(struct gv_plex *p, off_t smallest)
+gv_plex_smallest_sd(struct gv_plex *p)
{
struct gv_sd *s;
+ off_t smallest;
KASSERT(p != NULL, ("gv_plex_smallest_sd: NULL p"));
+ s = LIST_FIRST(&p->subdisks);
+ if (s == NULL)
+ return (-1);
+ smallest = s->size;
LIST_FOREACH(s, &p->subdisks, in_plex) {
if (s->size < smallest)
smallest = s->size;
@@ -267,7 +272,7 @@
gv_sd_to_plex(struct gv_sd *s, struct gv_plex *p)
{
struct gv_sd *s2;
- off_t psizeorig, remainder;
+ off_t psizeorig, remainder, smallest;
/* If this subdisk was already given to this plex, do nothing. */
if (s->plex_sc == p)
@@ -277,7 +282,9 @@
s2 = LIST_FIRST(&p->subdisks);
/* Adjust the subdisk-size if necessary. */
if (s2 != NULL && gv_is_striped(p)) {
+ /* First adjust to the stripesize. */
remainder = s->size % p->stripesize;
+
if (remainder) {
printf("VINUM: size of sd %s is not a "
"multiple of plex stripesize, taking off "
@@ -285,6 +292,35 @@
(intmax_t)remainder);
gv_adjust_freespace(s, remainder);
}
+
+ smallest = gv_plex_smallest_sd(p);
+ /* Then take off extra if other subdisks are smaller. */
+ remainder = s->size - smallest;
+
+ /*
+ * Don't allow a remainder below zero for running plexes, it's too
+ * painful, and if someone were to accidentally do this, the
+ * resulting array might be smaller than the original... not god
+ */
+ if (remainder < 0) {
+ if (!(p->flags & GV_PLEX_NEWBORN)) {
+ printf("VINUM: sd %s too small for plex %s!\n",
+ s->name, p->name);
+ return (GV_ERR_BADSIZE);
+ }
+ /* Adjust other subdisks. */
+ LIST_FOREACH(s2, &p->subdisks, in_plex) {
+ printf("VINUM: size of sd %s is to big, "
+ "taking off %jd bytes\n", s->name,
+ (intmax_t)remainder);
+ gv_adjust_freespace(s2, (remainder * -1));
+ }
+ } else if (remainder > 0) {
+ printf("VINUM: size of sd %s is to big, "
+ "taking off %jd bytes\n", s->name,
+ (intmax_t)remainder);
+ gv_adjust_freespace(s, remainder);
+ }
}
/* Find the correct plex offset for this subdisk, if needed. */
@@ -338,8 +374,6 @@
if ((p->org == GV_PLEX_RAID5 ||
p->org == GV_PLEX_STRIPED) &&
!(p->flags & GV_PLEX_NEWBORN)) {
- printf("Adding to a running plex, must add grow-flag to"
- " sd and plex\n");
s->flags |= GV_SD_GROW;
}
p->sdcount++;
@@ -485,7 +519,6 @@
} else {
LIST_FOREACH(s, &p->subdisks, in_plex) {
if (s->flags & GV_SD_GROW) {
- printf("Setting state\n");
gv_set_plex_state(p, GV_PLEX_DEGRADED,
GV_SETSTATE_FORCE);
break;
More information about the p4-projects
mailing list