From: Viktor Mihajlovski <[email protected]> Probe for all device/transport types as every block device could be a DASD on s390.
Observe fdasd_get_geometry return code for proper error handling. Remove the obsolete API check as we no longer require the DASD-specific IOCTLs. We can't rely on PED_DEVICE_DASD to be set for non-native DASDs so we use a heuristic on s390x implemented in ped_device_like_dasd() Signed-off-by: Viktor Mihajlovski <[email protected]> Acked-by: Stefan Haberland <[email protected]> Signed-off-by: Hendrik Brueckner <[email protected]> --- include/parted/device.in.h | 2 ++ libparted/arch/linux.c | 8 ++++++-- libparted/device.c | 32 ++++++++++++++++++++++++++++---- libparted/labels/dasd.c | 18 ++++++++---------- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/include/parted/device.in.h b/include/parted/device.in.h index 82d4104..85b1567 100644 --- a/include/parted/device.in.h +++ b/include/parted/device.in.h @@ -156,6 +156,8 @@ extern PedConstraint *ped_device_get_optimal_aligned_constraint( extern PedAlignment *ped_device_get_minimum_alignment(const PedDevice *dev); extern PedAlignment *ped_device_get_optimum_alignment(const PedDevice *dev); +extern int ped_device_like_dasd(const PedDevice *dev); + /* private stuff ;-) */ extern void _ped_device_probe (const char* path); diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c index 906298f..7eb6a9a 100644 --- a/libparted/arch/linux.c +++ b/libparted/arch/linux.c @@ -783,9 +783,13 @@ _device_set_sector_size (PedDevice* dev) #endif #if defined __s390__ || defined __s390x__ + /* The real_sector_size is currently needed for DASD layouts, + * so we set it unconditionally. In the long run it should + * be considered to use the dev->phys_sector_size in label/dasd.c. + */ + arch_specific->real_sector_size = dev->sector_size; /* Return PED_SECTOR_SIZE_DEFAULT for DASDs. */ if (dev->type == PED_DEVICE_DASD) { - arch_specific->real_sector_size = dev->sector_size; dev->sector_size = PED_SECTOR_SIZE_DEFAULT; } #endif @@ -3196,7 +3200,7 @@ linux_get_optimum_alignment(const PedDevice *dev) && PED_DEFAULT_ALIGNMENT % minimum_io == 0) ) { /* DASD needs to use minimum alignment */ - if (dev->type == PED_DEVICE_DASD) + if (ped_device_like_dasd(dev)) return linux_get_minimum_alignment(dev); return ped_alignment_new( diff --git a/libparted/device.c b/libparted/device.c index cdcc117..b207593 100644 --- a/libparted/device.c +++ b/libparted/device.c @@ -550,11 +550,9 @@ ped_device_get_optimum_alignment(const PedDevice *dev) /* If the arch specific code could not give as an alignment return a default value based on the type of device. */ if (align == NULL) { - switch (dev->type) { - case PED_DEVICE_DASD: + if (ped_device_like_dasd(dev)) align = ped_device_get_minimum_alignment(dev); - break; - default: + else { /* Align to a grain of 1MiB (like vista / win7) */ align = ped_alignment_new(0, (PED_DEFAULT_ALIGNMENT @@ -565,4 +563,30 @@ ped_device_get_optimum_alignment(const PedDevice *dev) return align; } +/** + * Check whether this device could be a DASD + * + * The device probing yields PED_DEVICE_DASD for native DASD transport + * If the block device uses a different transport (e.g. virtio) + * a simplified heuristic (assuming a model 3390 with 4K sectors) + * is applied (only) on s390x systems for this check. + * + * \return 1 if the geometry indicates this could be a DASD + * and 0 otherwise + */ +int ped_device_like_dasd(const PedDevice *dev) +{ +#if defined __s390__ || defined __s390x__ + return (dev->type == PED_DEVICE_DASD) || + (dev->hw_geom.heads == 15 && + dev->hw_geom.sectors == 12 && + (dev->hw_geom.cylinders * + dev->hw_geom.heads * + dev->hw_geom.sectors * dev->phys_sector_size == + dev->length * dev->sector_size)); +#else + return 0; +#endif +} + /** @} */ diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c index fa9414f..bb32d66 100644 --- a/libparted/labels/dasd.c +++ b/libparted/labels/dasd.c @@ -214,19 +214,13 @@ dasd_probe (const PedDevice *dev) PED_ASSERT(dev != NULL); - if (!(dev->type == PED_DEVICE_DASD - || dev->type == PED_DEVICE_VIODASD - || dev->type == PED_DEVICE_FILE)) - return 0; - arch_specific = LINUX_SPECIFIC(dev); /* add partition test here */ fdasd_initialize_anchor(&anchor); - fdasd_get_geometry(dev, &anchor, arch_specific->fd); - - fdasd_check_api_version(&anchor, arch_specific->fd); + if (fdasd_get_geometry(dev, &anchor, arch_specific->fd) == 0) + goto error_cleanup; /* Labels are required on CDL formatted DASDs. */ if (fdasd_check_volume(&anchor, arch_specific->fd) && @@ -276,7 +270,9 @@ dasd_read (PedDisk* disk) fdasd_initialize_anchor(&anchor); - fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd); + if (fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd) == 0) + goto error_close_dev; + disk_specific->label_block = anchor.label_block; if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE) @@ -630,7 +626,9 @@ dasd_write (const PedDisk* disk) /* initialize the anchor */ fdasd_initialize_anchor(&anchor); - fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd); + if (fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd) == 0) + goto error; + fdasd_check_volume(&anchor, arch_specific->fd); memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t)); anchor.vlabel_changed++; -- 1.7.1

