aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2010-07-19 09:22:35 +0200
committerPaul Gortmaker <paul.gortmaker@windriver.com>2011-01-06 18:08:04 -0500
commitc8f7a02386859e42e02d10f05f8c641bb165d373 (patch)
tree14a826a3dbeab6bffa3b48dd03a400704644813d
parent00a0f4383a9f15cec62905e25b97c4e76c001fb8 (diff)
dasd: use correct label location for diag fba disks
commit cffab6bc5511cd6f67a60bf16b62de4267b68c4c upstream. Partition boundary calculation fails for DASD FBA disks under the following conditions: - disk is formatted with CMS FORMAT with a blocksize of more than 512 bytes - all of the disk is reserved to a single CMS file using CMS RESERVE - the disk is accessed using the DIAG mode of the DASD driver Under these circumstances, the partition detection code tries to read the CMS label block containing partition-relevant information from logical block offset 1, while it is in fact located at physical block offset 1. Fix this problem by using the correct CMS label block location depending on the device type as determined by the DASD SENSE ID information. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--fs/partitions/ibm.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index fc71aab0846..bae725b7feb 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -74,6 +74,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
} *label;
unsigned char *data;
Sector sect;
+ sector_t labelsect;
res = 0;
blocksize = bdev_logical_block_size(bdev);
@@ -98,9 +99,19 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
goto out_freeall;
/*
+ * Special case for FBA disks: label sector does not depend on
+ * blocksize.
+ */
+ if ((info->cu_type == 0x6310 && info->dev_type == 0x9336) ||
+ (info->cu_type == 0x3880 && info->dev_type == 0x3370))
+ labelsect = info->label_block;
+ else
+ labelsect = info->label_block * (blocksize >> 9);
+
+ /*
* Get volume label, extract name and type.
*/
- data = read_dev_sector(bdev, info->label_block*(blocksize/512), &sect);
+ data = read_dev_sector(bdev, labelsect, &sect);
if (data == NULL)
goto out_readerr;