From: Wang Dong <dongdwdw@linux.vnet.ibm.com>
Date: Wed, 26 Oct 2016 04:22:46 +0200
Subject: libparted/dasd: unify vtoc handling for cdl/ldl
References: fate#321531
Patch-mainline: v3.3
Git-commit: 4f25d54d4d2bd6ae12d56b5a97ed2b7f60f753e9

Merge volume label cdl and ldl. It is convenient to manipulate
the same structure. Also remove unused arguments in the functions.

Signed-off-by: Wang Dong <dongdwdw@linux.vnet.ibm.com>
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: Brian C. Lane <bcl@redhat.com>
Acked-by: Sebastian Parschauer <sparschauer@suse.de>
---
 include/parted/vtoc.in.h | 34 +++++++++++++++++++---------------
 libparted/labels/dasd.c  |  8 +++-----
 libparted/labels/vtoc.c  | 38 +++++++++++++++++---------------------
 3 files changed, 39 insertions(+), 41 deletions(-)

--- a/include/parted/vtoc.in.h
+++ b/include/parted/vtoc.in.h
@@ -62,7 +62,6 @@ typedef struct cchh             cchh_t;
 typedef struct labeldate        labeldate_t;
 typedef struct volume_label     volume_label_t;
 typedef struct cms_volume_label cms_volume_label_t;
-typedef struct ldl_volume_label ldl_volume_label_t;
 typedef struct extent           extent_t;
 typedef struct dev_const        dev_const_t;
 typedef struct format1_label    format1_label_t;
@@ -94,6 +93,19 @@ struct __attribute__ ((packed)) labeldat
         u_int16_t day;
 };
 
+/*
+ * The following structure is a merger of the cdl and ldl volume label.
+ * On an ldl disk there is no key information, so when reading an
+ * ldl label from disk, the data should be copied at the address of vollbl.
+ * On the other side, the field ldl_version is reserved in a cdl record
+ * and the field formatted_blocks exists only for ldl labels. So when
+ * reading a cdl label from disk, the formatted_blocks field will contain
+ * arbitrary data.
+ * This layout may be a bit awkward, but the advantage of having the
+ * same label type for both disk layout types is bigger than the effort
+ * for taking a bit of extra care at the fringes.
+ */
+
 struct __attribute__ ((packed)) volume_label {
 	char volkey[4];         /* volume key = volume label                 */
 	char vollbl[4];	        /* volume label ("VOL1" in EBCDIC)           */
@@ -107,15 +119,8 @@ struct __attribute__ ((packed)) volume_l
 	char labperci[4];       /* no of labels per CI (FBA), blanks for CKD */
 	char res2[4];	        /* reserved                                  */
 	char lvtoc[14];	        /* owner code for LVTOC                      */
-	char res3[29];	        /* reserved                                  */
-        char fudge[4];          /* filler to match length of ldl label       */
-};
-
-struct __attribute__ ((packed)) ldl_volume_label {
-	char vollbl[4];         /* Label identifier ("LNX1" in EBCDIC)       */
-        char volid[6];          /* Volume identifier                         */
-        char res3[69];          /* Reserved field                            */
-        char ldl_version[1];    /* Version number, valid for ldl format      */
+        char res3[28];	        /* reserved                                  */
+        char ldl_version;       /* version number, valid for ldl format      */
         u_int64_t formatted_blocks;  /* valid when ldl_version >= "2" (in
                                         EBCDIC)                              */
 };
@@ -335,11 +340,10 @@ void vtoc_write_label (int fd, unsigned
                        format7_label_t const *f7,
                        format9_label_t const *f9);
 
-void vtoc_init_format1_label (char *volid, unsigned int blksize,
+void vtoc_init_format1_label (unsigned int blksize,
                               extent_t *part_extent, format1_label_t *f1);
 
 void vtoc_init_format4_label (format4_label_t *f4lbl,
-                              unsigned int usable_partitions,
                               unsigned int compat_cylinders,
                               unsigned int real_cylinders,
                               unsigned int tracks,
@@ -352,11 +356,11 @@ void vtoc_update_format4_label (format4_
 
 void vtoc_init_format5_label (format5_label_t *f5);
 
-void vtoc_update_format5_label_add (format5_label_t *f5, int verbose, int cyl,
+void vtoc_update_format5_label_add (format5_label_t *f5, int verbose,
                                     int trk, u_int16_t a, u_int16_t b,
                                     u_int8_t c);
 
-void vtoc_update_format5_label_del (format5_label_t *f5, int verbose, int cyl,
+void vtoc_update_format5_label_del (format5_label_t *f5, int verbose,
                                     int trk, u_int16_t a, u_int16_t b,
                                     u_int8_t c);
 
@@ -368,7 +372,7 @@ void vtoc_update_format7_label_add (form
 void vtoc_update_format7_label_del (format7_label_t *f7, int verbose,
                                     u_int32_t a, u_int32_t b);
 
-void vtoc_init_format8_label (char *volid, unsigned int blksize,
+void vtoc_init_format8_label (unsigned int blksize,
                               extent_t *part_extent, format1_label_t *f1);
 
 void vtoc_update_format8_label (cchhb_t *associated_f9, format1_label_t *f8);
--- a/libparted/labels/dasd.c
+++ b/libparted/labels/dasd.c
@@ -341,13 +341,12 @@ dasd_read (PedDisk* disk)
 		DasdPartitionData* dasd_data;
 
 		union vollabel {
-			volume_label_t unused;
-			ldl_volume_label_t ldl;
+			volume_label_t ldl;
 			cms_volume_label_t cms;
 		};
 		union vollabel *cms_ptr1 = (union vollabel *) anchor.vlabel;
 		cms_volume_label_t *cms_ptr = &cms_ptr1->cms;
-		ldl_volume_label_t *ldl_ptr = &cms_ptr1->ldl;
+		volume_label_t *ldl_ptr = &cms_ptr1->ldl;
 		int partition_start_block;
 
 		disk_specific->format_type = 1;
@@ -371,8 +370,7 @@ dasd_read (PedDisk* disk)
 				* (long long) cms_ptr->disk_offset;
 
 		if (is_ldl)
-		   if (strncmp(ldl_ptr->ldl_version,
-			       vtoc_ebcdic_enc("2", str, 1), 1) >= 0)
+		   if (ldl_ptr->ldl_version >= 0xf2)
 		      end = (long long) arch_specific->real_sector_size
 			    / (long long) disk->dev->sector_size
 			    * (long long) ldl_ptr->formatted_blocks - 1;
--- a/libparted/labels/vtoc.c
+++ b/libparted/labels/vtoc.c
@@ -150,7 +150,7 @@ enum failure {
 	unable_to_read
 };
 
-static char buffer[89];
+static char buffer[93];
 
 static void
 vtoc_error (enum failure why, char const *s1, char const *s2)
@@ -329,7 +329,7 @@ void
 vtoc_volume_label_init (volume_label_t *vlabel)
 {
 	PDEBUG
-	sprintf(buffer, "%88s", " ");
+	sprintf(buffer, "%92s", " ");
 	vtoc_ebcdic_enc(buffer, buffer, sizeof *vlabel);
 	memcpy(vlabel, buffer, sizeof *vlabel);
 }
@@ -348,8 +348,8 @@ vtoc_read_volume_label (int f, unsigned
 	typedef union vollabel vollabel_t;
 
 	union __attribute__((packed)) vollabel {
+		/* cdl and ldl have the same data struct */
 		volume_label_t cdl;
-		ldl_volume_label_t ldl;
 		cms_volume_label_t cms;
 	};
 
@@ -373,9 +373,7 @@ vtoc_read_volume_label (int f, unsigned
 	}
 
 	rc = read(f, vlabel, sizeof(volume_label_t));
-	if (rc != sizeof(volume_label_t) &&
-	/* For CDL we ask to read 88 bytes, but only get 84 */
-            rc != sizeof(volume_label_t) - 4) {
+	if (rc != sizeof(volume_label_t)) {
 		vtoc_error(unable_to_read, "vtoc_read_volume_label",
 			   _("Could not read volume label."));
 		return 1;
@@ -427,10 +425,8 @@ vtoc_write_volume_label (int f, unsigned
 		vtoc_error(unable_to_seek, "vtoc_write_volume_label",
 			   _("Could not write volume label."));
 
-	rc = write(f, vlabel, sizeof(volume_label_t) - 4);
-	/* Subtract 4 to leave off the "fudge" variable when writing.
-           We only write CDL volume labels, never LDL or CMS.  */
-	if (rc != sizeof(volume_label_t) - 4)
+	rc = write(f, vlabel, sizeof(volume_label_t));
+	if (rc != sizeof(volume_label_t))
 		vtoc_error(unable_to_write, "vtoc_write_volume_label",
 			   _("Could not write volume label."));
 
@@ -632,7 +628,7 @@ vtoc_write_label (int f, unsigned long p
  * initializes a format4 label
  */
 void
-vtoc_init_format4_label (format4_label_t *f4, unsigned int usable_partitions,
+vtoc_init_format4_label (format4_label_t *f4,
                          unsigned int compat_cylinders,
                          unsigned int real_cylinders, unsigned int tracks,
                          unsigned int blocks, unsigned int blksize,
@@ -740,7 +736,7 @@ vtoc_init_format7_label (format7_label_t
  * format1 or format 8 label, all but the field DS1FMTID
  */
 void
-vtoc_init_format_1_8_label (char *volid, unsigned int blksize,
+vtoc_init_format_1_8_label (unsigned int blksize,
                             extent_t *part_extent, format1_label_t *f1)
 {
 	PDEBUG
@@ -794,18 +790,18 @@ vtoc_init_format_1_8_label (char *volid,
 }
 
 void
-vtoc_init_format1_label (char *volid, unsigned int blksize,
+vtoc_init_format1_label (unsigned int blksize,
                          extent_t *part_extent, format1_label_t *f1)
 {
-	vtoc_init_format_1_8_label(volid, blksize, part_extent, f1);
+	vtoc_init_format_1_8_label(blksize, part_extent, f1);
 	f1->DS1FMTID = 0xf1;
 }
 
 void
-vtoc_init_format8_label (char *volid, unsigned int blksize,
+vtoc_init_format8_label (unsigned int blksize,
                          extent_t *part_extent, format1_label_t *f8)
 {
-	vtoc_init_format_1_8_label(volid, blksize, part_extent, f8);
+	vtoc_init_format_1_8_label(blksize, part_extent, f8);
 	f8->DS1FMTID = 0xf8;
 }
 
@@ -886,7 +882,7 @@ vtoc_reorganize_FMT5_extents (format5_la
  * add a free space extent description to the VTOC FMT5 DSCB
  */
 void
-vtoc_update_format5_label_add (format5_label_t *f5, int verbose, int cyl,
+vtoc_update_format5_label_add (format5_label_t *f5, int verbose,
                                int trk, u_int16_t a, u_int16_t b, u_int8_t c)
 {
 	PDEBUG
@@ -974,7 +970,7 @@ vtoc_update_format5_label_add (format5_l
  * remove a free space extent description from the VTOC FMT5 DSCB
  */
 void
-vtoc_update_format5_label_del (format5_label_t *f5, int verbose, int cyl,
+vtoc_update_format5_label_del (format5_label_t *f5, int verbose,
                                int trk, u_int16_t a, u_int16_t b, u_int8_t c)
 {
 	PDEBUG
@@ -1054,7 +1050,7 @@ vtoc_update_format5_label_del (format5_l
 			ext->ft = (a - ext->t) % trk;
 
 			vtoc_update_format5_label_add(f5, verbose,
-						      cyl, trk, x, y, z);
+						      trk, x, y, z);
 
 			if (verbose)
 				puts ("FMT5 del extent: 2 pieces");
@@ -1322,9 +1318,9 @@ vtoc_set_freespace(format4_label_t *f4,
 		z =  (u_int8_t) ((stop - start + 1) % trk);
 
 		if (ch == '+')
-			vtoc_update_format5_label_add(f5, verbose, cyl, trk, x, y, z);
+			vtoc_update_format5_label_add(f5, verbose, trk, x, y, z);
 		else if (ch == '-')
-			vtoc_update_format5_label_del(f5, verbose, cyl, trk, x, y, z);
+			vtoc_update_format5_label_del(f5, verbose, trk, x, y, z);
 		else
 			puts ("BUG: syntax error in vtoc_set_freespace call");
 
