dasd_write(), was reading the volume label from the disk (trough fdasd_check_volume()) and later writing it back again, this is fine for existing dasd labels, but when creating a fresh label, this would also cause the old volume label to be re-used, and if the old label was corrupt, it would cause fdasd_check_volume() and thus dasd_write() to fail.
* libparted/arch/linux.c (toplevel): include fdasd.h. (init_dasd): Do BIODASDINFO ioctl, and store the dasd devno in arch_specific. (init_dasd): Remove dead (never reached) code. * libparted/arch/linux.h (struct _LinuxSpecific): Add devno member. * libparted/labels/dasd.c (DasdDiskSpecific): add vlabel member. (dasd_alloc): Init DasdDiskSpecific.vlabel for fresh disks (dasd_read): Store read vlabel in DasdDiskSpecific.vlabel. (dasd_write): Write DasdDiskSpecific.vlabel instead of on disk vlabel. --- libparted/arch/linux.c | 16 +++++++++++----- libparted/arch/linux.h | 1 + libparted/labels/dasd.c | 20 ++++++++++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c index d5d3597..18bdb0d 100644 --- a/libparted/arch/linux.c +++ b/libparted/arch/linux.c @@ -22,6 +22,9 @@ #include <parted/parted.h> #include <parted/debug.h> +#if defined __s390__ || defined __s390x__ +#include <parted/fdasd.h> +#endif #include <ctype.h> #include <errno.h> @@ -1090,7 +1093,7 @@ init_dasd (PedDevice* dev, const char* model_name) { struct stat dev_stat; struct hd_geometry geo; - char *errstr = 0; + dasd_information_t dasd_info; if (!_device_stat (dev, &dev_stat)) goto error; @@ -1126,15 +1129,18 @@ init_dasd (PedDevice* dev, const char* model_name) dev->hw_geom = dev->bios_geom; } + if (!ioctl(arch_specific->fd, BIODASDINFO, &dasd_info)) { + arch_specific->devno = dasd_info.devno; + } else { + arch_specific->devno = arch_specific->major * 256 + + arch_specific->minor; + } + dev->model = strdup (model_name); ped_device_close (dev); return 1; - ped_exception_throw ( PED_EXCEPTION_ERROR, - PED_EXCEPTION_IGNORE_CANCEL, - errstr ); - error_close_dev: ped_device_close (dev); error: diff --git a/libparted/arch/linux.h b/libparted/arch/linux.h index 7036886..dc4e076 100644 --- a/libparted/arch/linux.h +++ b/libparted/arch/linux.h @@ -33,6 +33,7 @@ struct _LinuxSpecific { char* dmtype; /**< device map target type */ #if defined __s390__ || defined __s390x__ unsigned int real_sector_size; + unsigned int devno; #endif #if USE_BLKID blkid_probe probe; diff --git a/libparted/labels/dasd.c b/libparted/labels/dasd.c index 56b8131..d5392d9 100644 --- a/libparted/labels/dasd.c +++ b/libparted/labels/dasd.c @@ -70,6 +70,7 @@ typedef struct { typedef struct { unsigned int format_type; + volume_label_t vlabel; } DasdDiskSpecific; static int dasd_probe (const PedDevice *dev); @@ -146,6 +147,7 @@ dasd_alloc (const PedDevice* dev) PedDisk* disk; LinuxSpecific* arch_specific; DasdDiskSpecific *disk_specific; + char volser[7]; PED_ASSERT (dev != NULL, return NULL); @@ -163,6 +165,15 @@ dasd_alloc (const PedDevice* dev) /* CDL format, newer */ disk_specific->format_type = 2; + /* Setup volume label (for fresh disks) */ + snprintf(volser, sizeof(volser), "0X%04X", arch_specific->devno); + vtoc_volume_label_init(&disk_specific->vlabel); + vtoc_volume_label_set_key(&disk_specific->vlabel, "VOL1"); + vtoc_volume_label_set_label(&disk_specific->vlabel, "VOL1"); + vtoc_volume_label_set_volser(&disk_specific->vlabel, volser); + vtoc_set_cchhb(&disk_specific->vlabel.vtoc, + VTOC_START_CC, VTOC_START_HH, 0x01); + return disk; } @@ -296,6 +307,9 @@ dasd_read (PedDisk* disk) if (fdasd_check_volume(&anchor, arch_specific->fd)) goto error_close_dev; + /* 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++; @@ -556,10 +570,8 @@ dasd_write (const PedDisk* disk) /* initialize the anchor */ fdasd_initialize_anchor(&anchor); fdasd_get_geometry(&anchor, arch_specific->fd); - - /* check dasd for labels and vtoc */ - if (fdasd_check_volume(&anchor, arch_specific->fd)) - goto error; + memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t)); + anchor.vlabel_changed++; if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE) anchor.big_disk++; -- 1.6.5.2 _______________________________________________ bug-parted mailing list bug-parted@gnu.org http://lists.gnu.org/mailman/listinfo/bug-parted