[parted/f18] - change partition UUID to use partX-UUID (#858704) - fixup losetup usage in tests - add support for
Brian C. Lane
bcl at fedoraproject.org
Tue Oct 16 23:54:49 UTC 2012
commit 68f2aab138cd95a9aa657720ae0c3af02f979f96
Author: Brian C. Lane <bcl at redhat.com>
Date: Tue Oct 16 16:53:14 2012 -0700
- change partition UUID to use partX-UUID (#858704)
- fixup losetup usage in tests
- add support for implicit FBA DASD partitions (#707027)
- add support for EAV DASD partitions (#707032)
...arted-add-support-for-EAV-DASD-partitions.patch | 1058 ++++++++++++++++++++
...-support-for-implicit-FBA-DASD-partitions.patch | 187 ++++
...parted-preserve-the-uuid-on-dm-partitions.patch | 14 +-
...1-tests-Make-sure-dm-UUIDs-are-not-erased.patch | 2 +-
parted-3.1-tests-cleanup-losetup-usage.patch | 137 +++
parted.spec | 11 +-
6 files changed, 1400 insertions(+), 9 deletions(-)
---
diff --git a/parted-3.1-libparted-add-support-for-EAV-DASD-partitions.patch b/parted-3.1-libparted-add-support-for-EAV-DASD-partitions.patch
new file mode 100644
index 0000000..81f73a8
--- /dev/null
+++ b/parted-3.1-libparted-add-support-for-EAV-DASD-partitions.patch
@@ -0,0 +1,1058 @@
+Subject: [PATCH] libparted: add support for EAV DASD partitions
+
+From: Nageswara R Sastry <rnsastry at linux.vnet.ibm.com>
+
+Extended Address Volume (EAV) DASDs are ECKD DASDs with more than
+65520 cylinders. This patch adds support for recognizing and
+modifying partitions on EAV DASDs to Parted. The changes are
+based on the EAV support added to version 1.8.1 [1] of the
+s390-tools package.
+
+[1] http://www.ibm.com/developerworks/linux/linux390/s390-tools-1.8.1.html
+
+Signed-off-by: Nageswara R Sastry <rnsastry at linux.vnet.ibm.com>
+Signed-off-by: Peter Oberparleiter <oberpar at linux.vnet.ibm.com>
+
+---
+ include/parted/fdasd.h | 89 ++++++++++++++++--
+ include/parted/vtoc.h | 58 ++++++++++--
+ libparted/labels/dasd.c | 1
+ libparted/labels/fdasd.c | 226 ++++++++++++++++++++++++++++++++---------------
+ libparted/labels/vtoc.c | 173 ++++++++++++++++++++++++++++++-----
+ 5 files changed, 435 insertions(+), 112 deletions(-)
+
+--- a/include/parted/fdasd.h
++++ b/include/parted/fdasd.h
+@@ -74,6 +74,80 @@ typedef struct dasd_information_t {
+ char configuration_data[256]; /* from read_configuration_data */
+ } dasd_information_t;
+
++struct dasd_eckd_characteristics {
++ unsigned short cu_type;
++ struct {
++ unsigned char support:2;
++ unsigned char async:1;
++ unsigned char reserved:1;
++ unsigned char cache_info:1;
++ unsigned char model:3;
++ } __attribute__ ((packed)) cu_model;
++ unsigned short dev_type;
++ unsigned char dev_model;
++ struct {
++ unsigned char mult_burst:1;
++ unsigned char RT_in_LR:1;
++ unsigned char reserved1:1;
++ unsigned char RD_IN_LR:1;
++ unsigned char reserved2:4;
++ unsigned char reserved3:8;
++ unsigned char defect_wr:1;
++ unsigned char XRC_supported:1;
++ unsigned char reserved4:1;
++ unsigned char striping:1;
++ unsigned char reserved5:4;
++ unsigned char cfw:1;
++ unsigned char reserved6:2;
++ unsigned char cache:1;
++ unsigned char dual_copy:1;
++ unsigned char dfw:1;
++ unsigned char reset_alleg:1;
++ unsigned char sense_down:1;
++ } __attribute__ ((packed)) facilities;
++ unsigned char dev_class;
++ unsigned char unit_type;
++ unsigned short no_cyl;
++ unsigned short trk_per_cyl;
++ unsigned char sec_per_trk;
++ unsigned char byte_per_track[3];
++ unsigned short home_bytes;
++ unsigned char formula;
++ union {
++ struct {
++ unsigned char f1;
++ unsigned short f2;
++ unsigned short f3;
++ } __attribute__ ((packed)) f_0x01;
++ struct {
++ unsigned char f1;
++ unsigned char f2;
++ unsigned char f3;
++ unsigned char f4;
++ unsigned char f5;
++ } __attribute__ ((packed)) f_0x02;
++ } __attribute__ ((packed)) factors;
++ unsigned short first_alt_trk;
++ unsigned short no_alt_trk;
++ unsigned short first_dia_trk;
++ unsigned short no_dia_trk;
++ unsigned short first_sup_trk;
++ unsigned short no_sup_trk;
++ unsigned char MDR_ID;
++ unsigned char OBR_ID;
++ unsigned char director;
++ unsigned char rd_trk_set;
++ unsigned short max_rec_zero;
++ unsigned char reserved1;
++ unsigned char RWANY_in_LR;
++ unsigned char factor6;
++ unsigned char factor7;
++ unsigned char factor8;
++ unsigned char reserved2[3];
++ unsigned char reserved3[6];
++ unsigned int long_no_cyl;
++} __attribute__ ((packed));
++
+ /*
+ * struct format_data_t
+ * represents all data necessary to format a dasd
+@@ -116,18 +190,6 @@ typedef struct format_data_t {
+ #define BLKRRPART _IO(0x12,95)
+ /* get block device sector size */
+ #define BLKSSZGET _IO(0x12,104)
+-
+-/*****************************************************************************
+- * SECTION: Definition from hdreq.h *
+- *****************************************************************************/
+-
+-struct fdasd_hd_geometry {
+- unsigned char heads;
+- unsigned char sectors;
+- unsigned short cylinders;
+- unsigned long start;
+-};
+-
+ /* get device geometry */
+ #define HDIO_GETGEO 0x0301
+
+@@ -189,10 +251,13 @@ typedef struct fdasd_anchor {
+ format4_label_t *f4;
+ format5_label_t *f5;
+ format7_label_t *f7;
++ format9_label_t *f9; /* template for all f9 labels */
+ partition_info_t *first;
+ partition_info_t *last;
+ volume_label_t *vlabel;
+ config_data_t confdata[USABLE_PARTITIONS];
++ u_int32_t hw_cylinders;
++ u_int32_t formatted_cylinders;
+ struct fdasd_hd_geometry geo;
+ unsigned int label_block;
+ unsigned int FBA_layout;
+--- a/include/parted/vtoc.h
++++ b/include/parted/vtoc.h
+@@ -42,7 +42,18 @@
+
+ #define VOLSER_LENGTH 6
+ #define BIG_DISK_SIZE 0x10000
++#define LV_COMPAT_CYL 0xFFFE
+
++/*****************************************************************************
++ * SECTION: Definition from hdreq.h *
++ *****************************************************************************/
++
++struct fdasd_hd_geometry {
++ unsigned char heads;
++ unsigned char sectors;
++ unsigned short cylinders;
++ unsigned long start;
++};
+
+ typedef struct ttr ttr_t;
+ typedef struct cchhb cchhb_t;
+@@ -59,6 +70,7 @@ typedef struct ds5ext ds5ext_t
+ typedef struct format5_label format5_label_t;
+ typedef struct ds7ext ds7ext_t;
+ typedef struct format7_label format7_label_t;
++typedef struct format9_label format9_label_t;
+
+ struct __attribute__ ((packed)) ttr {
+ u_int16_t tt;
+@@ -169,6 +181,10 @@ struct __attribute__ ((packed)) dev_cons
+ u_int8_t DS4DEVDB; /* number of directory blocks per track */
+ };
+
++/*
++ * format 1 and format 8 label have the same layout so we use the following
++ * structure for both.
++ */
+ struct __attribute__ ((packed)) format1_label {
+ char DS1DSNAM[44]; /* data set name */
+ u_int8_t DS1FMTID; /* format identifier */
+@@ -229,7 +245,11 @@ struct __attribute__ ((packed)) format4_
+ char res2[10]; /* reserved */
+ u_int8_t DS4EFLVL; /* extended free-space management level */
+ cchhb_t DS4EFPTR; /* pointer to extended free-space info */
+- char res3[9]; /* reserved */
++ char res3; /* reserved */
++ u_int32_t DS4DCYL; /* number of logical cyls */
++ char res4[2]; /* reserved */
++ u_int8_t DS4DEVF2; /* device flags */
++ char res5; /* reserved */
+ };
+
+ struct __attribute__ ((packed)) ds5ext {
+@@ -261,12 +281,28 @@ struct __attribute__ ((packed)) format7_
+ cchhb_t DS7PTRDS; /* pointer to next FMT7 DSCB */
+ };
+
++struct __attribute__ ((packed)) format9_label {
++ u_int8_t DS9KEYID; /* key code for format 9 labels (0x09) */
++ u_int8_t DS9SUBTY; /* subtype (0x01) */
++ u_int8_t DS9NUMF9; /* number of F9 datasets */
++ u_int8_t res1[41]; /* reserved */
++ u_int8_t DS9FMTID; /* format identifier */
++ u_int8_t res2[95]; /* reserved */
++};
++
+ char *vtoc_ebcdic_enc (char const *source, char *target, int l);
+ char *vtoc_ebcdic_dec (char const *source, char *target, int l);
+ void vtoc_set_extent (extent_t *ext, u_int8_t typeind, u_int8_t seqno,
+ cchh_t *lower, cchh_t *upper);
+-void vtoc_set_cchh (cchh_t *addr, u_int16_t cc, u_int16_t hh);
+-void vtoc_set_cchhb (cchhb_t *addr, u_int16_t cc, u_int16_t hh, u_int8_t b);
++void vtoc_set_cchh (cchh_t *addr, u_int32_t cc, u_int16_t hh);
++u_int32_t vtoc_get_cyl_from_cchh(cchh_t *addr);
++u_int16_t vtoc_get_head_from_cchh(cchh_t *addr);
++void vtoc_set_cchhb (cchhb_t *addr, u_int32_t cc, u_int16_t hh, u_int8_t b);
++u_int32_t vtoc_get_cyl_from_cchhb(cchhb_t *addr);
++u_int16_t vtoc_get_head_from_cchhb(cchhb_t *addr);
++u_int64_t cchhb2blk(cchhb_t *p, struct fdasd_hd_geometry *geo);
++u_int64_t cchh2blk (cchh_t *p, struct fdasd_hd_geometry *geo);
++u_int32_t cchh2trk (cchh_t *p, struct fdasd_hd_geometry *geo);
+ void vtoc_set_date (labeldate_t *d, u_int8_t year, u_int16_t day);
+
+ void vtoc_volume_label_init (volume_label_t *vlabel);
+@@ -295,14 +331,16 @@ void vtoc_write_label (int fd, unsigned
+ format1_label_t const *f1,
+ format4_label_t const *f4,
+ format5_label_t const *f5,
+- format7_label_t const *f7);
++ format7_label_t const *f7,
++ format9_label_t const *f9);
+
+ void vtoc_init_format1_label (char *volid, 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 cylinders,
++ unsigned int compat_cylinders,
++ unsigned int real_cylinders,
+ unsigned int tracks,
+ unsigned int blocks,
+ unsigned int blksize,
+@@ -329,8 +367,16 @@ 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,
++ extent_t *part_extent, format1_label_t *f1);
++
++void vtoc_update_format8_label (cchhb_t *associated_f9, format1_label_t *f8);
++
++void vtoc_init_format9_label (format9_label_t *f9);
++
+ void vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
+ format7_label_t *f7, char ch, int verbose,
+- u_int32_t start, u_int32_t stop, int cyl, int trk);
++ u_int32_t start, u_int32_t stop, u_int32_t cyl,
++ u_int32_t trk);
+
+ #endif /* VTOC_H */
+--- a/libparted/labels/dasd.c
++++ b/libparted/labels/dasd.c
+@@ -631,6 +631,7 @@ dasd_write (const PedDisk* disk)
+ /* initialize the anchor */
+ fdasd_initialize_anchor(&anchor);
+ fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
++ fdasd_check_volume(&anchor, arch_specific->fd);
+ memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t));
+ anchor.vlabel_changed++;
+
+--- a/libparted/labels/fdasd.c
++++ b/libparted/labels/fdasd.c
+@@ -59,6 +59,48 @@ setpos (fdasd_anchor_t *anc, int dsn, in
+ anc->partno[dsn] = pos;
+ }
+
++static u_int32_t
++get_usable_cylinders (fdasd_anchor_t *anc)
++{
++ u_int32_t cyl;
++
++ /* large volume */
++ if (anc->f4->DS4DEVCT.DS4DSCYL == LV_COMPAT_CYL &&
++ anc->f4->DS4DCYL > anc->f4->DS4DEVCT.DS4DSCYL)
++ return anc->f4->DS4DCYL;
++ /* normal volume */
++ if (anc->f4->DS4DEVCT.DS4DEVFG & ALTERNATE_CYLINDERS_USED)
++ cyl = anc->f4->DS4DEVCT.DS4DSCYL -
++ (u_int16_t) anc->f4->DS4DEVAC;
++ else
++ cyl = anc->f4->DS4DEVCT.DS4DSCYL;
++ return cyl;
++}
++
++static void
++get_addr_of_highest_f1_f8_label (fdasd_anchor_t *anc, cchhb_t *addr)
++{
++
++ u_int8_t record;
++ /* We have to count the follwing labels:
++ * one format 4
++ * one format 5
++ * format 7 only if we have moren then BIG_DISK_SIZE tracks
++ * one for each format 1 or format 8 label == one for each partition
++ * one for each format 9 label before the last format 8
++ * We assume that all partitions use format 8 labels when
++ * anc->formatted_cylinders > LV_COMPAT_CYL
++ * Note: Record zero is special, so block 0 on our disk is record 1!
++ */
++
++ record = anc->used_partitions + 2;
++ if (anc->big_disk)
++ record++;
++ if (anc->formatted_cylinders > LV_COMPAT_CYL)
++ record += anc->used_partitions - 1;
++ vtoc_set_cchhb(addr, VTOC_START_CC, VTOC_START_HH, record);
++}
++
+ void
+ fdasd_cleanup (fdasd_anchor_t *anchor)
+ {
+@@ -72,6 +114,7 @@ fdasd_cleanup (fdasd_anchor_t *anchor)
+ free(anchor->f4);
+ free(anchor->f5);
+ free(anchor->f7);
++ free(anchor->f9);
+ free(anchor->vlabel);
+
+ p = anchor->first;
+@@ -82,6 +125,7 @@ fdasd_cleanup (fdasd_anchor_t *anchor)
+ if (p == NULL)
+ return;
+ q = p->next;
++ free(p->f1);
+ free(p);
+ p = q;
+ }
+@@ -154,17 +198,6 @@ fdasd_error (fdasd_anchor_t *anc, enum f
+ }
+
+ /*
+- * converts cyl-cyl-head-head-blk to blk
+- */
+-static unsigned long
+-cchhb2blk (cchhb_t *p, struct fdasd_hd_geometry *geo)
+-{
+- PDEBUG
+- return (unsigned long) (p->cc * geo->heads * geo->sectors
+- + p->hh * geo->sectors + p->b);
+-}
+-
+-/*
+ * initializes the anchor structure and allocates some
+ * memory for the labels
+ */
+@@ -216,9 +249,16 @@ fdasd_initialize_anchor (fdasd_anchor_t
+ if (anc->f7 == NULL)
+ fdasd_error(anc, malloc_failed, "FMT7 DSCB.");
+
++ /* template for all format 9 labels */
++ anc->f9 = malloc(sizeof(format9_label_t));
++ if (anc->f9 == NULL)
++ fdasd_error(anc, malloc_failed, "FMT9 DSCB.");
++
+ bzero(anc->f4, sizeof(format4_label_t));
+ bzero(anc->f5, sizeof(format5_label_t));
+ bzero(anc->f7, sizeof(format7_label_t));
++ bzero(anc->f9, sizeof(format9_label_t));
++ vtoc_init_format9_label(anc->f9);
+
+ v = malloc(sizeof(volume_label_t));
+ if (v == NULL)
+@@ -259,6 +299,8 @@ fdasd_initialize_anchor (fdasd_anchor_t
+
+ q = p;
+ }
++ anc->hw_cylinders = 0;
++ anc->formatted_cylinders = 0;
+ }
+
+ /*
+@@ -269,44 +311,46 @@ fdasd_write_vtoc_labels (fdasd_anchor_t
+ {
+ PDEBUG
+ partition_info_t *p;
+- unsigned long b;
++ unsigned long b, maxblk;
+ char dsno[6], s1[7], s2[45], *c1, *c2, *ch;
+ int i = 0, k = 0;
++ cchhb_t f9addr;
++ format1_label_t emptyf1;
+
+ b = (cchhb2blk (&anc->vlabel->vtoc, &anc->geo) - 1) * anc->blksize;
+ if (b <= 0)
+ fdasd_error (anc, vlabel_corrupted, "");
++ maxblk = b + anc->blksize * 9; /* f4+f5+f7+3*f8+3*f9 */
+
+ /* write FMT4 DSCB */
+- vtoc_write_label (fd, b, NULL, anc->f4, NULL, NULL);
++ vtoc_write_label (fd, b, NULL, anc->f4, NULL, NULL, NULL);
++ b += anc->blksize;
+
+ /* write FMT5 DSCB */
++ vtoc_write_label (fd, b, NULL, NULL, anc->f5, NULL, NULL);
+ b += anc->blksize;
+- vtoc_write_label (fd, b, NULL, NULL, anc->f5, NULL);
+
+ /* write FMT7 DSCB */
+ if (anc->big_disk) {
++ vtoc_write_label (fd, b, NULL, NULL, NULL, anc->f7, NULL);
+ b += anc->blksize;
+- vtoc_write_label (fd, b, NULL, NULL, NULL, anc->f7);
+ }
+
+- /* loop over all FMT1 DSCBs */
+- p = anc->first;
+- for (i = 0; i < USABLE_PARTITIONS; i++) {
+- b += anc->blksize;
++ /* loop over all partitions (format 1 or format 8 DCB) */
++ for (p = anc->first; p != NULL; p = p->next) {
+
+ if (p->used != 0x01) {
+- vtoc_write_label (fd, b, p->f1, NULL, NULL, NULL);
+ continue;
+ }
+
++ i++;
+ strncpy (p->f1->DS1DSSN, anc->vlabel->volid, 6);
+
+ ch = p->f1->DS1DSNAM;
+ vtoc_ebcdic_dec (ch, ch, 44);
+ c1 = ch + 7;
+
+- if (getdsn (anc, i) > -1) {
++ if (getdsn (anc, i-1) > -1) {
+ /* re-use the existing data set name */
+ c2 = strchr (c1, '.');
+ if (c2 != NULL)
+@@ -325,11 +369,7 @@ fdasd_write_vtoc_labels (fdasd_anchor_t
+ while (getpos (anc, k) > -1)
+ k++;
+
+- setpos (anc, k, i);
+-
+- strncpy (s2, ch, 44);
+- s2[44] = 0;
+- vtoc_ebcdic_dec (s2, s2, 44);
++ setpos (anc, k, i-1);
+
+ strncpy (ch, "LINUX.V " " ", 44);
+
+@@ -366,8 +406,32 @@ fdasd_write_vtoc_labels (fdasd_anchor_t
+
+ vtoc_ebcdic_enc (ch, ch, 44);
+
+- vtoc_write_label (fd, b, p->f1, NULL, NULL, NULL);
+- p = p->next;
++ if (p->f1->DS1FMTID == 0xf8 ) {
++ /* Now as we know where which label will be written, we
++ * can add the address of the format 9 label to the
++ * format 8 label. The f9 record will be written to the
++ * block after the current blk. Remember: records are of
++ * by one, so we have to add 2 and not just one.
++ */
++ vtoc_set_cchhb(&f9addr, VTOC_START_CC, VTOC_START_HH,
++ ((b / anc->blksize) % anc->geo.sectors) + 2);
++ vtoc_update_format8_label(&f9addr, p->f1);
++ vtoc_write_label(fd, b, p->f1, NULL, NULL, NULL, NULL);
++ b += anc->blksize;
++ vtoc_write_label(fd, b, NULL, NULL, NULL, NULL,
++ anc->f9);
++ b += anc->blksize;
++ } else {
++ vtoc_write_label(fd, b, p->f1, NULL, NULL, NULL, NULL);
++ b += anc->blksize;
++ }
++ }
++
++ /* write empty labels to the rest of the blocks */
++ bzero(&emptyf1, sizeof(emptyf1));
++ while (b < maxblk) {
++ vtoc_write_label(fd, b, &emptyf1, NULL, NULL, NULL, NULL);
++ b += anc->blksize;
+ }
+ }
+
+@@ -394,20 +458,25 @@ int
+ fdasd_prepare_labels (fdasd_anchor_t *anc, int fd)
+ {
+ PDEBUG
+- partition_info_t *p = anc->first;
++ partition_info_t *p;
+ char dsno[6], s1[7], s2[45], *c1, *c2, *ch;
+ int i = 0, k = 0;
+
+- /* loop over all FMT1 DSCBs */
+- p = anc->first;
+- for (i = 0; i < USABLE_PARTITIONS; i++) {
++ /* loop over all partitions (format 1 or format 8 DCB) */
++ for (p = anc->first; p != NULL; p = p->next) {
++
++ if (p->used != 0x01) {
++ continue;
++ }
++
++ i++;
+ strncpy (p->f1->DS1DSSN, anc->vlabel->volid, 6);
+
+ ch = p->f1->DS1DSNAM;
+ vtoc_ebcdic_dec (ch, ch, 44);
+ c1 = ch + 7;
+
+- if (getdsn (anc, i) > -1) {
++ if (getdsn (anc, i-1) > -1) {
+ /* re-use the existing data set name */
+ c2 = strchr (c1, '.');
+ if (c2 != NULL)
+@@ -426,11 +495,7 @@ fdasd_prepare_labels (fdasd_anchor_t *an
+ while (getpos (anc, k) > -1)
+ k++;
+
+- setpos (anc, k, i);
+-
+- strncpy (s2, ch, 44);
+- s2[44] = 0;
+- vtoc_ebcdic_dec (s2, s2, 44);
++ setpos (anc, k, i-1);
+
+ strncpy (ch, "LINUX.V " " ", 44);
+
+@@ -466,7 +531,6 @@ fdasd_prepare_labels (fdasd_anchor_t *an
+ }
+
+ vtoc_ebcdic_enc (ch, ch, 44);
+- p = p->next;
+ }
+
+ return 1;
+@@ -482,6 +546,7 @@ fdasd_recreate_vtoc (fdasd_anchor_t *anc
+ vtoc_init_format4_label(anc->f4,
+ USABLE_PARTITIONS,
+ anc->geo.cylinders,
++ anc->formatted_cylinders,
+ anc->geo.heads,
+ anc->geo.sectors,
+ anc->blksize,
+@@ -492,8 +557,8 @@ fdasd_recreate_vtoc (fdasd_anchor_t *anc
+ vtoc_set_freespace(anc->f4, anc->f5, anc->f7,
+ '+', anc->verbose,
+ FIRST_USABLE_TRK,
+- anc->geo.cylinders * anc->geo.heads - 1,
+- anc->geo.cylinders, anc->geo.heads);
++ anc->formatted_cylinders * anc->geo.heads - 1,
++ anc->formatted_cylinders, anc->geo.heads);
+
+ for (i = 0; i < USABLE_PARTITIONS; i++) {
+ bzero(p->f1, sizeof(format1_label_t));
+@@ -507,7 +572,8 @@ fdasd_recreate_vtoc (fdasd_anchor_t *anc
+ }
+
+ anc->used_partitions = 0;
+- anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
++ anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads -
++ FIRST_USABLE_TRK;
+
+ for (i=0; i<USABLE_PARTITIONS; i++)
+ setpos(anc, i, -1);
+@@ -526,15 +592,15 @@ fdasd_update_partition_info (fdasd_ancho
+ {
+ PDEBUG
+ partition_info_t *q = NULL, *p = anc->first;
+- unsigned int h = anc->geo.heads;
+- unsigned long max = anc->geo.cylinders * h - 1;
++ unsigned long max = anc->formatted_cylinders * anc->geo.heads - 1;
+ int i;
+ char *ch;
+
+ anc->used_partitions = anc->geo.sectors - 2 - anc->f4->DS4DSREC;
+
+ for (i = 1; i <= USABLE_PARTITIONS; i++) {
+- if (p->f1->DS1FMTID != 0xf1) {
++ if (p->f1->DS1FMTID != 0xf1 &&
++ p->f1->DS1FMTID != 0xf8) {
+ if (i == 1)
+ /* there is no partition at all */
+ anc->fspace_trk = max - FIRST_USABLE_TRK + 1;
+@@ -546,8 +612,8 @@ fdasd_update_partition_info (fdasd_ancho
+
+ /* this is a valid format 1 label */
+ p->used = 0x01;
+- p->start_trk = p->f1->DS1EXT1.llimit.cc * h + p->f1->DS1EXT1.llimit.hh;
+- p->end_trk = p->f1->DS1EXT1.ulimit.cc * h + p->f1->DS1EXT1.ulimit.hh;
++ p->start_trk = cchh2trk(&p->f1->DS1EXT1.llimit, &anc->geo);
++ p->end_trk = cchh2trk(&p->f1->DS1EXT1.ulimit, &anc->geo);
+ p->len_trk = p->end_trk - p->start_trk + 1;
+
+ if (i == 1) {
+@@ -618,14 +684,22 @@ fdasd_process_valid_vtoc (fdasd_anchor_t
+ format1_label_t q;
+ char s[5], *ch;
+
++ if (anc->f4->DS4DEVCT.DS4DSCYL == LV_COMPAT_CYL &&
++ anc->f4->DS4DCYL > anc->f4->DS4DEVCT.DS4DSCYL)
++ anc->formatted_cylinders = anc->f4->DS4DCYL;
++ else
++ anc->formatted_cylinders = anc->f4->DS4DEVCT.DS4DSCYL;
++ anc->fspace_trk = anc->formatted_cylinders * anc->geo.heads -
++ FIRST_USABLE_TRK;
+ b += anc->blksize;
+
+- for (i = 1; i <= anc->geo.sectors; i++) {
++ for (i = 1; i < anc->geo.sectors; i++) {
+ bzero (&q, f1size);
+ vtoc_read_label (fd, b, &q, NULL, NULL, NULL);
+
+ switch (q.DS1FMTID) {
+ case 0xf1:
++ case 0xf8:
+ if (p == NULL)
+ break;
+ memcpy (p->f1, &q, f1size);
+@@ -669,6 +743,12 @@ fdasd_process_valid_vtoc (fdasd_anchor_t
+ memcpy (anc->f7, &q, f1size);
+ f7_counter++;
+ break;
++ case 0xf9:
++ /* each format 8 lable has an associated
++ * format 9 lable, but they are of no further
++ * use to us.
++ */
++ break;
+ }
+
+ b += anc->blksize;
+@@ -718,7 +798,7 @@ fdasd_check_volume (fdasd_anchor_t *anc,
+ {
+ PDEBUG
+ volume_label_t *v = anc->vlabel;
+- unsigned long b = -1;
++ long long b = -1;
+ char str[LINE_LENGTH];
+
+ memset(v, 0, sizeof(volume_label_t));
+@@ -784,6 +864,7 @@ fdasd_get_geometry (const PedDevice *dev
+ PDEBUG
+ int blksize = 0;
+ dasd_information_t dasd_info;
++ struct dasd_eckd_characteristics *characteristics;
+
+ /* We can't get geometry from a regular file,
+ so simulate something usable, for the sake of testing. */
+@@ -803,6 +884,8 @@ fdasd_get_geometry (const PedDevice *dev
+ dasd_info.devno = 513;
+ dasd_info.label_block = 2;
+ dasd_info.FBA_layout = 0;
++ anc->hw_cylinders = ((st.st_size / blksize) / anc->geo.sectors) /
++ anc->geo.heads;
+ } else {
+ if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
+ fdasd_error(anc, unable_to_ioctl,
+@@ -816,13 +899,20 @@ fdasd_get_geometry (const PedDevice *dev
+ if (ioctl(f, BIODASDINFO, &dasd_info) != 0)
+ fdasd_error(anc, unable_to_ioctl,
+ _("Could not retrieve disk information."));
++
++ characteristics = (struct dasd_eckd_characteristics *)
++ &dasd_info.characteristics;
++ if (characteristics->no_cyl == LV_COMPAT_CYL &&
++ characteristics->long_no_cyl)
++ anc->hw_cylinders = characteristics->long_no_cyl;
++ else
++ anc->hw_cylinders = characteristics->no_cyl;
+ }
+
+ anc->dev_type = dasd_info.dev_type;
+ anc->blksize = blksize;
+ anc->label_pos = dasd_info.label_block * blksize;
+ anc->devno = dasd_info.devno;
+- anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
+ anc->label_block = dasd_info.label_block;
+ anc->FBA_layout = dasd_info.FBA_layout;
+ }
+@@ -850,20 +940,17 @@ fdasd_get_partition_data (fdasd_anchor_t
+ unsigned int *stop_ptr)
+ {
+ PDEBUG
+- unsigned int limit, cc, hh;
++ unsigned int limit;
++ u_int32_t cc, c;
++ u_int16_t hh, h;
+ cchh_t llimit, ulimit;
+ partition_info_t *q;
+ u_int8_t b1, b2;
+- u_int16_t c, h;
+ unsigned int start = *start_ptr, stop = *stop_ptr;
+ int i;
+ char *ch;
+
+- if (anc->f4->DS4DEVCT.DS4DEVFG & ALTERNATE_CYLINDERS_USED)
+- c = anc->f4->DS4DEVCT.DS4DSCYL - (u_int16_t) anc->f4->DS4DEVAC;
+- else
+- c = anc->f4->DS4DEVCT.DS4DSCYL;
+-
++ c = get_usable_cylinders(anc);
+ h = anc->f4->DS4DEVCT.DS4DSTRK;
+ limit = (h * c - 1);
+
+@@ -1019,7 +1106,6 @@ fdasd_add_partition (fdasd_anchor_t *anc
+ cchhb_t hf1;
+ partition_info_t *p;
+ extent_t ext;
+- int i;
+
+ PDEBUG;
+
+@@ -1032,8 +1118,14 @@ fdasd_add_partition (fdasd_anchor_t *anc
+ if (fdasd_get_partition_data(anc, &ext, p, &start, &stop) != 0)
+ return 0;
+
+- PDEBUG;
+- vtoc_init_format1_label(anc->vlabel->volid, anc->blksize, &ext, p->f1);
++ if (anc->formatted_cylinders > LV_COMPAT_CYL) {
++ vtoc_init_format8_label(anc->vlabel->volid, anc->blksize, &ext,
++ p->f1);
++ } else {
++ PDEBUG;
++ vtoc_init_format1_label(anc->vlabel->volid, anc->blksize, &ext,
++ p->f1);
++ }
+
+ PDEBUG;
+ fdasd_enqueue_new_partition(anc);
+@@ -1041,23 +1133,17 @@ fdasd_add_partition (fdasd_anchor_t *anc
+ PDEBUG;
+ anc->used_partitions += 1;
+
+- i = anc->used_partitions + 2;
+- if (anc->big_disk)
+- i++;
+- PDEBUG;
+-
+- vtoc_set_cchhb(&hf1, VTOC_START_CC, VTOC_START_HH, i);
+-
++ get_addr_of_highest_f1_f8_label(anc, &hf1);
+ vtoc_update_format4_label(anc->f4, &hf1, anc->f4->DS4DSREC - 1);
+
+ PDEBUG;
+
+- start = ext.llimit.cc * anc->geo.heads + ext.llimit.hh;
+- stop = ext.ulimit.cc * anc->geo.heads + ext.ulimit.hh;
++ start = cchh2trk(&ext.llimit, &anc->geo);
++ stop = cchh2trk(&ext.ulimit, &anc->geo);
+
+ PDEBUG;
+ vtoc_set_freespace(anc->f4, anc->f5, anc->f7, '-', anc->verbose,
+- start, stop, anc->geo.cylinders, anc->geo.heads);
++ start, stop, anc->formatted_cylinders, anc->geo.heads);
+
+ anc->vtoc_changed++;
+
+--- a/libparted/labels/vtoc.c
++++ b/libparted/labels/vtoc.c
+@@ -218,11 +218,32 @@ vtoc_set_extent (extent_t *ext, u_int8_t
+ }
+
+ void
+-vtoc_set_cchh (cchh_t *addr, u_int16_t cc, u_int16_t hh)
++vtoc_set_cchh (cchh_t *addr, u_int32_t cc, u_int16_t hh)
+ {
+ PDEBUG
+- addr->cc = cc;
+- addr->hh = hh;
++ addr->cc = (u_int16_t) cc;
++ addr->hh = cc >> 16;
++ addr->hh <<= 4;
++ addr->hh |= hh;
++}
++
++u_int32_t
++vtoc_get_cyl_from_cchh (cchh_t *addr)
++{
++ u_int32_t cyl;
++
++ /*decode cylinder for large volumes */
++ cyl = addr->hh & 0xFFF0;
++ cyl <<= 12;
++ cyl |= addr->cc;
++ return cyl;
++}
++
++u_int16_t
++vtoc_get_head_from_cchh (cchh_t *addr)
++{
++ /* decode heads for large volumes */
++ return addr->hh & 0x000F;
+ }
+
+ static void
+@@ -234,12 +255,63 @@ vtoc_set_ttr (ttr_t *addr, u_int16_t tt,
+ }
+
+ void
+-vtoc_set_cchhb (cchhb_t *addr, u_int16_t cc, u_int16_t hh, u_int8_t b)
++vtoc_set_cchhb (cchhb_t *addr, u_int32_t cc, u_int16_t hh, u_int8_t b)
+ {
+ PDEBUG
+- addr->cc = cc;
+- addr->hh = hh;
+- addr->b = b;
++ addr->cc = (u_int16_t) cc;
++ addr->hh = cc >> 16;
++ addr->hh <<= 4;
++ addr->hh |= hh;
++ addr->b = b;
++}
++
++u_int32_t
++vtoc_get_cyl_from_cchhb(cchhb_t *addr)
++{
++ u_int32_t cyl;
++
++ /* decode cylinder for large volumes */
++ cyl = addr->hh & 0xFFF0;
++ cyl <<= 12;
++ cyl |= addr->cc;
++ return cyl;
++}
++
++u_int16_t
++vtoc_get_head_from_cchhb(cchhb_t *addr)
++{
++ /* decode heads for large volumes */
++ return addr->hh & 0x000F;
++}
++
++/*
++ * some functions to convert cyl-cyl-head-head addresses to
++ * block or track numbers
++ * Note: Record zero is special, so first block on a track is
++ * in record 1!
++ */
++u_int64_t
++cchhb2blk (cchhb_t *p, struct fdasd_hd_geometry *geo)
++{
++ return (u_int64_t) vtoc_get_cyl_from_cchhb(p) *
++ geo->heads * geo->sectors +
++ vtoc_get_head_from_cchhb(p) * geo->sectors +
++ p->b;
++}
++
++u_int64_t
++cchh2blk (cchh_t *p, struct fdasd_hd_geometry *geo)
++{
++ return (u_int64_t) vtoc_get_cyl_from_cchh(p) *
++ geo->heads * geo->sectors +
++ vtoc_get_head_from_cchh(p) * geo->sectors;
++}
++
++u_int32_t
++cchh2trk (cchh_t *p, struct fdasd_hd_geometry *geo)
++{
++ return vtoc_get_cyl_from_cchh(p) * geo->heads +
++ vtoc_get_head_from_cchh(p);
+ }
+
+ void
+@@ -506,7 +578,8 @@ vtoc_write_label (int f, unsigned long p
+ format1_label_t const *f1,
+ format4_label_t const *f4,
+ format5_label_t const *f5,
+- format7_label_t const *f7)
++ format7_label_t const *f7,
++ format9_label_t const *f9)
+ {
+ PDEBUG
+ int t;
+@@ -542,6 +615,17 @@ vtoc_write_label (int f, unsigned long p
+ vtoc_error(unable_to_write, "vtoc_write_label",
+ _("Could not write VTOC FMT7 DSCB."));
+ }
++
++ if (f9 != NULL)
++ {
++ t = sizeof(format9_label_t);
++ if (write(f, f9, t) != t)
++ {
++ close(f);
++ vtoc_error(unable_to_write, "vtoc_write_label",
++ _("Could not write VTOC FMT9 DSCB."));
++ }
++ }
+ }
+
+ /*
+@@ -549,7 +633,8 @@ vtoc_write_label (int f, unsigned long p
+ */
+ void
+ vtoc_init_format4_label (format4_label_t *f4, unsigned int usable_partitions,
+- unsigned int cylinders, unsigned int tracks,
++ unsigned int compat_cylinders,
++ unsigned int real_cylinders, unsigned int tracks,
+ unsigned int blocks, unsigned int blksize,
+ u_int16_t dev_type)
+ {
+@@ -574,7 +659,7 @@ vtoc_init_format4_label (format4_label_t
+ f4->DS4DEVAC = 0x00;
+
+ /* -- begin f4->DS4DEVCT -- */
+- f4->DS4DEVCT.DS4DSCYL = cylinders;
++ f4->DS4DEVCT.DS4DSCYL = compat_cylinders;
+ f4->DS4DEVCT.DS4DSTRK = tracks;
+
+ switch (dev_type) {
+@@ -613,7 +698,11 @@ vtoc_init_format4_label (format4_label_t
+ bzero(f4->res2, sizeof(f4->res2));
+ f4->DS4EFLVL = 0x00;
+ bzero(&f4->DS4EFPTR, sizeof(f4->DS4EFPTR));
+- bzero(f4->res3, sizeof(f4->res3));
++ bzero(&f4->res3, sizeof(f4->res3));
++ f4->DS4DCYL = real_cylinders;
++ bzero(f4->res4, sizeof(f4->res4));
++ f4->DS4DEVF2 = 0x40; /* allow format 8 and 9 labels */
++ bzero(&f4->res5, sizeof(f4->res5));
+ }
+
+ /*
+@@ -647,11 +736,12 @@ vtoc_init_format7_label (format7_label_t
+ }
+
+ /*
+- * initializes a format1 label
++ * helper function that initializes a most parts of a
++ * format1 or format 8 label, all but the field DS1FMTID
+ */
+ void
+-vtoc_init_format1_label (char *volid, unsigned int blksize,
+- extent_t *part_extent, format1_label_t *f1)
++vtoc_init_format_1_8_label (char *volid, unsigned int blksize,
++ extent_t *part_extent, format1_label_t *f1)
+ {
+ PDEBUG
+ struct tm * creatime;
+@@ -666,7 +756,6 @@ vtoc_init_format1_label (char *volid, un
+ sprintf(str, "PART .NEW ");
+ vtoc_ebcdic_enc(str, str, 44);
+ strncpy(f1->DS1DSNAM, str, 44);
+- f1->DS1FMTID = 0xf1;
+ strncpy(f1->DS1DSSN, " ", 6);
+ f1->DS1VOLSQ = 0x0001;
+
+@@ -704,6 +793,37 @@ vtoc_init_format1_label (char *volid, un
+ vtoc_set_cchhb(&f1->DS1PTRDS, 0x0000, 0x0000, 0x00);
+ }
+
++void
++vtoc_init_format1_label (char *volid, unsigned int blksize,
++ extent_t *part_extent, format1_label_t *f1)
++{
++ vtoc_init_format_1_8_label(volid, blksize, part_extent, f1);
++ f1->DS1FMTID = 0xf1;
++}
++
++void
++vtoc_init_format8_label (char *volid, unsigned int blksize,
++ extent_t *part_extent, format1_label_t *f8)
++{
++ vtoc_init_format_1_8_label(volid, blksize, part_extent, f8);
++ f8->DS1FMTID = 0xf8;
++}
++
++void
++vtoc_update_format8_label (cchhb_t *associated_f9, format1_label_t *f8)
++{
++ memcpy(&f8->DS1PTRDS, associated_f9, sizeof(*associated_f9));
++}
++
++void
++vtoc_init_format9_label (format9_label_t *f9)
++{
++ f9->DS9KEYID = 0x09;
++ f9->DS9SUBTY = 0x01;
++ f9->DS9NUMF9 = 1;
++ f9->DS9FMTID = 0xf9;
++}
++
+ /*
+ * do some updates to the VTOC format4 label
+ */
+@@ -1060,7 +1180,7 @@ vtoc_update_format7_label_add (format7_l
+ if ((ext->a + ext->b) == 0x00000000)
+ continue;
+
+- if ((ext->b + 1) == tmp->a) {
++ if (ext->b == tmp->a) {
+ /* this extent precedes the new one */
+ ext->b = tmp->b;
+ bzero(tmp, sizeof(ds7ext_t));
+@@ -1074,7 +1194,7 @@ vtoc_update_format7_label_add (format7_l
+ continue;
+ }
+
+- if (ext->a == (tmp->b + 1)) {
++ if (ext->a == tmp->b) {
+ /* this extent succeeds the new one */
+ ext->a = tmp->a;
+ bzero(tmp, sizeof(ds7ext_t));
+@@ -1119,7 +1239,7 @@ vtoc_update_format7_label_del (format7_l
+
+ if ((a == ext->a) && (b < ext->b)) {
+ /* left-bounded in free space gap */
+- ext->a = b + 1;
++ ext->a = b;
+
+ if (verbose)
+ puts ("FMT7 add extent: left-bounded");
+@@ -1130,7 +1250,7 @@ vtoc_update_format7_label_del (format7_l
+
+ if ((a > ext->a) && (b == ext->b)) {
+ /* right-bounded in free space gap */
+- ext->b = a - 1;
++ ext->b = a;
+
+ if (verbose)
+ puts ("FMT7 add extent: right-bounded");
+@@ -1141,8 +1261,8 @@ vtoc_update_format7_label_del (format7_l
+
+ if ((a > ext->a) && (b < ext->b)) {
+ /* partition devides free space into 2 pieces */
+- vtoc_update_format7_label_add(f7, verbose, b+1, ext->b);
+- ext->b = a - 1;
++ vtoc_update_format7_label_add(f7, verbose, b, ext->b);
++ ext->b = a;
+
+ if (verbose)
+ puts ("FMT7 add extent: 2 pieces");
+@@ -1172,14 +1292,19 @@ vtoc_update_format7_label_del (format7_l
+ void
+ vtoc_set_freespace(format4_label_t *f4, format5_label_t *f5,
+ format7_label_t *f7, char ch, int verbose,
+- u_int32_t start, u_int32_t stop, int cyl, int trk)
++ u_int32_t start, u_int32_t stop, u_int32_t cyl,
++ u_int32_t trk)
+ {
+ PDEBUG
+ if ((cyl * trk) > BIG_DISK_SIZE) {
+ if (ch == '+')
+- vtoc_update_format7_label_add(f7, verbose, start, stop);
++ vtoc_update_format7_label_add(f7, verbose, start,
++ /* ds7ext RTA + 1 */
++ stop + 1);
+ else if (ch == '-')
+- vtoc_update_format7_label_del(f7, verbose, start, stop);
++ vtoc_update_format7_label_del(f7, verbose, start,
++ /* ds7ext RTA + 1 */
++ stop + 1);
+ else
+ puts ("BUG: syntax error in vtoc_set_freespace call");
+
diff --git a/parted-3.1-libparted-add-support-for-implicit-FBA-DASD-partitions.patch b/parted-3.1-libparted-add-support-for-implicit-FBA-DASD-partitions.patch
new file mode 100644
index 0000000..95d2551
--- /dev/null
+++ b/parted-3.1-libparted-add-support-for-implicit-FBA-DASD-partitions.patch
@@ -0,0 +1,187 @@
+Subject: [PATCH] libparted: add support for implicit FBA DASD partitions
+
+From: Nageswara R Sastry <rnsastry at linux.vnet.ibm.com>
+
+Fixed Block Access (FBA) DASDs are mainframe-specific disk devices
+which are layed out as a sequence of 512-byte sectors. In contrast
+to ECKD DASDs, these disks do not require formatting and resemble
+the LBA layout of non-mainframe disks. Despite this resemblance,
+the Linux kernel applies special handling during partition detection
+for FBA DASDs, resulting in a single, immutable partition being
+reported.
+
+While actual FBA DASD hardware is no longer available, the z/VM
+hypervisor can simulate FBA DASD disks, backed by either ECKD or
+SCSI devices.
+
+This patch adds support for recognizing FBA DASD partitions
+to parted.
+
+Signed-off-by: Nageswara R Sastry <rnsastry at linux.vnet.ibm.com>
+Signed-off-by: Peter Oberparleiter <oberpar at linux.vnet.ibm.com>
+
+---
+ include/parted/fdasd.h | 2 +
+ libparted/labels/dasd.c | 63 ++++++++++++++++++++++++++++++++++++++++-------
+ libparted/labels/fdasd.c | 5 +++
+ 3 files changed, 61 insertions(+), 9 deletions(-)
+
+--- a/include/parted/fdasd.h
++++ b/include/parted/fdasd.h
+@@ -194,6 +194,8 @@ typedef struct fdasd_anchor {
+ volume_label_t *vlabel;
+ config_data_t confdata[USABLE_PARTITIONS];
+ struct fdasd_hd_geometry geo;
++ unsigned int label_block;
++ unsigned int FBA_layout;
+ } fdasd_anchor_t;
+
+ enum offset {lower, upper};
+--- a/libparted/labels/dasd.c
++++ b/libparted/labels/dasd.c
+@@ -71,6 +71,7 @@ typedef struct {
+
+ typedef struct {
+ unsigned int format_type;
++ unsigned int label_block;
+ volume_label_t vlabel;
+ } DasdDiskSpecific;
+
+@@ -151,6 +152,7 @@ dasd_alloc (const PedDevice* dev)
+
+ /* CDL format, newer */
+ disk_specific->format_type = 2;
++ disk_specific->label_block = 2;
+
+ /* Setup volume label (for fresh disks) */
+ snprintf(volser, sizeof(volser), "0X%04X", arch_specific->devno);
+@@ -226,7 +228,9 @@ dasd_probe (const PedDevice *dev)
+
+ fdasd_check_api_version(&anchor, arch_specific->fd);
+
+- if (fdasd_check_volume(&anchor, arch_specific->fd))
++ /* Labels are required on CDL formatted DASDs. */
++ if (fdasd_check_volume(&anchor, arch_specific->fd) &&
++ anchor.FBA_layout == 0)
+ goto error_cleanup;
+
+ fdasd_cleanup(&anchor);
+@@ -273,17 +277,53 @@ dasd_read (PedDisk* disk)
+ fdasd_initialize_anchor(&anchor);
+
+ fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
++ disk_specific->label_block = anchor.label_block;
++
++ if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
++ anchor.big_disk++;
+
+ /* check dasd for labels and vtoc */
+- if (fdasd_check_volume(&anchor, arch_specific->fd))
+- goto error_close_dev;
++ if (fdasd_check_volume(&anchor, arch_specific->fd)) {
++ DasdPartitionData* dasd_data;
++
++ /* Kernel partitioning code will report 'implicit' partitions
++ * for non-CDL format DASDs even when there is no
++ * label/VTOC. */
++ if (anchor.FBA_layout == 0)
++ goto error_close_dev;
++
++ disk_specific->format_type = 1;
++
++ /* Register implicit partition */
++ ped_disk_delete_all (disk);
++
++ start = (PedSector) arch_specific->real_sector_size /
++ (PedSector) disk->dev->sector_size *
++ (PedSector) (anchor.label_block + 1);
++ end = disk->dev->length - 1;
++ part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL,
++ start, end);
++ if (!part)
++ goto error_close_dev;
++
++ part->num = 1;
++ part->fs_type = ped_file_system_probe (&part->geom);
++ dasd_data = part->disk_specific;
++ dasd_data->raid = 0;
++ dasd_data->lvm = 0;
++ dasd_data->type = 0;
++
++ if (!ped_disk_add_partition (disk, part, NULL))
++ goto error_close_dev;
++
++ fdasd_cleanup(&anchor);
++
++ return 1;
++ }
+
+ /* Save volume label (read by fdasd_check_volume) for writing */
+ memcpy(&disk_specific->vlabel, anchor.vlabel, sizeof(volume_label_t));
+
+- if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
+- anchor.big_disk++;
+-
+ ped_disk_delete_all (disk);
+
+ bool is_ldl = strncmp(anchor.vlabel->volkey,
+@@ -348,7 +388,7 @@ dasd_read (PedDisk* disk)
+ / (long long) disk->dev->sector_size
+ * (long long) (cms_ptr->block_count - 1) - 1;
+
+- part = ped_partition_new (disk, PED_PARTITION_PROTECTED, NULL, start, end);
++ part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL, start, end);
+ if (!part)
+ goto error_close_dev;
+
+@@ -923,7 +963,12 @@ dasd_alloc_metadata (PedDisk* disk)
+ the start of the first partition */
+ if (disk_specific->format_type == 1) {
+ part = ped_disk_get_partition(disk, 1);
+- vtoc_end = part->geom.start - 1;
++ if (part)
++ vtoc_end = part->geom.start - 1;
++ else
++ vtoc_end = (PedSector) arch_specific->real_sector_size /
++ (PedSector) disk->dev->sector_size *
++ (PedSector) disk_specific->label_block;
+ }
+ else {
+ if (disk->dev->type == PED_DEVICE_FILE)
+@@ -943,7 +988,7 @@ dasd_alloc_metadata (PedDisk* disk)
+ goto error;
+ }
+
+- if (disk_specific->format_type == 1) {
++ if (disk_specific->format_type == 1 && part) {
+ /*
+ For LDL or CMS there may be trailing metadata as well.
+ For example: the last block of a CMS reserved file,
+--- a/libparted/labels/fdasd.c
++++ b/libparted/labels/fdasd.c
+@@ -721,6 +721,7 @@ fdasd_check_volume (fdasd_anchor_t *anc,
+ unsigned long b = -1;
+ char str[LINE_LENGTH];
+
++ memset(v, 0, sizeof(volume_label_t));
+ vtoc_read_volume_label (fd, anc->label_pos, v);
+
+ if (strncmp(v->vollbl, vtoc_ebcdic_enc ("VOL1", str, 4), 4) == 0) {
+@@ -800,6 +801,8 @@ fdasd_get_geometry (const PedDevice *dev
+ dasd_info.dev_type = 13200;
+ dasd_info.label_block = 2;
+ dasd_info.devno = 513;
++ dasd_info.label_block = 2;
++ dasd_info.FBA_layout = 0;
+ } else {
+ if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
+ fdasd_error(anc, unable_to_ioctl,
+@@ -820,6 +823,8 @@ fdasd_get_geometry (const PedDevice *dev
+ anc->label_pos = dasd_info.label_block * blksize;
+ anc->devno = dasd_info.devno;
+ anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
++ anc->label_block = dasd_info.label_block;
++ anc->FBA_layout = dasd_info.FBA_layout;
+ }
+
+ /*
diff --git a/parted-3.1-libparted-preserve-the-uuid-on-dm-partitions.patch b/parted-3.1-libparted-preserve-the-uuid-on-dm-partitions.patch
index 805ee07..d33a272 100644
--- a/parted-3.1-libparted-preserve-the-uuid-on-dm-partitions.patch
+++ b/parted-3.1-libparted-preserve-the-uuid-on-dm-partitions.patch
@@ -1,16 +1,16 @@
-From 399cfc2a9cfc60a46ab9094b4c999bb11a36033e Mon Sep 17 00:00:00 2001
-From: Fedora Ninjas <parted-owner at fedoraproject.org>
+From e2b9f9051c8d9905b15af0f7fa79c85502370b25 Mon Sep 17 00:00:00 2001
+From: Brian C. Lane <bcl at redhat.com>
Date: Fri, 3 Aug 2012 17:03:50 -0700
Subject: [PATCH] libparted: preserve the uuid on dm partitions (#832145)
* libparted/arch/linux.c (_dm_add_partition): Set the uuid if there was
one.
---
- libparted/arch/linux.c | 11 +++++++++++
- 1 files changed, 11 insertions(+), 0 deletions(-)
+ libparted/arch/linux.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
-index 37ddb5f..9f0434a 100644
+index 37ddb5f..2c410a0 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2803,6 +2803,8 @@ _dm_add_partition (PedDisk* disk, PedPartition* part)
@@ -35,7 +35,7 @@ index 37ddb5f..9f0434a 100644
goto err;
+ if ( dev_uuid && (strlen(dev_uuid) > 0) \
-+ && ! (vol_uuid = zasprintf ("%sp%d", dev_uuid, part->num)))
++ && ! (vol_uuid = zasprintf ("part%d-%s", part->num, dev_uuid)))
+ goto err;
+
/* Caution: dm_task_destroy frees dev_name. */
@@ -67,5 +67,5 @@ index 37ddb5f..9f0434a 100644
return 0;
}
--
-1.7.7.6
+1.7.11.4
diff --git a/parted-3.1-tests-Make-sure-dm-UUIDs-are-not-erased.patch b/parted-3.1-tests-Make-sure-dm-UUIDs-are-not-erased.patch
index 342225d..c24bfaf 100644
--- a/parted-3.1-tests-Make-sure-dm-UUIDs-are-not-erased.patch
+++ b/parted-3.1-tests-Make-sure-dm-UUIDs-are-not-erased.patch
@@ -1,5 +1,5 @@
From cc96f793bb4fb088123a40fb9d802e7db1fdbffb Mon Sep 17 00:00:00 2001
-From: Fedora Ninjas <parted-owner at fedoraproject.org>
+From: Brian C. Lane <bcl at redhat.com>
Date: Tue, 7 Aug 2012 10:14:03 -0700
Subject: [PATCH] tests: Make sure dm UUIDs are not erased
diff --git a/parted-3.1-tests-cleanup-losetup-usage.patch b/parted-3.1-tests-cleanup-losetup-usage.patch
new file mode 100644
index 0000000..06f13c8
--- /dev/null
+++ b/parted-3.1-tests-cleanup-losetup-usage.patch
@@ -0,0 +1,137 @@
+From a1aa9eb26f357bb1a5111eb332594dfb7b39ace0 Mon Sep 17 00:00:00 2001
+From: "Brian C. Lane" <bcl at redhat.com>
+Date: Mon, 15 Oct 2012 17:27:18 -0700
+Subject: [PATCH 1/2] tests: cleanup losetup usage
+
+The unsafe_losetup_ function was failing because losetup didn't
+recognize that the 'private' /dev/loopX devices were the same as
+/dev/loopX, it would fail even if one was in use. Switch to using
+losetup --show which is a cleaner solution.
+Also use sparse file for loop_setup to save space.
+---
+ tests/lvm-utils.sh | 24 ++----------------------
+ tests/t-lvm.sh | 24 ++----------------------
+ tests/t6001-psep.sh | 8 ++------
+ tests/t6003-dm-uuid.sh | 3 +--
+ 4 files changed, 7 insertions(+), 52 deletions(-)
+
+diff --git a/tests/lvm-utils.sh b/tests/lvm-utils.sh
+index 456d265..a204b08 100644
+--- a/tests/lvm-utils.sh
++++ b/tests/lvm-utils.sh
+@@ -16,34 +16,14 @@ export LVM_SUPPRESS_FD_WARNINGS=1
+ ME=$(basename "$0")
+ warn() { echo >&2 "$ME: $@"; }
+
+-unsafe_losetup_()
+-{
+- f=$1
+-
+- test -n "$G_dev_" \
+- || fail_ "Internal error: unsafe_losetup_ called before init_root_dir_"
+-
+- # Iterate through $G_dev_/loop{,/}{0,1,2,3,4,5,6,7,8,9}
+- for slash in '' /; do
+- for i in 0 1 2 3 4 5 6 7 8 9; do
+- dev=$G_dev_/loop$slash$i
+- losetup $dev > /dev/null 2>&1 && continue;
+- losetup "$dev" "$f" > /dev/null && { echo "$dev"; return 0; }
+- break
+- done
+- done
+-
+- return 1
+-}
+-
+ loop_setup_()
+ {
+ file=$1
+- dd if=/dev/zero of="$file" bs=1M count=1 seek=1000 > /dev/null 2>&1 \
++ dd if=/dev/null of="$file" bs=1M count=1 seek=1000 > /dev/null 2>&1 \
+ || { warn "loop_setup_ failed: Unable to create tmp file $file"; return 1; }
+
+ # NOTE: this requires a new enough version of losetup
+- dev=$(unsafe_losetup_ "$file") \
++ dev=$(losetup --show -f "$file") 2>/dev/null \
+ || { warn "loop_setup_ failed: Unable to create loopback device"; return 1; }
+
+ echo "$dev"
+diff --git a/tests/t-lvm.sh b/tests/t-lvm.sh
+index b08f934..3c7657b 100644
+--- a/tests/t-lvm.sh
++++ b/tests/t-lvm.sh
+@@ -16,34 +16,14 @@ export LVM_SUPPRESS_FD_WARNINGS=1
+ ME=$(basename "$0")
+ warn() { echo >&2 "$ME: $@"; }
+
+-unsafe_losetup_()
+-{
+- f=$1
+-
+- test -n "$G_dev_" \
+- || error "Internal error: unsafe_losetup_ called before init_root_dir_"
+-
+- # Iterate through $G_dev_/loop{,/}{0,1,2,3,4,5,6,7,8,9}
+- for slash in '' /; do
+- for i in 0 1 2 3 4 5 6 7 8 9; do
+- dev=$G_dev_/loop$slash$i
+- losetup $dev > /dev/null 2>&1 && continue;
+- losetup "$dev" "$f" > /dev/null && { echo "$dev"; return 0; }
+- break
+- done
+- done
+-
+- return 1
+-}
+-
+ loop_setup_()
+ {
+ file=$1
+- dd if=/dev/zero of="$file" bs=1M count=1 seek=1000 > /dev/null 2>&1 \
++ dd if=/dev/null of="$file" bs=1M count=1 seek=1000 > /dev/null 2>&1 \
+ || { warn "loop_setup_ failed: Unable to create tmp file $file"; return 1; }
+
+ # NOTE: this requires a new enough version of losetup
+- dev=$(unsafe_losetup_ "$file" 2>/dev/null) \
++ dev=$(losetup --show -f "$file") 2>/dev/null \
+ || { warn "loop_setup_ failed: Unable to create loopback device"; return 1; }
+
+ echo "$dev"
+diff --git a/tests/t6001-psep.sh b/tests/t6001-psep.sh
+index 490c6d2..1859ac9 100644
+--- a/tests/t6001-psep.sh
++++ b/tests/t6001-psep.sh
+@@ -44,14 +44,10 @@ cleanup_fn_() {
+ # create a file of size N bytes
+ N=10M
+
+-# create the test file
+-f1=$(pwd)/1; dd if=/dev/null of=$f1 bs=1 seek=$N 2> /dev/null || fail=1
+-f2=$(pwd)/2; dd if=/dev/null of=$f2 bs=1 seek=$N 2> /dev/null || fail=1
+-
+-d1=$(loop_setup_ "$f1") \
++f1=$(pwd)/1; d1=$(loop_setup_ "$f1") \
+ || skip_ "is this partition mounted with 'nodev'?"
+
+-d2=$(loop_setup_ "$f2") \
++f2=$(pwd)/2 ;d2=$(loop_setup_ "$f2") \
+ || skip_ "is this partition mounted with 'nodev'?"
+
+ dmsetup_cmd="0 `blockdev --getsz $d1` linear $d1 0"
+diff --git a/tests/t6003-dm-uuid.sh b/tests/t6003-dm-uuid.sh
+index 1751cb4..f58cb06 100755
+--- a/tests/t6003-dm-uuid.sh
++++ b/tests/t6003-dm-uuid.sh
+@@ -36,8 +36,7 @@ cleanup_() {
+ }
+
+ # create a file large enough to hold a GPT partition table
+-dd if=/dev/null of=$loop_file bs=$ss seek=$ns || framework_failure
+-dev=$(losetup --show -f $loop_file) || framework_failure
++dev=$(loop_setup_ $loop_file) || framework_failure
+ dmsetup create $dm_name --table "0 $ns linear $dev 0" || framework_failure
+ dmsetup rename $dm_name --setuuid f139317b-f98a-45d7-ab3b-9b4e0a336872 || framework_failure
+
+--
+1.7.11.4
+
diff --git a/parted.spec b/parted.spec
index 77645af..ab4cc49 100644
--- a/parted.spec
+++ b/parted.spec
@@ -4,7 +4,7 @@
Summary: The GNU disk partition manipulation program
Name: parted
Version: 3.1
-Release: 7%{?dist}
+Release: 8%{?dist}
License: GPLv3+
Group: Applications/System
URL: http://www.gnu.org/software/parted
@@ -23,6 +23,9 @@ patch6: parted-3.1-test-creating-20-device-mapper-partitions.patch
Patch7: parted-3.1-libparted-preserve-the-uuid-on-dm-partitions.patch
Patch8: parted-3.1-tests-Make-sure-dm-UUIDs-are-not-erased.patch
Patch9: parted-3.1-libparted-reallocate-buf-after-_disk_analyse_block_s.patch
+Patch10: parted-3.1-tests-cleanup-losetup-usage.patch
+Patch11: parted-3.1-libparted-add-support-for-implicit-FBA-DASD-partitions.patch
+Patch12: parted-3.1-libparted-add-support-for-EAV-DASD-partitions.patch
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: e2fsprogs-devel
@@ -158,6 +161,12 @@ fi
%changelog
+* Tue Oct 16 2012 Brian C. Lane <bcl at redhat.com> 3.1-8
+- change partition UUID to use partX-UUID (#858704)
+- fixup losetup usage in tests
+- add support for implicit FBA DASD partitions (#707027)
+- add support for EAV DASD partitions (#707032)
+
* Tue Sep 04 2012 Brian C. Lane <bcl at redhat.com> 3.1-7
- reallocate buf after _disk_analyse_block_size (#835601)
More information about the scm-commits
mailing list