From c410e9767338b92aea6653ce3a5fd0b0291e2a8c Mon Sep 17 00:00:00 2001 From: sobomax Date: Mon, 26 Jun 2006 00:32:54 +0000 Subject: 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 --- sys/geom/geom_gpt.c | 29 ++++++++++++++++++++++++----- 1 file 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 -- cgit v1.1