提交 526f7c79 编写于 作者: M Martin K. Petersen 提交者: James Bottomley

[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: NMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
上级 3e51d3c9
...@@ -1554,7 +1554,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, ...@@ -1554,7 +1554,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
} }
/* Logical blocks per physical block exponent */ /* 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 */ /* Lowest aligned logical block */
alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size; 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,7 +1567,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
struct request_queue *q = sdp->request_queue; struct request_queue *q = sdp->request_queue;
sdkp->thin_provisioning = 1; 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; q->limits.max_discard_sectors = 0xffffffff;
if (buffer[14] & 0x40) /* TPRZ */ if (buffer[14] & 0x40) /* TPRZ */
...@@ -1635,7 +1635,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, ...@@ -1635,7 +1635,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
} }
sdkp->capacity = lba + 1; sdkp->capacity = lba + 1;
sdkp->hw_sector_size = sector_size; sdkp->physical_block_size = sector_size;
return sector_size; return sector_size;
} }
...@@ -1756,10 +1756,10 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) ...@@ -1756,10 +1756,10 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
(unsigned long long)sdkp->capacity, (unsigned long long)sdkp->capacity,
sector_size, cap_str_10, cap_str_2); 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, sd_printk(KERN_NOTICE, sdkp,
"%u-byte physical blocks\n", "%u-byte physical blocks\n",
sdkp->hw_sector_size); sdkp->physical_block_size);
} }
} }
...@@ -1773,7 +1773,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) ...@@ -1773,7 +1773,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
else if (sector_size == 256) else if (sector_size == 256)
sdkp->capacity >>= 1; 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; sdkp->device->sector_size = sector_size;
} }
......
...@@ -51,7 +51,7 @@ struct scsi_disk { ...@@ -51,7 +51,7 @@ struct scsi_disk {
atomic_t openers; atomic_t openers;
sector_t capacity; /* size in 512-byte sectors */ sector_t capacity; /* size in 512-byte sectors */
u32 index; u32 index;
unsigned short hw_sector_size; unsigned int physical_block_size;
u8 media_present; u8 media_present;
u8 write_prot; u8 write_prot;
u8 protection_type;/* Data Integrity Field */ u8 protection_type;/* Data Integrity Field */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册