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.
This commit is contained in:
Marcel Moolenaar 2007-05-08 20:18:17 +00:00
parent 62c4e3f043
commit d287f59062
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169389
4 changed files with 102 additions and 94 deletions

View File

@ -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;
}
@ -731,13 +730,6 @@ g_part_ctl_move(struct gctl_req *req, struct g_part_parms *gpp)
return (ENOSYS);
}
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)
{
@ -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;

View File

@ -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_ */

View File

@ -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);

View File

@ -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;