summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2006-06-26 00:32:54 +0000
committersobomax <sobomax@FreeBSD.org>2006-06-26 00:32:54 +0000
commitc410e9767338b92aea6653ce3a5fd0b0291e2a8c (patch)
tree79afb48b764c7a886fb590a241564dda51c30b6b
parent1d174c9f4d2c265d6959ed3c4e6bf8dca05b1f02 (diff)
downloadFreeBSD-src-c410e9767338b92aea6653ce3a5fd0b0291e2a8c.zip
FreeBSD-src-c410e9767338b92aea6653ce3a5fd0b0291e2a8c.tar.gz
Improve check for protective MBR. Instead of assiming that protective
MBR should have only one entry of type 0xEE, consider protective MBR to be one, that has at least one entry of type 0xEE covering the whole unit. This makes GEOM_GPT compatible with disks partitioned by the Apple's BootCamp. Approved in principle by: marcel MFC After: 1 month
-rw-r--r--sys/geom/geom_gpt.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/geom/geom_gpt.c b/sys/geom/geom_gpt.c
index aa074ee..24aa3c9 100644
--- a/sys/geom/geom_gpt.c
+++ b/sys/geom/geom_gpt.c
@@ -360,31 +360,50 @@ g_gpt_has_pmbr(struct g_consumer *cp, int *error)
{
char *buf;
uint8_t *typ;
- int i, pmbr;
+ int i, pmbr, vmbr;
uint16_t magic;
+ uint32_t dp_start, dp_size;
buf = g_read_data(cp, 0L, cp->provider->sectorsize, error);
if (buf == NULL)
return (0);
pmbr = 0;
+ vmbr = 0;
magic = le16toh(*(uint16_t *)(uintptr_t)(buf + DOSMAGICOFFSET));
if (magic != DOSMAGIC)
goto out;
+ /*
+ * Check that there are at least one partition of type
+ * DOSPTYP_PMBR that covers the whole unit.
+ */
for (i = 0; i < 4; i++) {
typ = buf + DOSPARTOFF + i * sizeof(struct dos_partition) +
offsetof(struct dos_partition, dp_typ);
+ bcopy(buf + DOSPARTOFF + i * sizeof(struct dos_partition) +
+ offsetof(struct dos_partition, dp_start), &dp_start, sizeof(dp_start));
+ bcopy(buf + DOSPARTOFF + i * sizeof(struct dos_partition) +
+ offsetof(struct dos_partition, dp_size), &dp_size, sizeof(dp_size));
+ if ((*typ == DOSPTYP_PMBR) &&
+ (le32toh(dp_start) == 1) &&
+ (cp->provider->mediasize ==
+ (le32toh(dp_size) * 512ULL))) {
+ pmbr = 1;
+ break;
+ }
if (*typ != 0 && *typ != DOSPTYP_PMBR)
- goto out;
+ vmbr = 1;
}
- pmbr = 1;
-
out:
g_free(buf);
- return (pmbr);
+ /*
+ * Return true if protective MBR is detected or if MBR has
+ * no valid entries at all.
+ */
+ return (pmbr || !vmbr);
}
static void
OpenPOWER on IntegriCloud