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 18:33:20 -0400 |
commit | 526f7c7950bbf1271e59177d70d74438c2ef96de (patch) | |
tree | 5e8550890534e73a307e53707d68ccbedaac62af /drivers/scsi/sd.c | |
parent | 3e51d3c924aea8a1f1372e6c615b0a37b528121d (diff) |
[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>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 13 |
1 files changed, 7 insertions, 6 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, | |||
1554 | } | 1554 | } |
1555 | 1555 | ||
1556 | /* Logical blocks per physical block exponent */ | 1556 | /* Logical blocks per physical block exponent */ |
1557 | sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size; | 1557 | sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size; |
1558 | 1558 | ||
1559 | /* Lowest aligned logical block */ | 1559 | /* Lowest aligned logical block */ |
1560 | alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size; | 1560 | 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, | |||
1567 | struct request_queue *q = sdp->request_queue; | 1567 | struct request_queue *q = sdp->request_queue; |
1568 | 1568 | ||
1569 | sdkp->thin_provisioning = 1; | 1569 | sdkp->thin_provisioning = 1; |
1570 | q->limits.discard_granularity = sdkp->hw_sector_size; | 1570 | q->limits.discard_granularity = sdkp->physical_block_size; |
1571 | q->limits.max_discard_sectors = 0xffffffff; | 1571 | q->limits.max_discard_sectors = 0xffffffff; |
1572 | 1572 | ||
1573 | if (buffer[14] & 0x40) /* TPRZ */ | 1573 | if (buffer[14] & 0x40) /* TPRZ */ |
@@ -1635,7 +1635,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, | |||
1635 | } | 1635 | } |
1636 | 1636 | ||
1637 | sdkp->capacity = lba + 1; | 1637 | sdkp->capacity = lba + 1; |
1638 | sdkp->hw_sector_size = sector_size; | 1638 | sdkp->physical_block_size = sector_size; |
1639 | return sector_size; | 1639 | return sector_size; |
1640 | } | 1640 | } |
1641 | 1641 | ||
@@ -1756,10 +1756,10 @@ got_data: | |||
1756 | (unsigned long long)sdkp->capacity, | 1756 | (unsigned long long)sdkp->capacity, |
1757 | sector_size, cap_str_10, cap_str_2); | 1757 | sector_size, cap_str_10, cap_str_2); |
1758 | 1758 | ||
1759 | if (sdkp->hw_sector_size != sector_size) | 1759 | if (sdkp->physical_block_size != sector_size) |
1760 | sd_printk(KERN_NOTICE, sdkp, | 1760 | sd_printk(KERN_NOTICE, sdkp, |
1761 | "%u-byte physical blocks\n", | 1761 | "%u-byte physical blocks\n", |
1762 | sdkp->hw_sector_size); | 1762 | sdkp->physical_block_size); |
1763 | } | 1763 | } |
1764 | } | 1764 | } |
1765 | 1765 | ||
@@ -1773,7 +1773,8 @@ got_data: | |||
1773 | else if (sector_size == 256) | 1773 | else if (sector_size == 256) |
1774 | sdkp->capacity >>= 1; | 1774 | sdkp->capacity >>= 1; |
1775 | 1775 | ||
1776 | blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size); | 1776 | blk_queue_physical_block_size(sdp->request_queue, |
1777 | sdkp->physical_block_size); | ||
1777 | sdkp->device->sector_size = sector_size; | 1778 | sdkp->device->sector_size = sector_size; |
1778 | } | 1779 | } |
1779 | 1780 | ||