summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2014-02-16 19:46:20 +0000
committermarcel <marcel@FreeBSD.org>2014-02-16 19:46:20 +0000
commit035a99067304e7c2ddce71a40b251d094ff6c06c (patch)
tree9eee2414266d31fddf3fb4431f26ce7cc240339c /sys/geom
parent9940d9e0d8af00e822a306a7429432f1892a95bc (diff)
downloadFreeBSD-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')
-rw-r--r--sys/geom/part/g_part_gpt.c20
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
OpenPOWER on IntegriCloud