|
|
8dc857 |
Subject: [PATCH] libparted: add support for implicit FBA DASD partitions
|
|
|
8dc857 |
|
|
|
8dc857 |
From: Nageswara R Sastry <rnsastry@linux.vnet.ibm.com>
|
|
|
8dc857 |
|
|
|
8dc857 |
Fixed Block Access (FBA) DASDs are mainframe-specific disk devices
|
|
|
8dc857 |
which are layed out as a sequence of 512-byte sectors. In contrast
|
|
|
8dc857 |
to ECKD DASDs, these disks do not require formatting and resemble
|
|
|
8dc857 |
the LBA layout of non-mainframe disks. Despite this resemblance,
|
|
|
8dc857 |
the Linux kernel applies special handling during partition detection
|
|
|
8dc857 |
for FBA DASDs, resulting in a single, immutable partition being
|
|
|
8dc857 |
reported.
|
|
|
8dc857 |
|
|
|
8dc857 |
While actual FBA DASD hardware is no longer available, the z/VM
|
|
|
8dc857 |
hypervisor can simulate FBA DASD disks, backed by either ECKD or
|
|
|
8dc857 |
SCSI devices.
|
|
|
8dc857 |
|
|
|
8dc857 |
This patch adds support for recognizing FBA DASD partitions
|
|
|
8dc857 |
to parted.
|
|
|
8dc857 |
|
|
|
8dc857 |
Signed-off-by: Nageswara R Sastry <rnsastry@linux.vnet.ibm.com>
|
|
|
8dc857 |
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
|
|
8dc857 |
|
|
|
8dc857 |
---
|
|
|
8dc857 |
include/parted/fdasd.h | 2 +
|
|
|
8dc857 |
libparted/labels/dasd.c | 63 ++++++++++++++++++++++++++++++++++++++++-------
|
|
|
8dc857 |
libparted/labels/fdasd.c | 5 +++
|
|
|
8dc857 |
3 files changed, 61 insertions(+), 9 deletions(-)
|
|
|
8dc857 |
|
|
|
8dc857 |
--- a/include/parted/fdasd.h
|
|
|
8dc857 |
+++ b/include/parted/fdasd.h
|
|
|
8dc857 |
@@ -194,6 +194,8 @@ typedef struct fdasd_anchor {
|
|
|
8dc857 |
volume_label_t *vlabel;
|
|
|
8dc857 |
config_data_t confdata[USABLE_PARTITIONS];
|
|
|
8dc857 |
struct fdasd_hd_geometry geo;
|
|
|
8dc857 |
+ unsigned int label_block;
|
|
|
8dc857 |
+ unsigned int FBA_layout;
|
|
|
8dc857 |
} fdasd_anchor_t;
|
|
|
8dc857 |
|
|
|
8dc857 |
enum offset {lower, upper};
|
|
|
8dc857 |
--- a/libparted/labels/dasd.c
|
|
|
8dc857 |
+++ b/libparted/labels/dasd.c
|
|
|
8dc857 |
@@ -71,6 +71,7 @@ typedef struct {
|
|
|
8dc857 |
|
|
|
8dc857 |
typedef struct {
|
|
|
8dc857 |
unsigned int format_type;
|
|
|
8dc857 |
+ unsigned int label_block;
|
|
|
8dc857 |
volume_label_t vlabel;
|
|
|
8dc857 |
} DasdDiskSpecific;
|
|
|
8dc857 |
|
|
|
8dc857 |
@@ -151,6 +152,7 @@ dasd_alloc (const PedDevice* dev)
|
|
|
8dc857 |
|
|
|
8dc857 |
/* CDL format, newer */
|
|
|
8dc857 |
disk_specific->format_type = 2;
|
|
|
8dc857 |
+ disk_specific->label_block = 2;
|
|
|
8dc857 |
|
|
|
8dc857 |
/* Setup volume label (for fresh disks) */
|
|
|
8dc857 |
snprintf(volser, sizeof(volser), "0X%04X", arch_specific->devno);
|
|
|
8dc857 |
@@ -226,7 +228,9 @@ dasd_probe (const PedDevice *dev)
|
|
|
8dc857 |
|
|
|
8dc857 |
fdasd_check_api_version(&anchor, arch_specific->fd);
|
|
|
8dc857 |
|
|
|
8dc857 |
- if (fdasd_check_volume(&anchor, arch_specific->fd))
|
|
|
8dc857 |
+ /* Labels are required on CDL formatted DASDs. */
|
|
|
8dc857 |
+ if (fdasd_check_volume(&anchor, arch_specific->fd) &&
|
|
|
8dc857 |
+ anchor.FBA_layout == 0)
|
|
|
8dc857 |
goto error_cleanup;
|
|
|
8dc857 |
|
|
|
8dc857 |
fdasd_cleanup(&anchor);
|
|
|
8dc857 |
@@ -273,17 +277,53 @@ dasd_read (PedDisk* disk)
|
|
|
8dc857 |
fdasd_initialize_anchor(&anchor);
|
|
|
8dc857 |
|
|
|
8dc857 |
fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
|
|
|
8dc857 |
+ disk_specific->label_block = anchor.label_block;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
|
|
|
8dc857 |
+ anchor.big_disk++;
|
|
|
8dc857 |
|
|
|
8dc857 |
/* check dasd for labels and vtoc */
|
|
|
8dc857 |
- if (fdasd_check_volume(&anchor, arch_specific->fd))
|
|
|
8dc857 |
- goto error_close_dev;
|
|
|
8dc857 |
+ if (fdasd_check_volume(&anchor, arch_specific->fd)) {
|
|
|
8dc857 |
+ DasdPartitionData* dasd_data;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ /* Kernel partitioning code will report 'implicit' partitions
|
|
|
8dc857 |
+ * for non-CDL format DASDs even when there is no
|
|
|
8dc857 |
+ * label/VTOC. */
|
|
|
8dc857 |
+ if (anchor.FBA_layout == 0)
|
|
|
8dc857 |
+ goto error_close_dev;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ disk_specific->format_type = 1;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ /* Register implicit partition */
|
|
|
8dc857 |
+ ped_disk_delete_all (disk);
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ start = (PedSector) arch_specific->real_sector_size /
|
|
|
8dc857 |
+ (PedSector) disk->dev->sector_size *
|
|
|
8dc857 |
+ (PedSector) (anchor.label_block + 1);
|
|
|
8dc857 |
+ end = disk->dev->length - 1;
|
|
|
8dc857 |
+ part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL,
|
|
|
8dc857 |
+ start, end);
|
|
|
8dc857 |
+ if (!part)
|
|
|
8dc857 |
+ goto error_close_dev;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ part->num = 1;
|
|
|
8dc857 |
+ part->fs_type = ped_file_system_probe (&part->geom);
|
|
|
8dc857 |
+ dasd_data = part->disk_specific;
|
|
|
8dc857 |
+ dasd_data->raid = 0;
|
|
|
8dc857 |
+ dasd_data->lvm = 0;
|
|
|
8dc857 |
+ dasd_data->type = 0;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ if (!ped_disk_add_partition (disk, part, NULL))
|
|
|
8dc857 |
+ goto error_close_dev;
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ fdasd_cleanup(&anchor);
|
|
|
8dc857 |
+
|
|
|
8dc857 |
+ return 1;
|
|
|
8dc857 |
+ }
|
|
|
8dc857 |
|
|
|
8dc857 |
/* Save volume label (read by fdasd_check_volume) for writing */
|
|
|
8dc857 |
memcpy(&disk_specific->vlabel, anchor.vlabel, sizeof(volume_label_t));
|
|
|
8dc857 |
|
|
|
8dc857 |
- if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
|
|
|
8dc857 |
- anchor.big_disk++;
|
|
|
8dc857 |
-
|
|
|
8dc857 |
ped_disk_delete_all (disk);
|
|
|
8dc857 |
|
|
|
8dc857 |
bool is_ldl = strncmp(anchor.vlabel->volkey,
|
|
|
8dc857 |
@@ -348,7 +388,7 @@ dasd_read (PedDisk* disk)
|
|
|
8dc857 |
/ (long long) disk->dev->sector_size
|
|
|
8dc857 |
* (long long) (cms_ptr->block_count - 1) - 1;
|
|
|
8dc857 |
|
|
|
8dc857 |
- part = ped_partition_new (disk, PED_PARTITION_PROTECTED, NULL, start, end);
|
|
|
8dc857 |
+ part = ped_partition_new (disk, PED_PARTITION_NORMAL, NULL, start, end);
|
|
|
8dc857 |
if (!part)
|
|
|
8dc857 |
goto error_close_dev;
|
|
|
8dc857 |
|
|
|
8dc857 |
@@ -923,7 +963,12 @@ dasd_alloc_metadata (PedDisk* disk)
|
|
|
8dc857 |
the start of the first partition */
|
|
|
8dc857 |
if (disk_specific->format_type == 1) {
|
|
|
8dc857 |
part = ped_disk_get_partition(disk, 1);
|
|
|
8dc857 |
- vtoc_end = part->geom.start - 1;
|
|
|
8dc857 |
+ if (part)
|
|
|
8dc857 |
+ vtoc_end = part->geom.start - 1;
|
|
|
8dc857 |
+ else
|
|
|
8dc857 |
+ vtoc_end = (PedSector) arch_specific->real_sector_size /
|
|
|
8dc857 |
+ (PedSector) disk->dev->sector_size *
|
|
|
8dc857 |
+ (PedSector) disk_specific->label_block;
|
|
|
8dc857 |
}
|
|
|
8dc857 |
else {
|
|
|
8dc857 |
if (disk->dev->type == PED_DEVICE_FILE)
|
|
|
8dc857 |
@@ -943,7 +988,7 @@ dasd_alloc_metadata (PedDisk* disk)
|
|
|
8dc857 |
goto error;
|
|
|
8dc857 |
}
|
|
|
8dc857 |
|
|
|
8dc857 |
- if (disk_specific->format_type == 1) {
|
|
|
8dc857 |
+ if (disk_specific->format_type == 1 && part) {
|
|
|
8dc857 |
/*
|
|
|
8dc857 |
For LDL or CMS there may be trailing metadata as well.
|
|
|
8dc857 |
For example: the last block of a CMS reserved file,
|
|
|
8dc857 |
--- a/libparted/labels/fdasd.c
|
|
|
8dc857 |
+++ b/libparted/labels/fdasd.c
|
|
|
8dc857 |
@@ -721,6 +721,7 @@ fdasd_check_volume (fdasd_anchor_t *anc,
|
|
|
8dc857 |
unsigned long b = -1;
|
|
|
8dc857 |
char str[LINE_LENGTH];
|
|
|
8dc857 |
|
|
|
8dc857 |
+ memset(v, 0, sizeof(volume_label_t));
|
|
|
8dc857 |
vtoc_read_volume_label (fd, anc->label_pos, v);
|
|
|
8dc857 |
|
|
|
8dc857 |
if (strncmp(v->vollbl, vtoc_ebcdic_enc ("VOL1", str, 4), 4) == 0) {
|
|
|
8dc857 |
@@ -800,6 +801,8 @@ fdasd_get_geometry (const PedDevice *dev
|
|
|
8dc857 |
dasd_info.dev_type = 13200;
|
|
|
8dc857 |
dasd_info.label_block = 2;
|
|
|
8dc857 |
dasd_info.devno = 513;
|
|
|
8dc857 |
+ dasd_info.label_block = 2;
|
|
|
8dc857 |
+ dasd_info.FBA_layout = 0;
|
|
|
8dc857 |
} else {
|
|
|
8dc857 |
if (ioctl(f, HDIO_GETGEO, &anc->geo) != 0)
|
|
|
8dc857 |
fdasd_error(anc, unable_to_ioctl,
|
|
|
8dc857 |
@@ -820,6 +823,8 @@ fdasd_get_geometry (const PedDevice *dev
|
|
|
8dc857 |
anc->label_pos = dasd_info.label_block * blksize;
|
|
|
8dc857 |
anc->devno = dasd_info.devno;
|
|
|
8dc857 |
anc->fspace_trk = anc->geo.cylinders * anc->geo.heads - FIRST_USABLE_TRK;
|
|
|
8dc857 |
+ anc->label_block = dasd_info.label_block;
|
|
|
8dc857 |
+ anc->FBA_layout = dasd_info.FBA_layout;
|
|
|
8dc857 |
}
|
|
|
8dc857 |
|
|
|
8dc857 |
/*
|