diff options
author | shidokht <none@none> | 2007-12-06 14:42:08 -0800 |
---|---|---|
committer | shidokht <none@none> | 2007-12-06 14:42:08 -0800 |
commit | ab92f716b59766135633fc08a66f7755835afb52 (patch) | |
tree | 544120b295162c4b3337ebd47fe550c3c57ac15e | |
parent | 7e60cf9bb9f2bd38e991524590b2d7b31b406a25 (diff) | |
download | illumos-joyent-ab92f716b59766135633fc08a66f7755835afb52.tar.gz |
6355349 sd treats a fdisk partitioned disk as EFI partitioned one
-rw-r--r-- | usr/src/uts/common/io/cmlb.c | 40 |
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; |