7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 * Copyright 2016 Toomas Soome <tsoome@me.com>
27 */
28
29 /*
30 * This module provides support for labeling operations for target
31 * drivers.
32 */
33
34 #include <sys/scsi/scsi.h>
35 #include <sys/sunddi.h>
36 #include <sys/dklabel.h>
37 #include <sys/dkio.h>
38 #include <sys/vtoc.h>
39 #include <sys/dktp/fdisk.h>
40 #include <sys/vtrace.h>
41 #include <sys/efi_partition.h>
42 #include <sys/cmlb.h>
43 #include <sys/cmlb_impl.h>
44 #if defined(__i386) || defined(__amd64)
45 #include <sys/fs/dv_node.h>
46 #endif
2730 static void
2731 cmlb_swap_efi_gpe(int nparts, efi_gpe_t *p)
2732 {
2733 int i;
2734
2735 _NOTE(ASSUMING_PROTECTED(*p))
2736 for (i = 0; i < nparts; i++) {
2737 UUID_LE_CONVERT(p[i].efi_gpe_PartitionTypeGUID,
2738 p[i].efi_gpe_PartitionTypeGUID);
2739 p[i].efi_gpe_StartingLBA = LE_64(p[i].efi_gpe_StartingLBA);
2740 p[i].efi_gpe_EndingLBA = LE_64(p[i].efi_gpe_EndingLBA);
2741 /* PartitionAttrs */
2742 }
2743 }
2744
2745 static int
2746 cmlb_validate_efi(efi_gpt_t *labp)
2747 {
2748 if (labp->efi_gpt_Signature != EFI_SIGNATURE)
2749 return (EINVAL);
2750 /* at least 96 bytes in this version of the spec. */
2751 if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
2752 labp->efi_gpt_HeaderSize)
2753 return (EINVAL);
2754 /* this should be 128 bytes */
2755 if (labp->efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t))
2756 return (EINVAL);
2757 return (0);
2758 }
2759
2760 /*
2761 * This function returns B_FALSE if there is a valid MBR signature and no
2762 * partition table entries of type EFI_PMBR (0xEE). Otherwise it returns B_TRUE.
2763 *
2764 * The EFI spec (1.10 and later) requires having a Protective MBR (PMBR) to
2765 * recognize the disk as GPT partitioned. However, some other OS creates an MBR
2766 * where a PMBR entry is not the only one. Also, if the first block has been
2767 * corrupted, currently best attempt to allow data access would be to try to
2768 * check for GPT headers. Hence in case of more than one partition entry, but
2769 * at least one EFI_PMBR partition type or no valid magic number, the function
2770 * returns B_TRUE to continue with looking for GPT header.
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 * Copyright 2016 Toomas Soome <tsoome@me.com>
27 * Copyright (c) 2019, Joyent, Inc.
28 */
29
30 /*
31 * This module provides support for labeling operations for target
32 * drivers.
33 */
34
35 #include <sys/scsi/scsi.h>
36 #include <sys/sunddi.h>
37 #include <sys/dklabel.h>
38 #include <sys/dkio.h>
39 #include <sys/vtoc.h>
40 #include <sys/dktp/fdisk.h>
41 #include <sys/vtrace.h>
42 #include <sys/efi_partition.h>
43 #include <sys/cmlb.h>
44 #include <sys/cmlb_impl.h>
45 #if defined(__i386) || defined(__amd64)
46 #include <sys/fs/dv_node.h>
47 #endif
2731 static void
2732 cmlb_swap_efi_gpe(int nparts, efi_gpe_t *p)
2733 {
2734 int i;
2735
2736 _NOTE(ASSUMING_PROTECTED(*p))
2737 for (i = 0; i < nparts; i++) {
2738 UUID_LE_CONVERT(p[i].efi_gpe_PartitionTypeGUID,
2739 p[i].efi_gpe_PartitionTypeGUID);
2740 p[i].efi_gpe_StartingLBA = LE_64(p[i].efi_gpe_StartingLBA);
2741 p[i].efi_gpe_EndingLBA = LE_64(p[i].efi_gpe_EndingLBA);
2742 /* PartitionAttrs */
2743 }
2744 }
2745
2746 static int
2747 cmlb_validate_efi(efi_gpt_t *labp)
2748 {
2749 if (labp->efi_gpt_Signature != EFI_SIGNATURE)
2750 return (EINVAL);
2751 /* at least 92 bytes in this version of the spec. */
2752 if (sizeof (efi_gpt_t) - sizeof (labp->efi_gpt_Reserved2) >
2753 labp->efi_gpt_HeaderSize)
2754 return (EINVAL);
2755 /* this should be 128 bytes */
2756 if (labp->efi_gpt_SizeOfPartitionEntry != sizeof (efi_gpe_t))
2757 return (EINVAL);
2758 return (0);
2759 }
2760
2761 /*
2762 * This function returns B_FALSE if there is a valid MBR signature and no
2763 * partition table entries of type EFI_PMBR (0xEE). Otherwise it returns B_TRUE.
2764 *
2765 * The EFI spec (1.10 and later) requires having a Protective MBR (PMBR) to
2766 * recognize the disk as GPT partitioned. However, some other OS creates an MBR
2767 * where a PMBR entry is not the only one. Also, if the first block has been
2768 * corrupted, currently best attempt to allow data access would be to try to
2769 * check for GPT headers. Hence in case of more than one partition entry, but
2770 * at least one EFI_PMBR partition type or no valid magic number, the function
2771 * returns B_TRUE to continue with looking for GPT header.
|