From 526f7c7950bbf1271e59177d70d74438c2ef96de Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 28 Sep 2010 14:48:47 -0400 Subject: [SCSI] sd: Fix overflow with big physical blocks The hw_sector_size variable could overflow if a device reported huge physical blocks. Switch to the more accurate physical_block_size terminology and make sure we use an unsigned int to match the range permitted by READ CAPACITY(16). Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 13 +++++++------ drivers/scsi/sd.h | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 50f1fe605303..08b60dda8bcf 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1554,7 +1554,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, } /* Logical blocks per physical block exponent */ - sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size; + sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size; /* Lowest aligned logical block */ alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size; @@ -1567,7 +1567,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, struct request_queue *q = sdp->request_queue; sdkp->thin_provisioning = 1; - q->limits.discard_granularity = sdkp->hw_sector_size; + q->limits.discard_granularity = sdkp->physical_block_size; q->limits.max_discard_sectors = 0xffffffff; if (buffer[14] & 0x40) /* TPRZ */ @@ -1635,7 +1635,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, } sdkp->capacity = lba + 1; - sdkp->hw_sector_size = sector_size; + sdkp->physical_block_size = sector_size; return sector_size; } @@ -1756,10 +1756,10 @@ got_data: (unsigned long long)sdkp->capacity, sector_size, cap_str_10, cap_str_2); - if (sdkp->hw_sector_size != sector_size) + if (sdkp->physical_block_size != sector_size) sd_printk(KERN_NOTICE, sdkp, "%u-byte physical blocks\n", - sdkp->hw_sector_size); + sdkp->physical_block_size); } } @@ -1773,7 +1773,8 @@ got_data: else if (sector_size == 256) sdkp->capacity >>= 1; - blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size); + blk_queue_physical_block_size(sdp->request_queue, + sdkp->physical_block_size); sdkp->device->sector_size = sector_size; } diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index a40730ee465c..55488faf0815 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -51,7 +51,7 @@ struct scsi_disk { atomic_t openers; sector_t capacity; /* size in 512-byte sectors */ u32 index; - unsigned short hw_sector_size; + unsigned int physical_block_size; u8 media_present; u8 write_prot; u8 protection_type;/* Data Integrity Field */ -- cgit v1.2.3