Subject: [PATCH] libparted: mklabel to support EAV DASD From: Nageswara R Sastry Extended Address Volume (EAV) DASDs are ECKD DASDs with more than 65520 cylinders. This patch adds support for mklabel to properly handle unformatted EAV DASDs. Signed-off-by: Nageswara R Sastry --- include/parted/fdasd.h | 1 libparted/labels/fdasd.c | 92 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 3 deletions(-) --- a/include/parted/fdasd.h +++ b/include/parted/fdasd.h @@ -288,7 +288,6 @@ void fdasd_get_geometry (const PedDevice void fdasd_check_api_version (fdasd_anchor_t *anc, int fd); int fdasd_check_volume (fdasd_anchor_t *anc, int fd); int fdasd_write_labels (fdasd_anchor_t *anc, int fd); -int fdasd_invalid_vtoc_pointer(fdasd_anchor_t *anc); void fdasd_recreate_vtoc(fdasd_anchor_t *anc); partition_info_t * fdasd_add_partition (fdasd_anchor_t *anc, unsigned int start, unsigned int stop); --- a/libparted/labels/fdasd.c +++ b/libparted/labels/fdasd.c @@ -581,6 +581,22 @@ fdasd_recreate_vtoc (fdasd_anchor_t *anc anc->vtoc_changed++; } + /* + * initialize the VOL1 volume label + */ +static void +fdasd_init_volume_label(fdasd_anchor_t *anc, int fd) +{ + volume_label_t *vlabel = anc->vlabel; + + vtoc_volume_label_init(vlabel); + vtoc_volume_label_set_key(vlabel, "VOL1"); + vtoc_volume_label_set_label(vlabel, "VOL1"); + + vtoc_set_cchhb(&vlabel->vtoc, VTOC_START_CC, VTOC_START_HH, 0x01); +} + + /* * sets some important partition data * (like used, start_trk, end_trk, len_trk) @@ -769,6 +785,52 @@ fdasd_process_valid_vtoc (fdasd_anchor_t fdasd_update_partition_info (anc); } +static void +fdasd_invalid_vtoc_pointer(fdasd_anchor_t *anc) +{ + PDEBUG + anc->formatted_cylinders = anc->hw_cylinders; + anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads + - FIRST_USABLE_TRK; + vtoc_init_format4_label(anc->f4, USABLE_PARTITIONS, + anc->geo.cylinders, anc->formatted_cylinders, + anc->geo.heads, anc->geo.sectors, + anc->blksize, anc->dev_type); + + vtoc_init_format5_label(anc->f5); + vtoc_init_format7_label(anc->f7); + + vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '+', anc->verbose, + FIRST_USABLE_TRK, + anc->formatted_cylinders * anc->geo.heads - 1, + anc->formatted_cylinders, anc->geo.heads); + + vtoc_set_cchhb(&anc->vlabel->vtoc, VTOC_START_CC, VTOC_START_HH, 0x01); +} + +/* + * we have a invalid FMT4 DSCB and therefore we will re-create the VTOC + */ +static void +fdasd_process_invalid_vtoc(fdasd_anchor_t *anc) +{ + anc->formatted_cylinders = anc->hw_cylinders; + anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads + - FIRST_USABLE_TRK; + vtoc_init_format4_label(anc->f4, USABLE_PARTITIONS, + anc->geo.cylinders, anc->formatted_cylinders, + anc->geo.heads, anc->geo.sectors, + anc->blksize, anc->dev_type); + + vtoc_init_format5_label(anc->f5); + vtoc_init_format7_label(anc->f7); + vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '+', anc->verbose, + FIRST_USABLE_TRK, + anc->formatted_cylinders * anc->geo.heads - 1, + anc->formatted_cylinders, anc->geo.heads); +} + + static int fdasd_valid_vtoc_pointer(fdasd_anchor_t *anc, unsigned long b, int fd) { @@ -781,6 +843,8 @@ fdasd_valid_vtoc_pointer(fdasd_anchor_t if (anc->f4->DS4IDFMT == 0xf4) { fdasd_process_valid_vtoc (anc, b, fd); return 0; + } else { + fdasd_process_invalid_vtoc(anc); } if (strncmp(anc->vlabel->volkey, vtoc_ebcdic_enc("LNX1",str,4),4) == 0 || strncmp(anc->vlabel->volkey, vtoc_ebcdic_enc("CMS1",str,4),4) == 0) @@ -817,13 +881,37 @@ fdasd_check_volume (fdasd_anchor_t *anc, else return 0; } else { - return 1; + fdasd_invalid_vtoc_pointer(anc); } } else if (strncmp (v->volkey, vtoc_ebcdic_enc ("LNX1", str, 4), 4) == 0 || strncmp (v->volkey, vtoc_ebcdic_enc ("CMS1", str, 4), 4) == 0) { return 0; + } else if (anc->FBA_layout == 1) { + /* Some times LDL formatted disks does not + contain any volume label */ + return 1; + } else { + /* didn't find VOL1 volume label */ + anc->formatted_cylinders = anc->hw_cylinders; + anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads + - FIRST_USABLE_TRK; + + fdasd_init_volume_label(anc, fd); + + vtoc_init_format4_label(anc->f4, USABLE_PARTITIONS, + anc->geo.cylinders, anc->formatted_cylinders, + anc->geo.heads, anc->geo.sectors, + anc->blksize, anc->dev_type); + + vtoc_init_format5_label(anc->f5); + vtoc_init_format7_label(anc->f7); + + vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '+', + anc->verbose, FIRST_USABLE_TRK, + anc->formatted_cylinders * anc->geo.heads - 1, + anc->formatted_cylinders, anc->geo.heads); + return 0; } - return 1; }