aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2013-11-21 22:02:59 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2013-11-21 22:02:59 +0000
commit3e5a0a6b70780ac5661a0b67824447b3c1cf81d2 (patch)
tree9735d314890f349e6767e9eedfcc82f68579ffb9 /sys/geom
parentd2ef321a59c8121f97c30155bd38e06a9eb441e7 (diff)
downloadsrc-3e5a0a6b70780ac5661a0b67824447b3c1cf81d2.tar.gz
src-3e5a0a6b70780ac5661a0b67824447b3c1cf81d2.zip
Have the GPT probe return a lower priority when the MBR is not a PMBR
The purpose of the PMBR is to have the disk appear in use to GPT unaware utilities (like fdisk). However, if the PMBR has been changed by a GPT unaware utlity then we must assume that this was deliberate (as it involved removal of the special slice) and we should not treat the unmodified GPT-specific sectors as being valid. By lowering the probe priority in that case, the MBR scheme will take precedence and the kernel will end up using the MBR and not the GPT. We will still use the GPT if the kernel does not support the MBR scheme.
Notes
Notes: svn path=/head/; revision=258448
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 13adf470d8bb..d10404756da4 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -759,8 +759,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)
@@ -785,11 +785,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);
@@ -801,7 +811,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,
@@ -810,7 +820,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