Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf1a95a2 authored by Stefan Haberland's avatar Stefan Haberland Committed by Martin Schwidefsky
Browse files

[S390] fixed cdl-format detection.



CDL formated DASDs are now detected correctly even if no VOL1 label is
on the disk. This prevents possible loss of data.

Signed-off-by: default avatarStefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 83119ad4
Loading
Loading
Loading
Loading
+97 −70
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
{
	int blocksize, offset, size,res;
	loff_t i_size;
	dasd_information_t *info;
	dasd_information2_t *info;
	struct hd_geometry *geo;
	char type[5] = {0,};
	char name[7] = {0,};
@@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
	if (i_size == 0)
		goto out_exit;

	if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
	info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL);
	if (info == NULL)
		goto out_exit;
	if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
	geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL);
	if (geo == NULL)
		goto out_nogeo;
	if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL)
	label = kmalloc(sizeof(union label_t), GFP_KERNEL);
	if (label == NULL)
		goto out_nolab;

	if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
	if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 ||
	    ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
		goto out_freeall;

@@ -96,8 +99,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
	res = 1;

	/*
	 * Three different types: CMS1, VOL1 and LNX1/unlabeled
	 * Three different formats: LDL, CDL and unformated disk
	 *
	 * identified by info->format
	 *
	 * unformated disks we do not have to care about
	 */
	if (info->format == DASD_FORMAT_LDL) {
		if (strncmp(type, "CMS1", 4) == 0) {
			/*
			 * VM style CMS1 labeled disk
@@ -107,32 +115,52 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
				/* disk is reserved minidisk */
				blocksize = label->cms.block_size;
				offset = label->cms.disk_offset;
			size = (label->cms.block_count - 1) * (blocksize >> 9);
				size = (label->cms.block_count - 1)
					* (blocksize >> 9);
			} else {
				printk("CMS1/%8s:", name);
				offset = (info->label_block + 1);
				size = i_size >> 9;
			}
		} else {
			/*
			 * Old style LNX1 or unlabeled disk
			 */
			if (strncmp(type, "LNX1", 4) == 0)
				printk ("LNX1/%8s:", name);
			else
				printk("(nonl)");
			offset = (info->label_block + 1);
			size = i_size >> 9;
		}
		put_partition(state, 1, offset*(blocksize >> 9),
				      size-offset*(blocksize >> 9));
	} else if ((strncmp(type, "VOL1", 4) == 0) &&
		(!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
	} else if (info->format == DASD_FORMAT_CDL) {
		/*
		 * New style VOL1 labeled disk
		 * New style CDL formatted disk
		 */
		unsigned int blk;
		int counter;

		/*
		 * check if VOL1 label is available
		 * if not, something is wrong, skipping partition detection
		 */
		if (strncmp(type, "VOL1",  4) == 0) {
			printk("VOL1/%8s:", name);

		/* get block number and read then go through format1 labels */
			/*
			 * get block number and read then go through format1
			 * labels
			 */
			blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
			counter = 0;
		while ((data = read_dev_sector(bdev, blk*(blocksize/512),
					       &sect)) != NULL) {
			data = read_dev_sector(bdev, blk * (blocksize/512),
					       &sect);
			while (data != NULL) {
				struct vtoc_format1_label f1;

			memcpy(&f1, data, sizeof(struct vtoc_format1_label));
				memcpy(&f1, data,
				       sizeof(struct vtoc_format1_label));
				put_dev_sector(sect);

				/* skip FMT4 / FMT5 / FMT7 labels */
@@ -140,6 +168,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
				    || f1.DS1FMTID == _ascebc['5']
				    || f1.DS1FMTID == _ascebc['7']) {
					blk++;
					data = read_dev_sector(bdev, blk *
							       (blocksize/512),
								&sect);
					continue;
				}

@@ -158,22 +189,18 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
					      size * (blocksize >> 9));
				counter++;
				blk++;
				data = read_dev_sector(bdev,
						       blk * (blocksize/512),
						       &sect);
			}

			if (!data)
				/* Are we not supposed to report this ? */
				goto out_readerr;
	} else {
		/*
		 * Old style LNX1 or unlabeled disk
		 */
		if (strncmp(type, "LNX1", 4) == 0)
			printk ("LNX1/%8s:", name);
		else
			printk("(nonl)/%8s:", name);
		offset = (info->label_block + 1);
		size = i_size >> 9;
		put_partition(state, 1, offset*(blocksize >> 9),
			      size-offset*(blocksize >> 9));
		} else
			printk(KERN_WARNING "Warning, expected Label VOL1 not "
			       "found, treating as CDL formated Disk");

	}

	printk("\n");