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

[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
...@@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
{ {
int blocksize, offset, size,res; int blocksize, offset, size,res;
loff_t i_size; loff_t i_size;
dasd_information_t *info; dasd_information2_t *info;
struct hd_geometry *geo; struct hd_geometry *geo;
char type[5] = {0,}; char type[5] = {0,};
char name[7] = {0,}; char name[7] = {0,};
...@@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
if (i_size == 0) if (i_size == 0)
goto out_exit; 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; 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; 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; 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) ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
goto out_freeall; goto out_freeall;
...@@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
res = 1; 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 (strncmp(type, "CMS1", 4) == 0) { if (info->format == DASD_FORMAT_LDL) {
/* if (strncmp(type, "CMS1", 4) == 0) {
* VM style CMS1 labeled disk /*
*/ * VM style CMS1 labeled disk
if (label->cms.disk_offset != 0) { */
printk("CMS1/%8s(MDSK):", name); if (label->cms.disk_offset != 0) {
/* disk is reserved minidisk */ printk("CMS1/%8s(MDSK):", name);
blocksize = label->cms.block_size; /* disk is reserved minidisk */
offset = label->cms.disk_offset; blocksize = label->cms.block_size;
size = (label->cms.block_count - 1) * (blocksize >> 9); offset = label->cms.disk_offset;
size = (label->cms.block_count - 1)
* (blocksize >> 9);
} else {
printk("CMS1/%8s:", name);
offset = (info->label_block + 1);
size = i_size >> 9;
}
} else { } else {
printk("CMS1/%8s:", name); /*
* Old style LNX1 or unlabeled disk
*/
if (strncmp(type, "LNX1", 4) == 0)
printk ("LNX1/%8s:", name);
else
printk("(nonl)");
offset = (info->label_block + 1); offset = (info->label_block + 1);
size = i_size >> 9; size = i_size >> 9;
} }
put_partition(state, 1, offset*(blocksize >> 9), put_partition(state, 1, offset*(blocksize >> 9),
size-offset*(blocksize >> 9)); size-offset*(blocksize >> 9));
} else if ((strncmp(type, "VOL1", 4) == 0) && } else if (info->format == DASD_FORMAT_CDL) {
(!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) {
/* /*
* New style VOL1 labeled disk * New style CDL formatted disk
*/ */
unsigned int blk; unsigned int blk;
int counter; int counter;
printk("VOL1/%8s:", name);
/* 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) {
struct vtoc_format1_label f1;
memcpy(&f1, data, sizeof(struct vtoc_format1_label));
put_dev_sector(sect);
/* skip FMT4 / FMT5 / FMT7 labels */
if (f1.DS1FMTID == _ascebc['4']
|| f1.DS1FMTID == _ascebc['5']
|| f1.DS1FMTID == _ascebc['7']) {
blk++;
continue;
}
/* only FMT1 valid at this point */
if (f1.DS1FMTID != _ascebc['1'])
break;
/* OK, we got valid partition data */
offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
size = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
offset + geo->sectors;
if (counter >= state->limit)
break;
put_partition(state, counter + 1,
offset * (blocksize >> 9),
size * (blocksize >> 9));
counter++;
blk++;
}
if (!data)
/* Are we not supposed to report this ? */
goto out_readerr;
} else {
/* /*
* Old style LNX1 or unlabeled disk * check if VOL1 label is available
* if not, something is wrong, skipping partition detection
*/ */
if (strncmp(type, "LNX1", 4) == 0) if (strncmp(type, "VOL1", 4) == 0) {
printk ("LNX1/%8s:", name); printk("VOL1/%8s:", name);
else /*
printk("(nonl)/%8s:", name); * get block number and read then go through format1
offset = (info->label_block + 1); * labels
size = i_size >> 9; */
put_partition(state, 1, offset*(blocksize >> 9), blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
size-offset*(blocksize >> 9)); counter = 0;
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));
put_dev_sector(sect);
/* skip FMT4 / FMT5 / FMT7 labels */
if (f1.DS1FMTID == _ascebc['4']
|| f1.DS1FMTID == _ascebc['5']
|| f1.DS1FMTID == _ascebc['7']) {
blk++;
data = read_dev_sector(bdev, blk *
(blocksize/512),
&sect);
continue;
}
/* only FMT1 valid at this point */
if (f1.DS1FMTID != _ascebc['1'])
break;
/* OK, we got valid partition data */
offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
size = cchh2blk(&f1.DS1EXT1.ulimit, geo) -
offset + geo->sectors;
if (counter >= state->limit)
break;
put_partition(state, counter + 1,
offset * (blocksize >> 9),
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
printk(KERN_WARNING "Warning, expected Label VOL1 not "
"found, treating as CDL formated Disk");
} }
printk("\n"); printk("\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment