From d287f590628fdf4fbdef05005ce3c2f9c0dc5a8f Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Tue, 8 May 2007 20:18:17 +0000 Subject: [PATCH] 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. --- sys/geom/part/g_part.c | 95 ++++++++++++++------------------------ sys/geom/part/g_part.h | 16 +++---- sys/geom/part/g_part_apm.c | 36 ++++++++++----- sys/geom/part/g_part_gpt.c | 49 ++++++++++++++------ 4 files changed, 102 insertions(+), 94 deletions(-) diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c index 2ccfe91b8c46..3a12a314b844 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; } @@ -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; diff --git a/sys/geom/part/g_part.h b/sys/geom/part/g_part.h index bd697b73e86e..8c6bbd52245c 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 f90fc6597f7f..50d5c1ee3d11 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 f8370a530f75..9f627b7b9714 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;