Author: marcel
Date: Thu Nov 21 22:02:59 2013
New Revision: 258448
URL: http://svnweb.freebsd.org/changeset/base/258448

Log:
  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.

Modified:
  head/sys/geom/part/g_part_gpt.c

Modified: head/sys/geom/part/g_part_gpt.c
==============================================================================
--- head/sys/geom/part/g_part_gpt.c     Thu Nov 21 21:25:58 2013        
(r258447)
+++ head/sys/geom/part/g_part_gpt.c     Thu Nov 21 22:02:59 2013        
(r258448)
@@ -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 *ta
        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 *ta
        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 *ta
                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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to