summaryrefslogtreecommitdiffstats
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 17:33:20 -0500
commit526f7c7950bbf1271e59177d70d74438c2ef96de (patch)
tree5e8550890534e73a307e53707d68ccbedaac62af
parent3e51d3c924aea8a1f1372e6c615b0a37b528121d (diff)
downloadlinux-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.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,
}
/* 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 */