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,8 +99,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -96,8 +99,13 @@ 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 (info->format == DASD_FORMAT_LDL) {
if (strncmp(type, "CMS1", 4) == 0) { if (strncmp(type, "CMS1", 4) == 0) {
/* /*
* VM style CMS1 labeled disk * VM style CMS1 labeled disk
...@@ -107,32 +115,52 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -107,32 +115,52 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
/* disk is reserved minidisk */ /* disk is reserved minidisk */
blocksize = label->cms.block_size; blocksize = label->cms.block_size;
offset = label->cms.disk_offset; offset = label->cms.disk_offset;
size = (label->cms.block_count - 1) * (blocksize >> 9); size = (label->cms.block_count - 1)
* (blocksize >> 9);
} else { } else {
printk("CMS1/%8s:", name); printk("CMS1/%8s:", name);
offset = (info->label_block + 1); offset = (info->label_block + 1);
size = i_size >> 9; 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), 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;
/*
* check if VOL1 label is available
* if not, something is wrong, skipping partition detection
*/
if (strncmp(type, "VOL1", 4) == 0) {
printk("VOL1/%8s:", name); 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; blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
counter = 0; counter = 0;
while ((data = read_dev_sector(bdev, blk*(blocksize/512), data = read_dev_sector(bdev, blk * (blocksize/512),
&sect)) != NULL) { &sect);
while (data != NULL) {
struct vtoc_format1_label f1; 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); put_dev_sector(sect);
/* skip FMT4 / FMT5 / FMT7 labels */ /* skip FMT4 / FMT5 / FMT7 labels */
...@@ -140,6 +168,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -140,6 +168,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
|| f1.DS1FMTID == _ascebc['5'] || f1.DS1FMTID == _ascebc['5']
|| f1.DS1FMTID == _ascebc['7']) { || f1.DS1FMTID == _ascebc['7']) {
blk++; blk++;
data = read_dev_sector(bdev, blk *
(blocksize/512),
&sect);
continue; continue;
} }
...@@ -158,22 +189,18 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) ...@@ -158,22 +189,18 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
size * (blocksize >> 9)); size * (blocksize >> 9));
counter++; counter++;
blk++; blk++;
data = read_dev_sector(bdev,
blk * (blocksize/512),
&sect);
} }
if (!data) if (!data)
/* Are we not supposed to report this ? */ /* Are we not supposed to report this ? */
goto out_readerr; goto out_readerr;
} else { } else
/* printk(KERN_WARNING "Warning, expected Label VOL1 not "
* Old style LNX1 or unlabeled disk "found, treating as CDL formated 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));
} }
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