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

Commit e28e5055 authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Greg Kroah-Hartman
Browse files

s390/dasd: Fix capacity calculation for large volumes



[ Upstream commit 2cc9637ce825f3a9f51f8f78af7474e9e85bfa5f ]

The DASD driver incorrectly limits the maximum number of blocks of ECKD
DASD volumes to 32 bit numbers. Volumes with a capacity greater than
2^32-1 blocks are incorrectly recognized as smaller volumes.

This results in the following volume capacity limits depending on the
formatted block size:

  BLKSIZE  MAX_GB   MAX_CYL
      512    2047   5843492c
     1024    4095   8676701
     2048    8191  13634816
     4096   16383  23860929

The same problem occurs when a volume with more than 17895697 cylinders
is accessed in raw-track-access mode.

Fix this problem by adding an explicit type cast when calculating the
maximum number of blocks.

Signed-off-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: default avatarStefan Haberland <sth@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent af5b7a15
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -2004,14 +2004,14 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
	blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
	blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);


raw:
raw:
	block->blocks = (private->real_cyl *
	block->blocks = ((unsigned long) private->real_cyl *
			  private->rdc_data.trk_per_cyl *
			  private->rdc_data.trk_per_cyl *
			  blk_per_trk);
			  blk_per_trk);


	dev_info(&device->cdev->dev,
	dev_info(&device->cdev->dev,
		 "DASD with %d KB/block, %d KB total size, %d KB/track, "
		 "DASD with %u KB/block, %lu KB total size, %u KB/track, "
		 "%s\n", (block->bp_block >> 10),
		 "%s\n", (block->bp_block >> 10),
		 ((private->real_cyl *
		 (((unsigned long) private->real_cyl *
		   private->rdc_data.trk_per_cyl *
		   private->rdc_data.trk_per_cyl *
		   blk_per_trk * (block->bp_block >> 9)) >> 1),
		   blk_per_trk * (block->bp_block >> 9)) >> 1),
		 ((blk_per_trk * block->bp_block) >> 10),
		 ((blk_per_trk * block->bp_block) >> 10),