summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2007-05-08 20:18:17 +0000
committermarcel <marcel@FreeBSD.org>2007-05-08 20:18:17 +0000
commit3b37bd02b406660a3b4ae896f7eb37e0450a6ada (patch)
tree070fc043d16305f96576d840dde7f300001f7e6b /sys/geom
parent27bb2c65508c54b1ee20345c2793dc0e70488b31 (diff)
downloadFreeBSD-src-3b37bd02b406660a3b4ae896f7eb37e0450a6ada.zip
FreeBSD-src-3b37bd02b406660a3b4ae896f7eb37e0450a6ada.tar.gz
MFp4:
119373: o Remove the query verb, along with the request and response parameters. o Add the version and output parameters. 119390: [APM,GPT] Properly clear deleted entries. 119394: o Make the alias the standard and use the '!' to prefix literal partition types. o Treat schemes and partition types as case insensitive. 119462: [GPT] Fix a page fault caused when modifying a partition entry without a new partition type.
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/part/g_part.c95
-rw-r--r--sys/geom/part/g_part.h16
-rw-r--r--sys/geom/part/g_part_apm.c36
-rw-r--r--sys/geom/part/g_part_gpt.c49
4 files changed, 102 insertions, 94 deletions
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 2ccfe91..3a12a31 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -64,12 +64,12 @@ struct g_part_alias_list {
const char *lexeme;
enum g_part_alias alias;
} g_part_alias_list[G_PART_ALIAS_COUNT] = {
- { "@efi", G_PART_ALIAS_EFI },
- { "@freebsd", G_PART_ALIAS_FREEBSD },
- { "@freebsd-swap", G_PART_ALIAS_FREEBSD_SWAP },
- { "@freebsd-ufs", G_PART_ALIAS_FREEBSD_UFS },
- { "@freebsd-vinum", G_PART_ALIAS_FREEBSD_VINUM },
- { "@mbr", G_PART_ALIAS_MBR }
+ { "efi", G_PART_ALIAS_EFI },
+ { "freebsd", G_PART_ALIAS_FREEBSD },
+ { "freebsd-swap", G_PART_ALIAS_FREEBSD_SWAP },
+ { "freebsd-ufs", G_PART_ALIAS_FREEBSD_UFS },
+ { "freebsd-vinum", G_PART_ALIAS_FREEBSD_VINUM },
+ { "mbr", G_PART_ALIAS_MBR }
};
/*
@@ -111,7 +111,6 @@ enum g_part_ctl {
G_PART_CTL_DESTROY,
G_PART_CTL_MODIFY,
G_PART_CTL_MOVE,
- G_PART_CTL_QUERY,
G_PART_CTL_RECOVER,
G_PART_CTL_RESIZE,
G_PART_CTL_UNDO
@@ -247,7 +246,7 @@ g_part_parm_scheme(const char *p, struct g_part_scheme **v)
SET_FOREACH(iter, g_part_scheme_set) {
if ((*iter)->name == NULL)
continue;
- if (!strcmp((*iter)->name, p)) {
+ if (!strcasecmp((*iter)->name, p)) {
s = *iter;
break;
}
@@ -732,13 +731,6 @@ g_part_ctl_move(struct gctl_req *req, struct g_part_parms *gpp)
}
static int
-g_part_ctl_query(struct gctl_req *req, struct g_part_parms *gpp)
-{
- gctl_error(req, "%d verb 'query'", ENOSYS);
- return (ENOSYS);
-}
-
-static int
g_part_ctl_recover(struct gctl_req *req, struct g_part_parms *gpp)
{
gctl_error(req, "%d verb 'recover'", ENOSYS);
@@ -863,83 +855,67 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
ctlreq = G_PART_CTL_NONE;
modifies = 0;
- mparms = oparms = 0;
+ mparms = 0;
+ oparms = G_PART_PARM_FLAGS | G_PART_PARM_OUTPUT | G_PART_PARM_VERSION;
switch (*verb) {
case 'a':
if (!strcmp(verb, "add")) {
ctlreq = G_PART_CTL_ADD;
modifies = 1;
- mparms = G_PART_PARM_GEOM | G_PART_PARM_SIZE |
+ mparms |= G_PART_PARM_GEOM | G_PART_PARM_SIZE |
G_PART_PARM_START | G_PART_PARM_TYPE;
- oparms = G_PART_PARM_FLAGS | G_PART_PARM_INDEX |
- G_PART_PARM_LABEL;
+ oparms |= G_PART_PARM_INDEX | G_PART_PARM_LABEL;
}
break;
case 'c':
if (!strcmp(verb, "commit")) {
ctlreq = G_PART_CTL_COMMIT;
- mparms = G_PART_PARM_GEOM;
- oparms = G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_GEOM;
} else if (!strcmp(verb, "create")) {
ctlreq = G_PART_CTL_CREATE;
modifies = 1;
- mparms = G_PART_PARM_PROVIDER |
- G_PART_PARM_SCHEME;
- oparms = G_PART_PARM_ENTRIES | G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_PROVIDER | G_PART_PARM_SCHEME;
+ oparms |= G_PART_PARM_ENTRIES;
}
break;
case 'd':
if (!strcmp(verb, "delete")) {
ctlreq = G_PART_CTL_DELETE;
modifies = 1;
- mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
- oparms = G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
} else if (!strcmp(verb, "destroy")) {
ctlreq = G_PART_CTL_DESTROY;
modifies = 1;
- mparms = G_PART_PARM_GEOM;
- oparms = G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_GEOM;
}
break;
case 'm':
if (!strcmp(verb, "modify")) {
ctlreq = G_PART_CTL_MODIFY;
modifies = 1;
- mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
- oparms = G_PART_PARM_FLAGS | G_PART_PARM_LABEL |
- G_PART_PARM_TYPE;
+ mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
+ oparms |= G_PART_PARM_LABEL | G_PART_PARM_TYPE;
} else if (!strcmp(verb, "move")) {
ctlreq = G_PART_CTL_MOVE;
modifies = 1;
- mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
- oparms = G_PART_PARM_FLAGS;
- }
- break;
- case 'q':
- if (!strcmp(verb, "query")) {
- ctlreq = G_PART_CTL_QUERY;
- mparms = G_PART_PARM_REQUEST | G_PART_PARM_RESPONSE;
- oparms = G_PART_PARM_FLAGS | G_PART_PARM_GEOM;
+ mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
}
break;
case 'r':
if (!strcmp(verb, "recover")) {
ctlreq = G_PART_CTL_RECOVER;
modifies = 1;
- mparms = G_PART_PARM_GEOM;
- oparms = G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_GEOM;
} else if (!strcmp(verb, "resize")) {
ctlreq = G_PART_CTL_RESIZE;
modifies = 1;
- mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
- oparms = G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
}
break;
case 'u':
if (!strcmp(verb, "undo")) {
ctlreq = G_PART_CTL_UNDO;
- mparms = G_PART_PARM_GEOM;
- oparms = G_PART_PARM_FLAGS;
+ mparms |= G_PART_PARM_GEOM;
}
break;
}
@@ -977,16 +953,14 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
if (!strcmp(ap->name, "label"))
parm = G_PART_PARM_LABEL;
break;
+ case 'o':
+ if (!strcmp(ap->name, "output"))
+ parm = G_PART_PARM_OUTPUT;
+ break;
case 'p':
if (!strcmp(ap->name, "provider"))
parm = G_PART_PARM_PROVIDER;
break;
- case 'r':
- if (!strcmp(ap->name, "request"))
- parm = G_PART_PARM_REQUEST;
- else if (!strcmp(ap->name, "response"))
- parm = G_PART_PARM_RESPONSE;
- break;
case 's':
if (!strcmp(ap->name, "scheme"))
parm = G_PART_PARM_SCHEME;
@@ -1002,6 +976,8 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
case 'v':
if (!strcmp(ap->name, "verb"))
continue;
+ else if (!strcmp(ap->name, "version"))
+ parm = G_PART_PARM_VERSION;
break;
}
if ((parm & (mparms | oparms)) == 0) {
@@ -1029,15 +1005,12 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
case G_PART_PARM_LABEL:
error = g_part_parm_str(p, &gpp.gpp_label);
break;
+ case G_PART_PARM_OUTPUT:
+ error = 0; /* Write-only parameter */
+ break;
case G_PART_PARM_PROVIDER:
error = g_part_parm_provider(p, &gpp.gpp_provider);
break;
- case G_PART_PARM_REQUEST:
- error = g_part_parm_str(p, &gpp.gpp_request);
- break;
- case G_PART_PARM_RESPONSE:
- error = 0; /* Write-only parameter. */
- break;
case G_PART_PARM_SCHEME:
error = g_part_parm_scheme(p, &gpp.gpp_scheme);
break;
@@ -1050,6 +1023,9 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
case G_PART_PARM_TYPE:
error = g_part_parm_str(p, &gpp.gpp_type);
break;
+ case G_PART_PARM_VERSION:
+ error = g_part_parm_uint(p, &gpp.gpp_version);
+ break;
default:
error = EDOOFUS;
break;
@@ -1106,9 +1082,6 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
case G_PART_CTL_MOVE:
error = g_part_ctl_move(req, &gpp);
break;
- case G_PART_CTL_QUERY:
- error = g_part_ctl_query(req, &gpp);
- break;
case G_PART_CTL_RECOVER:
error = g_part_ctl_recover(req, &gpp);
break;
diff --git a/sys/geom/part/g_part.h b/sys/geom/part/g_part.h
index bd697b7..8c6bbd5 100644
--- a/sys/geom/part/g_part.h
+++ b/sys/geom/part/g_part.h
@@ -104,13 +104,13 @@ struct g_part_entry *g_part_new_entry(struct g_part_table *, int, quad_t,
#define G_PART_PARM_GEOM 0x0004
#define G_PART_PARM_INDEX 0x0008
#define G_PART_PARM_LABEL 0x0010
-#define G_PART_PARM_PROVIDER 0x0020
-#define G_PART_PARM_REQUEST 0x0040
-#define G_PART_PARM_RESPONSE 0x0080
-#define G_PART_PARM_SCHEME 0x0100
-#define G_PART_PARM_SIZE 0x0200
-#define G_PART_PARM_START 0x0400
-#define G_PART_PARM_TYPE 0x0800
+#define G_PART_PARM_OUTPUT 0x0020
+#define G_PART_PARM_PROVIDER 0x0040
+#define G_PART_PARM_SCHEME 0x0080
+#define G_PART_PARM_SIZE 0x0100
+#define G_PART_PARM_START 0x0200
+#define G_PART_PARM_TYPE 0x0400
+#define G_PART_PARM_VERSION 0x0800
struct g_part_parms {
unsigned int gpp_parms;
@@ -120,11 +120,11 @@ struct g_part_parms {
unsigned int gpp_index;
const char *gpp_label;
struct g_provider *gpp_provider;
- const char *gpp_request;
struct g_part_scheme *gpp_scheme;
quad_t gpp_size;
quad_t gpp_start;
const char *gpp_type;
+ unsigned int gpp_version;
};
#endif /* !_GEOM_PART_H_ */
diff --git a/sys/geom/part/g_part_apm.c b/sys/geom/part/g_part_apm.c
index f90fc65..50d5c1e 100644
--- a/sys/geom/part/g_part_apm.c
+++ b/sys/geom/part/g_part_apm.c
@@ -99,8 +99,10 @@ G_PART_SCHEME_DECLARE(g_part_apm_scheme);
static int
apm_parse_type(const char *type, char *buf, size_t bufsz)
{
+ const char *alias;
- if (type[0] != '@') {
+ if (type[0] == '!') {
+ type++;
if (strlen(type) > bufsz)
return (EINVAL);
if (!strcmp(type, APM_ENT_TYPE_SELF) ||
@@ -109,17 +111,27 @@ apm_parse_type(const char *type, char *buf, size_t bufsz)
strncpy(buf, type, bufsz);
return (0);
}
- if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD)))
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
+ if (!strcasecmp(type, alias)) {
strcpy(buf, APM_ENT_TYPE_FREEBSD);
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
+ if (!strcasecmp(type, alias)) {
strcpy(buf, APM_ENT_TYPE_FREEBSD_SWAP);
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS);
+ if (!strcasecmp(type, alias)) {
strcpy(buf, APM_ENT_TYPE_FREEBSD_UFS);
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM);
+ if (!strcasecmp(type, alias)) {
strcpy(buf, APM_ENT_TYPE_FREEBSD_VINUM);
- else
- return (EINVAL);
- return (0);
+ return (0);
+ }
+ return (EINVAL);
}
static int
@@ -392,15 +404,15 @@ g_part_apm_write(struct g_part_table *basetable, struct g_consumer *cp)
baseentry = LIST_FIRST(&basetable->gpt_entry);
for (index = 1; index <= basetable->gpt_entries; index++) {
- if (baseentry != NULL && index == baseentry->gpe_index) {
- entry = (struct g_part_apm_entry *)baseentry;
+ entry = (baseentry != NULL && index == baseentry->gpe_index)
+ ? (struct g_part_apm_entry *)baseentry : NULL;
+ if (entry != NULL && !baseentry->gpe_deleted) {
be32enc(buf + 8, entry->ent.ent_start);
be32enc(buf + 12, entry->ent.ent_size);
bcopy(entry->ent.ent_name, buf + 16,
sizeof(entry->ent.ent_name));
bcopy(entry->ent.ent_type, buf + 48,
sizeof(entry->ent.ent_type));
- baseentry = LIST_NEXT(baseentry, gpe_entry);
} else {
bzero(buf + 8, 4 + 4 + 32 + 32);
strcpy(buf + 48, APM_ENT_TYPE_UNUSED);
@@ -408,6 +420,8 @@ g_part_apm_write(struct g_part_table *basetable, struct g_consumer *cp)
error = g_write_data(cp, (index + 1) * 512, buf, sizeof(buf));
if (error)
return (error);
+ if (entry != NULL)
+ baseentry = LIST_NEXT(baseentry, gpe_entry);
}
return (0);
diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index f8370a5..9f627b7 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -272,10 +272,11 @@ static int
gpt_parse_type(const char *type, struct uuid *uuid)
{
struct uuid tmp;
+ const char *alias;
int error;
- if (type[0] != '@') {
- error = parse_uuid(type, &tmp);
+ if (type[0] == '!') {
+ error = parse_uuid(type + 1, &tmp);
if (error)
return (error);
if (EQUUID(&tmp, &gpt_uuid_unused))
@@ -283,21 +284,37 @@ gpt_parse_type(const char *type, struct uuid *uuid)
*uuid = tmp;
return (0);
}
- if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_EFI)))
+ alias = g_part_alias_name(G_PART_ALIAS_EFI);
+ if (!strcasecmp(type, alias)) {
*uuid = gpt_uuid_efi;
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
+ if (!strcasecmp(type, alias)) {
*uuid = gpt_uuid_freebsd;
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
+ if (!strcasecmp(type, alias)) {
*uuid = gpt_uuid_freebsd_swap;
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS);
+ if (!strcasecmp(type, alias)) {
*uuid = gpt_uuid_freebsd_ufs;
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM);
+ if (!strcasecmp(type, alias)) {
*uuid = gpt_uuid_freebsd_vinum;
- else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_MBR)))
+ return (0);
+ }
+ alias = g_part_alias_name(G_PART_ALIAS_MBR);
+ if (!strcasecmp(type, alias)) {
*uuid = gpt_uuid_mbr;
- else
- return (EINVAL);
- return (0);
+ return (0);
+ }
+ return (EINVAL);
}
static int
@@ -391,9 +408,11 @@ g_part_gpt_modify(struct g_part_table *basetable,
int error;
entry = (struct g_part_gpt_entry *)baseentry;
- error = gpt_parse_type(gpp->gpp_type, &entry->ent.ent_type);
- if (error)
- return (error);
+ if (gpp->gpp_parms & G_PART_PARM_TYPE) {
+ error = gpt_parse_type(gpp->gpp_type, &entry->ent.ent_type);
+ if (error)
+ return (error);
+ }
/* XXX label */
return (0);
}
@@ -636,6 +655,8 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp)
le32enc(buf + 84, table->hdr.hdr_entsz);
LIST_FOREACH(baseentry, &basetable->gpt_entry, gpe_entry) {
+ if (baseentry->gpe_deleted)
+ continue;
entry = (struct g_part_gpt_entry *)baseentry;
index = baseentry->gpe_index - 1;
bp = buf + pp->sectorsize + table->hdr.hdr_entsz * index;
OpenPOWER on IntegriCloud