Tweak the two copies of gpt_chk_mbr() to return the index of the MBR
authorkrw <krw@openbsd.org>
Fri, 14 May 2021 15:31:01 +0000 (15:31 +0000)
committerkrw <krw@openbsd.org>
Fri, 14 May 2021 15:31:01 +0000 (15:31 +0000)
0xEE (DOSPTYP_EFI) partition, or -1 no usable such partition is found.

Adopt a consistent idiom to capture the index for future use.

Clean up the gpt_chk_mbr() logic to make it clearer what constraints
are being applied when looking for the DOSTYP_EFI partition.

No intentional functional change.

sbin/fdisk/cmd.c
sbin/fdisk/fdisk.c
sbin/fdisk/mbr.c
sbin/fdisk/user.c
sys/kern/subr_disk.c

index 0ee22c3..8ba7f5e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cmd.c,v 1.102 2021/05/10 17:16:01 krw Exp $   */
+/*     $OpenBSD: cmd.c,v 1.103 2021/05/14 15:31:01 krw Exp $   */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -45,7 +45,9 @@ int
 Xreinit(char *args, struct mbr *mbr)
 {
        struct dos_mbr dos_mbr;
-       int dogpt;
+       int efi, dogpt;
+
+       efi = MBR_protective_mbr(mbr);
 
        if (strncasecmp(args, "gpt", 3) == 0)
                dogpt = 1;
@@ -54,7 +56,7 @@ Xreinit(char *args, struct mbr *mbr)
        else if (strlen(args) > 0) {
                printf("Unrecognized modifier '%s'\n", args);
                return (CMD_CONT);
-       } else if (MBR_protective_mbr(mbr) == 0)
+       } else if (efi != -1)
                dogpt = 1;
        else
                dogpt = 0;
@@ -393,8 +395,10 @@ Xselect(char *args, struct mbr *mbr)
 int
 Xprint(char *args, struct mbr *mbr)
 {
+       int efi;
 
-       if (MBR_protective_mbr(mbr) == 0 && letoh64(gh.gh_sig) == GPTSIGNATURE)
+       efi = MBR_protective_mbr(mbr);
+       if (efi != -1 && letoh64(gh.gh_sig) == GPTSIGNATURE)
                GPT_print(args, VERBOSE);
        else
                MBR_print(mbr, args);
index 55ad12d..9fc0abb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fdisk.c,v 1.106 2021/05/10 17:16:01 krw Exp $ */
+/*     $OpenBSD: fdisk.c,v 1.107 2021/05/14 15:31:01 krw Exp $ */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -71,7 +71,7 @@ int
 main(int argc, char *argv[])
 {
        ssize_t len;
-       int ch, fd, error;
+       int ch, fd, efi, error;
        int e_flag = 0, g_flag = 0, i_flag = 0, u_flag = 0;
        int verbosity = TERSE;
        int c_arg = 0, h_arg = 0, s_arg = 0;
@@ -175,7 +175,8 @@ main(int argc, char *argv[])
        MBR_parse(&dos_mbr, 0, 0, &mbr);
 
        /* Get the GPT if present. Either primary or secondary is ok. */
-       if (MBR_protective_mbr(&mbr) == 0)
+       efi = MBR_protective_mbr(&mbr);
+       if (efi != -1)
                GPT_read(ANYGPT);
 
        if (!(i_flag || u_flag || e_flag)) {
index 9ae2523..e833989 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mbr.c,v 1.68 2021/05/07 22:15:13 krw Exp $    */
+/*     $OpenBSD: mbr.c,v 1.69 2021/05/14 15:31:01 krw Exp $    */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -289,39 +289,36 @@ MBR_zapgpt(struct dos_mbr *dos_mbr, uint64_t lastsec)
 }
 
 /*
- * Returns 0 if the MBR with the provided partition array is a GPT protective
- * MBR, and returns 1 otherwise. A GPT protective MBR would have one and only
- * one MBR partition, an EFI partition that either covers the whole disk or as
- * much of it as is possible with a 32bit size field.
+ * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such
+ * partition exists.
  *
  * Taken from kern/subr_disk.c.
  *
- * NOTE: MS always uses a size of UINT32_MAX for the EFI partition!**
  */
 int
-gpt_chk_mbr(struct dos_partition *dp, uint64_t dsize)
+gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize)
 {
        struct dos_partition *dp2;
-       int efi, found, i;
-       uint32_t psize;
+       int efi, eficnt, found, i;
+       u_int32_t psize;
 
-       found = efi = 0;
+       found = efi = eficnt = 0;
        for (dp2=dp, i=0; i < NDOSPART; i++, dp2++) {
                if (dp2->dp_typ == DOSPTYP_UNUSED)
                        continue;
                found++;
                if (dp2->dp_typ != DOSPTYP_EFI)
                        continue;
+               if (letoh32(dp2->dp_start) != GPTSECTOR)
+                       continue;
                psize = letoh32(dp2->dp_size);
-               if (psize == (dsize - 1) ||
-                   psize == UINT32_MAX) {
-                       if (letoh32(dp2->dp_start) == 1)
-                               efi++;
+               if (psize == (dsize - 1) || psize == UINT32_MAX) {
+                       efi = i;
+                       eficnt++;
                }
        }
-       if (found == 1 && efi == 1)
-               return (0);
+       if (found == 1 && eficnt == 1)
+               return (efi);
 
-       return (1);
+       return (-1);
 }
-
index 409ff36..1f721a8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: user.c,v 1.53 2021/05/10 17:16:01 krw Exp $   */
+/*     $OpenBSD: user.c,v 1.54 2021/05/14 15:31:01 krw Exp $   */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -63,7 +63,7 @@ USER_edit(off_t offset, off_t reloff)
        struct dos_mbr dos_mbr;
        struct mbr mbr;
        char *cmd, *args;
-       int i, st, error;
+       int i, st, efi, error;
 
        /* One level deeper */
        editlevel += 1;
@@ -79,7 +79,8 @@ USER_edit(off_t offset, off_t reloff)
        if (editlevel == 1) {
                memset(&gh, 0, sizeof(gh));
                memset(&gp, 0, sizeof(gp));
-               if (MBR_protective_mbr(&mbr) == 0)
+               efi = MBR_protective_mbr(&mbr);
+               if (efi != -1)
                        GPT_read(ANYGPT);
        }
 
@@ -141,7 +142,7 @@ void
 USER_print_disk(int verbosity)
 {
        off_t offset, firstoff;
-       int i, error;
+       int i, efi, error;
        struct dos_mbr dos_mbr;
        struct mbr mbr;
 
@@ -153,8 +154,8 @@ USER_print_disk(int verbosity)
                        break;
                MBR_parse(&dos_mbr, offset, firstoff, &mbr);
                if (offset == 0) {
-                       if (verbosity == VERBOSE || MBR_protective_mbr(&mbr) ==
-                           0) {
+                       efi = MBR_protective_mbr(&mbr);
+                       if (verbosity == VERBOSE || efi != -1) {
                                if (verbosity == VERBOSE) {
                                        printf("Primary GPT:\n");
                                        GPT_read(PRIMARYGPT);
index 40397a9..21c61e7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: subr_disk.c,v 1.239 2021/05/08 16:41:24 krw Exp $     */
+/*     $OpenBSD: subr_disk.c,v 1.240 2021/05/14 15:31:01 krw Exp $     */
 /*     $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $  */
 
 /*
@@ -330,13 +330,13 @@ int
 readdoslabel(struct buf *bp, void (*strat)(struct buf *),
     struct disklabel *lp, daddr_t *partoffp, int spoofonly)
 {
+       struct dos_partition dp[NDOSPART], *dp2;
        struct disklabel *gptlp;
        u_int64_t dospartoff = 0, dospartend = DL_GETBEND(lp);
-       int i, ourpart = -1, wander = 1, n = 0, loop = 0, offset;
-       struct dos_partition dp[NDOSPART], *dp2;
        u_int64_t sector = DOSBBSECTOR;
        u_int32_t extoff = 0;
-       int error;
+       int ourpart = -1, wander = 1, n = 0, loop = 0;
+       int efi, error, i, offset;
 
        if (lp->d_secpercyl == 0)
                return (EINVAL);        /* invalid label */
@@ -374,7 +374,8 @@ readdoslabel(struct buf *bp, void (*strat)(struct buf *),
                        if (mbrtest != 0x55aa)
                                goto notmbr;
 
-                       if (gpt_chk_mbr(dp, DL_GETDSIZE(lp)) != 0)
+                       efi = gpt_chk_mbr(dp, DL_GETDSIZE(lp));
+                       if (efi == -1)
                                goto notgpt;
 
                        gptlp = malloc(sizeof(struct disklabel), M_DEVBUF,
@@ -584,38 +585,37 @@ notfat:
 }
 
 /*
- * Returns 0 if the MBR with the provided partition array is a GPT protective
- * MBR, and returns 1 otherwise. A GPT protective MBR would have one and only
- * one MBR partition, an EFI partition that either covers the whole disk or as
- * much of it as is possible with a 32bit size field.
+ * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such
+ * partition exists.
  *
- * NOTE: MS always uses a size of UINT32_MAX for the EFI partition!**
+ * Copied into sbin/fdisk/mbr.c.
  */
 int
 gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize)
 {
        struct dos_partition *dp2;
-       int efi, found, i;
+       int efi, eficnt, found, i;
        u_int32_t psize;
 
-       found = efi = 0;
+       found = efi = eficnt = 0;
        for (dp2=dp, i=0; i < NDOSPART; i++, dp2++) {
                if (dp2->dp_typ == DOSPTYP_UNUSED)
                        continue;
                found++;
                if (dp2->dp_typ != DOSPTYP_EFI)
                        continue;
+               if (letoh32(dp2->dp_start) != GPTSECTOR)
+                       continue;
                psize = letoh32(dp2->dp_size);
-               if (psize == (dsize - 1) ||
-                   psize == UINT32_MAX) {
-                       if (letoh32(dp2->dp_start) == 1)
-                               efi++;
+               if (psize == (dsize - 1) || psize == UINT32_MAX) {
+                       efi = i;
+                       eficnt++;
                }
        }
-       if (found == 1 && efi == 1)
-               return (0);
+       if (found == 1 && eficnt == 1)
+               return (efi);
 
-       return (1);
+       return (-1);
 }
 
 int