diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2010-09-28 14:48:47 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-10-11 17:33:20 -0500 |
commit | 526f7c7950bbf1271e59177d70d74438c2ef96de (patch) | |
tree | 5e8550890534e73a307e53707d68ccbedaac62af | |
parent | 3e51d3c924aea8a1f1372e6c615b0a37b528121d (diff) | |
download | linux-526f7c7950bbf1271e59177d70d74438c2ef96de.tar.bz2 |
[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 <martin.petersen@oracle.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r-- | drivers/scsi/sd.c | 13 | ||||
-rw-r--r-- | 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 */ |