aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2010-09-28 14:48:47 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-11 18:33:20 -0400
commit526f7c7950bbf1271e59177d70d74438c2ef96de (patch)
tree5e8550890534e73a307e53707d68ccbedaac62af /drivers
parent3e51d3c924aea8a1f1372e6c615b0a37b528121d (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')
-rw-r--r--drivers/scsi/sd.c13
-rw-r--r--drivers/scsi/sd.h2
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,
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
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 {
51 atomic_t openers; 51 atomic_t openers;
52 sector_t capacity; /* size in 512-byte sectors */ 52 sector_t capacity; /* size in 512-byte sectors */
53 u32 index; 53 u32 index;
54 unsigned short hw_sector_size; 54 unsigned int physical_block_size;
55 u8 media_present; 55 u8 media_present;
56 u8 write_prot; 56 u8 write_prot;
57 u8 protection_type;/* Data Integrity Field */ 57 u8 protection_type;/* Data Integrity Field */