summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/cmlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io/cmlb.c')
-rw-r--r--usr/src/uts/common/io/cmlb.c519
1 files changed, 511 insertions, 8 deletions
diff --git a/usr/src/uts/common/io/cmlb.c b/usr/src/uts/common/io/cmlb.c
index 83c962afb9..848ea4b92f 100644
--- a/usr/src/uts/common/io/cmlb.c
+++ b/usr/src/uts/common/io/cmlb.c
@@ -39,6 +39,9 @@
#include <sys/efi_partition.h>
#include <sys/cmlb.h>
#include <sys/cmlb_impl.h>
+#if defined(__i386) || defined(__amd64)
+#include <sys/fs/dv_node.h>
+#endif
#include <sys/ddi_impldefs.h>
/*
@@ -104,6 +107,78 @@ static struct driver_minor_data dk_minor_data[] = {
{0}
};
+#if defined(__i386) || defined(__amd64)
+#if defined(_FIRMWARE_NEEDS_FDISK)
+static struct driver_minor_data dk_ext_minor_data[] = {
+ {"p5", 21, S_IFBLK},
+ {"p6", 22, S_IFBLK},
+ {"p7", 23, S_IFBLK},
+ {"p8", 24, S_IFBLK},
+ {"p9", 25, S_IFBLK},
+ {"p10", 26, S_IFBLK},
+ {"p11", 27, S_IFBLK},
+ {"p12", 28, S_IFBLK},
+ {"p13", 29, S_IFBLK},
+ {"p14", 30, S_IFBLK},
+ {"p15", 31, S_IFBLK},
+ {"p16", 32, S_IFBLK},
+ {"p17", 33, S_IFBLK},
+ {"p18", 34, S_IFBLK},
+ {"p19", 35, S_IFBLK},
+ {"p20", 36, S_IFBLK},
+ {"p21", 37, S_IFBLK},
+ {"p22", 38, S_IFBLK},
+ {"p23", 39, S_IFBLK},
+ {"p24", 40, S_IFBLK},
+ {"p25", 41, S_IFBLK},
+ {"p26", 42, S_IFBLK},
+ {"p27", 43, S_IFBLK},
+ {"p28", 44, S_IFBLK},
+ {"p29", 45, S_IFBLK},
+ {"p30", 46, S_IFBLK},
+ {"p31", 47, S_IFBLK},
+ {"p32", 48, S_IFBLK},
+ {"p33", 49, S_IFBLK},
+ {"p34", 50, S_IFBLK},
+ {"p35", 51, S_IFBLK},
+ {"p36", 52, S_IFBLK},
+ {"p5,raw", 21, S_IFCHR},
+ {"p6,raw", 22, S_IFCHR},
+ {"p7,raw", 23, S_IFCHR},
+ {"p8,raw", 24, S_IFCHR},
+ {"p9,raw", 25, S_IFCHR},
+ {"p10,raw", 26, S_IFCHR},
+ {"p11,raw", 27, S_IFCHR},
+ {"p12,raw", 28, S_IFCHR},
+ {"p13,raw", 29, S_IFCHR},
+ {"p14,raw", 30, S_IFCHR},
+ {"p15,raw", 31, S_IFCHR},
+ {"p16,raw", 32, S_IFCHR},
+ {"p17,raw", 33, S_IFCHR},
+ {"p18,raw", 34, S_IFCHR},
+ {"p19,raw", 35, S_IFCHR},
+ {"p20,raw", 36, S_IFCHR},
+ {"p21,raw", 37, S_IFCHR},
+ {"p22,raw", 38, S_IFCHR},
+ {"p23,raw", 39, S_IFCHR},
+ {"p24,raw", 40, S_IFCHR},
+ {"p25,raw", 41, S_IFCHR},
+ {"p26,raw", 42, S_IFCHR},
+ {"p27,raw", 43, S_IFCHR},
+ {"p28,raw", 44, S_IFCHR},
+ {"p29,raw", 45, S_IFCHR},
+ {"p30,raw", 46, S_IFCHR},
+ {"p31,raw", 47, S_IFCHR},
+ {"p32,raw", 48, S_IFCHR},
+ {"p33,raw", 49, S_IFCHR},
+ {"p34,raw", 50, S_IFCHR},
+ {"p35,raw", 51, S_IFCHR},
+ {"p36,raw", 52, S_IFCHR},
+ {0}
+};
+#endif /* defined(_FIRMWARE_NEEDS_FDISK) */
+#endif /* if defined(__i386) || defined(__amd64) */
+
static struct driver_minor_data dk_minor_data_efi[] = {
{"a", 0, S_IFBLK},
{"b", 1, S_IFBLK},
@@ -247,6 +322,12 @@ static int cmlb_dkio_partition(struct cmlb_lun *cl, caddr_t arg, int flag,
void *tg_cookie);
#if defined(__i386) || defined(__amd64)
+static int cmlb_dkio_set_ext_part(struct cmlb_lun *cl, caddr_t arg, int flag,
+ void *tg_cookie);
+static int cmlb_validate_ext_part(struct cmlb_lun *cl, int part, int epart,
+ uint32_t start, uint32_t size);
+static int cmlb_is_linux_swap(struct cmlb_lun *cl, uint32_t part_start,
+ void *tg_cookie);
static int cmlb_dkio_get_virtgeom(struct cmlb_lun *cl, caddr_t arg, int flag);
static int cmlb_dkio_get_phygeom(struct cmlb_lun *cl, caddr_t arg, int flag);
static int cmlb_dkio_partinfo(struct cmlb_lun *cl, dev_t dev, caddr_t arg,
@@ -593,6 +674,9 @@ cmlb_attach(dev_info_t *devi, cmlb_tg_ops_t *tgopsp, int device_type,
cl->cl_alter_behavior = alter_behavior;
cl->cl_reserved = -1;
cl->cl_msglog_flag |= CMLB_ALLOW_2TB_WARN;
+#if defined(__i386) || defined(__amd64)
+ cl->cl_logical_drive_count = 0;
+#endif
if (is_removable == 0) {
mutex_exit(CMLB_MUTEX(cl));
@@ -1051,6 +1135,9 @@ cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd, intptr_t arg,
case DKIOCSGEOM:
case DKIOCSETEFI:
case DKIOCSMBOOT:
+#if defined(__i386) || defined(__amd64)
+ case DKIOCSETEXTPART:
+#endif
break;
case DKIOCSVTOC:
#if defined(__i386) || defined(__amd64)
@@ -1195,7 +1282,12 @@ cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd, intptr_t arg,
err = ENOTTY;
#endif
break;
-
+#if defined(__i386) || defined(__amd64)
+ case DKIOCSETEXTPART:
+ cmlb_dbg(CMLB_TRACE, cl, "DKIOCSETEXTPART");
+ err = cmlb_dkio_set_ext_part(cl, (caddr_t)arg, flag, tg_cookie);
+ break;
+#endif
default:
err = ENOTTY;
@@ -1632,7 +1724,7 @@ no_solaris_partition:
* Note that dkl_cylno is not used for the fdisk map entries, so
* we set it to an entirely bogus value.
*/
- for (count = 0; count < FD_NUMPART; count++) {
+ for (count = 0; count < FDISK_PARTS; count++) {
cl->cl_map[FDISK_P1 + count].dkl_cylno = UINT16_MAX;
cl->cl_map[FDISK_P1 + count].dkl_nblk =
cl->cl_fmap[count].fmap_nblk;
@@ -1837,6 +1929,267 @@ cmlb_resync_geom_caches(struct cmlb_lun *cl, diskaddr_t capacity,
}
+#if defined(__i386) || defined(__amd64)
+/*
+ * Function: cmlb_update_ext_minor_nodes
+ *
+ * Description: Routine to add/remove extended partition device nodes
+ *
+ * Arguments:
+ * cl driver soft state (unit) structure
+ * num_parts Number of logical drives found on the LUN
+ *
+ * Should be called with the mutex held
+ *
+ * Return Code: 0 for success
+ *
+ * Context: User and Kernel thread
+ *
+ */
+static int
+cmlb_update_ext_minor_nodes(struct cmlb_lun *cl, int num_parts)
+{
+ int i;
+ char name[48];
+ int instance;
+ struct driver_minor_data *demdp, *demdpr;
+ char *devnm;
+ dev_info_t *pdip;
+
+ ASSERT(mutex_owned(CMLB_MUTEX(cl)));
+ ASSERT(cl->cl_update_ext_minor_nodes == 1);
+ instance = ddi_get_instance(CMLB_DEVINFO(cl));
+
+ demdp = dk_ext_minor_data;
+ demdpr = &dk_ext_minor_data[MAX_EXT_PARTS];
+
+ if (cl->cl_logical_drive_count) {
+ for (i = 0; i < cl->cl_logical_drive_count; i++) {
+ (void) sprintf(name, "%s", demdp->name);
+ ddi_remove_minor_node(CMLB_DEVINFO(cl), name);
+ (void) sprintf(name, "%s", demdpr->name);
+ ddi_remove_minor_node(CMLB_DEVINFO(cl), name);
+ demdp++;
+ demdpr++;
+ }
+ /* There are existing device nodes. Remove them */
+ devnm = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
+ (void) ddi_deviname(cl->cl_devi, devnm);
+ pdip = ddi_get_parent(cl->cl_devi);
+ (void) devfs_clean(pdip, devnm + 1, DV_CLEAN_FORCE);
+ kmem_free(devnm, MAXNAMELEN + 1);
+ }
+
+ demdp = dk_ext_minor_data;
+ demdpr = &dk_ext_minor_data[MAX_EXT_PARTS];
+
+ for (i = 0; i < num_parts; i++) {
+ (void) sprintf(name, "%s", demdp->name);
+ if (ddi_create_minor_node(CMLB_DEVINFO(cl), name,
+ demdp->type,
+ (instance << CMLBUNIT_SHIFT) | demdp->minor,
+ cl->cl_node_type, NULL) == DDI_FAILURE) {
+ /*
+ * Clean up any nodes that may have been
+ * created, in case this fails in the middle
+ * of the loop.
+ */
+ ddi_remove_minor_node(CMLB_DEVINFO(cl), NULL);
+ cl->cl_logical_drive_count = 0;
+ return (ENXIO);
+ }
+ (void) sprintf(name, "%s", demdpr->name);
+ if (ddi_create_minor_node(CMLB_DEVINFO(cl), name,
+ demdpr->type,
+ (instance << CMLBUNIT_SHIFT) | demdpr->minor,
+ cl->cl_node_type, NULL) == DDI_FAILURE) {
+ /*
+ * Clean up any nodes that may have been
+ * created, in case this fails in the middle
+ * of the loop.
+ */
+ ddi_remove_minor_node(CMLB_DEVINFO(cl), NULL);
+ cl->cl_logical_drive_count = 0;
+ return (ENXIO);
+ }
+ demdp++;
+ demdpr++;
+ }
+ cl->cl_logical_drive_count = i;
+ cl->cl_update_ext_minor_nodes = 0;
+ return (0);
+}
+/*
+ * Function: cmlb_validate_ext_part
+ *
+ * Description: utility routine to validate an extended partition's
+ * metadata as found on disk
+ *
+ * Arguments:
+ * cl driver soft state (unit) structure
+ * part partition number of the extended partition
+ * epart partition number of the logical drive
+ * start absolute sector number of the start of the logical
+ * drive being validated
+ * size size of logical drive being validated
+ *
+ * Return Code: 0 for success
+ *
+ * Context: User and Kernel thread
+ *
+ * Algorithm :
+ * Error cases are :
+ * 1. If start block is lesser than or equal to the end block
+ * 2. If either start block or end block is beyond the bounadry
+ * of the extended partition.
+ * 3. start or end block overlap with existing partitions.
+ * To check this, first make sure that the start block doesnt
+ * overlap with existing partitions. Then, calculate the
+ * possible end block for the given start block that doesnt
+ * overlap with existing partitions. This can be calculated by
+ * first setting the possible end block to the end of the
+ * extended partition (optimistic) and then, checking if there
+ * is any other partition that lies after the start of the
+ * partition being validated. If so, set the possible end to
+ * one block less than the beginning of the next nearest partition
+ * If the actual end block is greater than the calculated end
+ * block, we have an overlap.
+ *
+ */
+static int
+cmlb_validate_ext_part(struct cmlb_lun *cl, int part, int epart, uint32_t start,
+ uint32_t size)
+{
+ int i;
+ uint32_t end = start + size - 1;
+ uint32_t ext_start = cl->cl_fmap[part].fmap_start;
+ uint32_t ext_end = ext_start + cl->cl_fmap[part].fmap_nblk - 1;
+ uint32_t ts, te;
+ uint32_t poss_end = ext_end;
+
+ if (end <= start) {
+ return (1);
+ }
+
+ /*
+ * Check if the logical drive boundaries are within that of the
+ * extended partition.
+ */
+ if (start <= ext_start || start > ext_end || end <= ext_start ||
+ end > ext_end) {
+ return (1);
+ }
+
+ /*
+ * epart will be equal to FD_NUMPART if it is the first logical drive.
+ * There is no need to check for overlaps with other logical drives,
+ * since it is the only logical drive that we have come across so far.
+ */
+ if (epart == FD_NUMPART) {
+ return (0);
+ }
+
+ /* Check for overlaps with existing logical drives */
+ i = FD_NUMPART;
+ ts = cl->cl_fmap[FD_NUMPART].fmap_start;
+ te = ts + cl->cl_fmap[FD_NUMPART].fmap_nblk - 1;
+
+ while ((i < epart) && ts && te) {
+ if (start >= ts && start <= te) {
+ return (1);
+ }
+
+ if ((ts < poss_end) && (ts > start)) {
+ poss_end = ts - 1;
+ }
+
+ i++;
+ ts = cl->cl_fmap[i].fmap_start;
+ te = ts + cl->cl_fmap[i].fmap_nblk - 1;
+ }
+
+ if (end > poss_end) {
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Function: cmlb_is_linux_swap
+ *
+ * Description: utility routine to verify if a partition is a linux swap
+ * partition or not.
+ *
+ * Arguments:
+ * cl driver soft state (unit) structure
+ * part_start absolute sector number of the start of the partition
+ * being verified
+ * tg_cookie cookie from target driver to be passed back to target
+ * driver when we call back to it through tg_ops.
+ *
+ * Return Code: 0 for success
+ *
+ * Context: User and Kernel thread
+ *
+ * Notes:
+ * The linux swap magic "SWAP-SPACE" or "SWAPSPACE2" is found as the
+ * last 10 bytes of a disk block whose size is that of the linux page
+ * size. This disk block is found at the beginning of the swap partition.
+ */
+static int
+cmlb_is_linux_swap(struct cmlb_lun *cl, uint32_t part_start, void *tg_cookie)
+{
+ int i;
+ int rval = -1;
+ uint32_t seek_offset;
+ uint32_t linux_pg_size;
+ char *buf, *linux_swap_magic;
+ int sec_sz = cl->cl_sys_blocksize;
+ /* Known linux kernel page sizes */
+ uint32_t linux_pg_size_arr[] = {4096, };
+
+ ASSERT(cl != NULL);
+ ASSERT(mutex_owned(CMLB_MUTEX(cl)));
+
+ if ((buf = kmem_zalloc(sec_sz, KM_NOSLEEP)) == NULL) {
+ return (ENOMEM);
+ }
+
+ linux_swap_magic = buf + sec_sz - 10;
+
+ for (i = 0; i < sizeof (linux_pg_size_arr)/sizeof (uint32_t); i++) {
+ linux_pg_size = linux_pg_size_arr[i];
+ seek_offset = linux_pg_size/sec_sz - 1;
+ seek_offset += part_start;
+
+ mutex_exit(CMLB_MUTEX(cl));
+ rval = DK_TG_READ(cl, buf, seek_offset, sec_sz, tg_cookie);
+ mutex_enter(CMLB_MUTEX(cl));
+
+ if (rval != 0) {
+ cmlb_dbg(CMLB_ERROR, cl,
+ "cmlb_is_linux_swap: disk read err\n");
+ rval = EIO;
+ break;
+ }
+
+ rval = -1;
+
+ if ((strncmp(linux_swap_magic, "SWAP-SPACE", 10) == 0) ||
+ (strncmp(linux_swap_magic, "SWAPSPACE2", 10) == 0)) {
+ /* Found a linux swap */
+ rval = 0;
+ break;
+ }
+ }
+
+ kmem_free(buf, sec_sz);
+ return (rval);
+}
+#endif
+
/*
* Function: cmlb_read_fdisk
*
@@ -1869,7 +2222,7 @@ cmlb_read_fdisk(struct cmlb_lun *cl, diskaddr_t capacity, void *tg_cookie)
struct ipart *fdp;
struct mboot *mbp;
struct ipart fdisk[FD_NUMPART];
- int i;
+ int i, k;
char sigbuf[2];
caddr_t bufp;
int uidx;
@@ -1878,6 +2231,13 @@ cmlb_read_fdisk(struct cmlb_lun *cl, diskaddr_t capacity, void *tg_cookie)
uint_t solaris_offset; /* offset to solaris part. */
daddr_t solaris_size; /* size of solaris partition */
uint32_t blocksize;
+#if defined(__i386) || defined(__amd64)
+ struct ipart eparts[2];
+ struct ipart *efdp1 = &eparts[0];
+ struct ipart *efdp2 = &eparts[1];
+ int ext_part_exists = 0;
+ int ld_count = 0;
+#endif
ASSERT(cl != NULL);
ASSERT(mutex_owned(CMLB_MUTEX(cl)));
@@ -1992,6 +2352,14 @@ cmlb_read_fdisk(struct cmlb_lun *cl, diskaddr_t capacity, void *tg_cookie)
for (fdp = fdisk, i = 0; i < FD_NUMPART; i++, fdp++) {
uint32_t relsect;
uint32_t numsect;
+ uchar_t systid;
+#if defined(__i386) || defined(__amd64)
+ /*
+ * Stores relative block offset from the beginning of the
+ * Extended Partition.
+ */
+ int ext_relsect = 0;
+#endif
if (fdp->numsect == 0) {
cl->cl_fmap[i].fmap_start = 0;
@@ -2007,6 +2375,96 @@ cmlb_read_fdisk(struct cmlb_lun *cl, diskaddr_t capacity, void *tg_cookie)
cl->cl_fmap[i].fmap_start = relsect;
cl->cl_fmap[i].fmap_nblk = numsect;
+ cl->cl_fmap[i].fmap_systid = LE_8(fdp->systid);
+
+#if defined(__i386) || defined(__amd64)
+ /* Support only one extended partition per LUN */
+ if ((fdp->systid == EXTDOS || fdp->systid == FDISK_EXTLBA) &&
+ (ext_part_exists == 0)) {
+ int j;
+ uint32_t logdrive_offset;
+ uint32_t ext_numsect;
+ uint32_t abs_secnum;
+ int is_linux_swap;
+
+ ext_part_exists = 1;
+
+ for (j = FD_NUMPART; j < FDISK_PARTS; j++) {
+ mutex_exit(CMLB_MUTEX(cl));
+ rval = DK_TG_READ(cl, bufp,
+ (relsect + ext_relsect), blocksize,
+ tg_cookie);
+ mutex_enter(CMLB_MUTEX(cl));
+
+ if (rval != 0) {
+ cmlb_dbg(CMLB_ERROR, cl,
+ "cmlb_read_fdisk: Extended "
+ "partition read err\n");
+ goto done;
+ }
+ /*
+ * The first ipart entry provides the offset
+ * at which the logical drive starts off from
+ * the beginning of the container partition
+ * and the size of the logical drive.
+ * The second ipart entry provides the offset
+ * of the next container partition from the
+ * beginning of the extended partition.
+ */
+ bcopy(&bufp[FDISK_PART_TABLE_START], eparts,
+ sizeof (eparts));
+ logdrive_offset = LE_32(efdp1->relsect);
+ ext_numsect = LE_32(efdp1->numsect);
+ systid = LE_8(efdp1->systid);
+ if (logdrive_offset <= 0 || ext_numsect <= 0)
+ break;
+ abs_secnum = relsect + ext_relsect +
+ logdrive_offset;
+
+ /* Boundary condition and overlap checking */
+ if (cmlb_validate_ext_part(cl, i, j, abs_secnum,
+ ext_numsect)) {
+ break;
+ }
+
+ if ((cl->cl_fmap[j].fmap_start != abs_secnum) ||
+ (cl->cl_fmap[j].fmap_nblk != ext_numsect) ||
+ (cl->cl_fmap[j].fmap_systid != systid)) {
+ /*
+ * Indicates change from previous
+ * partinfo. Need to recreate
+ * logical device nodes.
+ */
+ cl->cl_update_ext_minor_nodes = 1;
+ }
+ cl->cl_fmap[j].fmap_start = abs_secnum;
+ cl->cl_fmap[j].fmap_nblk = ext_numsect;
+ cl->cl_fmap[j].fmap_systid = systid;
+ ld_count++;
+
+ is_linux_swap = 0;
+ if (efdp1->systid == SUNIXOS) {
+ if (cmlb_is_linux_swap(cl, abs_secnum,
+ tg_cookie) == 0) {
+ is_linux_swap = 1;
+ }
+ }
+
+ if ((efdp1->systid == SUNIXOS) ||
+ (efdp1->systid == SUNIXOS2)) {
+ if ((uidx == -1) && (!is_linux_swap)) {
+ uidx = 0;
+ solaris_offset = abs_secnum;
+ solaris_size = ext_numsect;
+ }
+ }
+
+ if ((ext_relsect = LE_32(efdp2->relsect)) == 0)
+ break;
+ }
+ }
+
+#endif
if (fdp->systid != SUNIXOS &&
fdp->systid != SUNIXOS2 &&
@@ -2022,12 +2480,38 @@ cmlb_read_fdisk(struct cmlb_lun *cl, diskaddr_t capacity, void *tg_cookie)
* then use the first inactive solaris partition id
*/
if ((uidx == -1) || (fdp->bootid == ACTIVE)) {
- uidx = i;
- solaris_offset = relsect;
- solaris_size = numsect;
+#if defined(__i386) || defined(__amd64)
+ if (cmlb_is_linux_swap(cl, relsect, tg_cookie) != 0) {
+#endif
+ uidx = i;
+ solaris_offset = relsect;
+ solaris_size = numsect;
+#if defined(__i386) || defined(__amd64)
+ }
+#endif
}
}
-
+#if defined(__i386) || defined(__amd64)
+ if (ld_count < cl->cl_logical_drive_count) {
+ /*
+ * Some/all logical drives were deleted. Clear out
+ * the fmap entries correspoding to those deleted drives.
+ */
+ for (k = ld_count + FD_NUMPART;
+ k < cl->cl_logical_drive_count + FD_NUMPART; k++) {
+ cl->cl_fmap[k].fmap_start = 0;
+ cl->cl_fmap[k].fmap_nblk = 0;
+ cl->cl_fmap[k].fmap_systid = 0;
+ }
+ cl->cl_update_ext_minor_nodes = 1;
+ }
+ if (cl->cl_update_ext_minor_nodes) {
+ rval = cmlb_update_ext_minor_nodes(cl, ld_count);
+ if (rval != 0) {
+ goto done;
+ }
+ }
+#endif
cmlb_dbg(CMLB_INFO, cl, "fdisk 0x%x 0x%lx",
cl->cl_solaris_offset, cl->cl_solaris_size);
done:
@@ -4485,6 +4969,25 @@ cmlb_dkio_set_mboot(struct cmlb_lun *cl, caddr_t arg, int flag, void *tg_cookie)
}
+#if defined(__i386) || defined(__amd64)
+/*ARGSUSED*/
+static int
+cmlb_dkio_set_ext_part(struct cmlb_lun *cl, caddr_t arg, int flag,
+ void *tg_cookie)
+{
+ int fdisk_rval;
+ diskaddr_t capacity;
+
+ ASSERT(!mutex_owned(CMLB_MUTEX(cl)));
+
+ mutex_enter(CMLB_MUTEX(cl));
+ capacity = cl->cl_blockcount;
+ fdisk_rval = cmlb_read_fdisk(cl, capacity, tg_cookie);
+ mutex_exit(CMLB_MUTEX(cl));
+ return (fdisk_rval);
+}
+#endif
+
/*
* Function: cmlb_setup_default_geometry
*
@@ -4723,7 +5226,7 @@ no_solaris_partition:
* Note that dkl_cylno is not used for the fdisk map entries, so
* we set it to an entirely bogus value.
*/
- for (count = 0; count < FD_NUMPART; count++) {
+ for (count = 0; count < FDISK_PARTS; count++) {
cl->cl_map[FDISK_P1 + count].dkl_cylno = UINT32_MAX;
cl->cl_map[FDISK_P1 + count].dkl_nblk =
cl->cl_fmap[count].fmap_nblk;