summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshidokht <none@none>2007-12-06 14:42:08 -0800
committershidokht <none@none>2007-12-06 14:42:08 -0800
commitab92f716b59766135633fc08a66f7755835afb52 (patch)
tree544120b295162c4b3337ebd47fe550c3c57ac15e
parent7e60cf9bb9f2bd38e991524590b2d7b31b406a25 (diff)
downloadillumos-joyent-ab92f716b59766135633fc08a66f7755835afb52.tar.gz
6355349 sd treats a fdisk partitioned disk as EFI partitioned one
-rw-r--r--usr/src/uts/common/io/cmlb.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/usr/src/uts/common/io/cmlb.c b/usr/src/uts/common/io/cmlb.c
index 6650a0289f..549e675533 100644
--- a/usr/src/uts/common/io/cmlb.c
+++ b/usr/src/uts/common/io/cmlb.c
@@ -191,6 +191,7 @@ static void cmlb_clear_vtoc(struct cmlb_lun *cl, void *tg_cookie);
static void cmlb_setup_default_geometry(struct cmlb_lun *cl, void *tg_cookie);
static int cmlb_create_minor_nodes(struct cmlb_lun *cl);
static int cmlb_check_update_blockcount(struct cmlb_lun *cl, void *tg_cookie);
+static int cmlb_check_efi_mbr(uchar_t *buf);
#if defined(__i386) || defined(__amd64)
static int cmlb_update_fdisk_and_vtoc(struct cmlb_lun *cl, void *tg_cookie);
@@ -2016,6 +2017,40 @@ cmlb_validate_efi(efi_gpt_t *labp)
return (0);
}
+/*
+ * This function returns FALSE if there is a valid MBR signature and no
+ * partition table entries of type EFI_PMBR (0xEE). Otherwise it returns TRUE.
+ *
+ * The EFI spec (1.10 and later) requires having a Protective MBR (PMBR) to
+ * recognize the disk as GPT partitioned. However, some other OS creates an MBR
+ * where a PMBR entry is not the only one. Also, if the first block has been
+ * corrupted, currently best attempt to allow data access would be to try to
+ * check for GPT headers. Hence in case of more than one partition entry, but
+ * at least one EFI_PMBR partition type or no valid magic number, the function
+ * returns TRUE to continue with looking for GPT header.
+ */
+
+static int
+cmlb_check_efi_mbr(uchar_t *buf)
+{
+ struct ipart *fdp;
+ struct mboot *mbp = (struct mboot *)buf;
+ struct ipart fdisk[FD_NUMPART];
+ int i;
+
+ if (LE_16(mbp->signature) != MBB_MAGIC)
+ return (TRUE);
+
+ bcopy(&mbp->parts[0], fdisk, sizeof (fdisk));
+
+ for (fdp = fdisk, i = 0; i < FD_NUMPART; i++, fdp++) {
+ if (fdp->systid == EFI_PMBR)
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
static int
cmlb_use_efi(struct cmlb_lun *cl, diskaddr_t capacity, int flags,
void *tg_cookie)
@@ -2057,6 +2092,11 @@ cmlb_use_efi(struct cmlb_lun *cl, diskaddr_t capacity, int flags,
goto done_err;
}
+ if (cmlb_check_efi_mbr(buf) == FALSE) {
+ rval = EINVAL;
+ goto done_err;
+ }
+
rval = DK_TG_READ(cl, buf, 1, lbasize, tg_cookie);
if (rval) {
iofailed = 1;