diff options
author | marcel <marcel@FreeBSD.org> | 2014-02-16 19:46:20 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2014-02-16 19:46:20 +0000 |
commit | 035a99067304e7c2ddce71a40b251d094ff6c06c (patch) | |
tree | 9eee2414266d31fddf3fb4431f26ce7cc240339c /sys/geom/part | |
parent | 9940d9e0d8af00e822a306a7429432f1892a95bc (diff) | |
download | FreeBSD-src-035a99067304e7c2ddce71a40b251d094ff6c06c.zip FreeBSD-src-035a99067304e7c2ddce71a40b251d094ff6c06c.tar.gz |
MFC r258448:
Have the GPT probe return a lower priority when the MBR is not a PMBR.
Diffstat (limited to 'sys/geom/part')
-rw-r--r-- | sys/geom/part/g_part_gpt.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c index 751dd16..efabfbc 100644 --- a/sys/geom/part/g_part_gpt.c +++ b/sys/geom/part/g_part_gpt.c @@ -758,8 +758,8 @@ static int g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) { struct g_provider *pp; - char *buf; - int error, res; + u_char *buf; + int error, index, pri, res; /* We don't nest, which means that our depth should be 0. */ if (table->gpt_depth != 0) @@ -784,11 +784,21 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) if (pp->sectorsize < MBRSIZE || pp->mediasize < 6 * pp->sectorsize) return (ENOSPC); - /* Check that there's a MBR. */ + /* + * Check that there's a MBR or a PMBR. If it's a PMBR, we return + * as the highest priority on a match, otherwise we assume some + * GPT-unaware tool has destroyed the GPT by recreating a MBR and + * we really want the MBR scheme to take precedence. + */ buf = g_read_data(cp, 0L, pp->sectorsize, &error); if (buf == NULL) return (error); res = le16dec(buf + DOSMAGICOFFSET); + pri = G_PART_PROBE_PRI_LOW; + for (index = 0; index < NDOSPART; index++) { + if (buf[DOSPARTOFF + DOSPARTSIZE * index + 4] == 0xee) + pri = G_PART_PROBE_PRI_HIGH; + } g_free(buf); if (res != DOSMAGIC) return (ENXIO); @@ -800,7 +810,7 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) res = memcmp(buf, GPT_HDR_SIG, 8); g_free(buf); if (res == 0) - return (G_PART_PROBE_PRI_HIGH); + return (pri); /* No primary? Check that there's a secondary. */ buf = g_read_data(cp, pp->mediasize - pp->sectorsize, pp->sectorsize, @@ -809,7 +819,7 @@ g_part_gpt_probe(struct g_part_table *table, struct g_consumer *cp) return (error); res = memcmp(buf, GPT_HDR_SIG, 8); g_free(buf); - return ((res == 0) ? G_PART_PROBE_PRI_HIGH : ENXIO); + return ((res == 0) ? pri : ENXIO); } static int |