[SCSI] sd: Fix overflow with big physical blocks
authorMartin K. Petersen <martin.petersen@oracle.com>
Tue, 28 Sep 2010 18:48:47 +0000 (14:48 -0400)
committerJames Bottomley <James.Bottomley@suse.de>
Mon, 11 Oct 2010 22:33:20 +0000 (17:33 -0500)
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>
drivers/scsi/sd.c
drivers/scsi/sd.h

index 50f1fe6053030952846b8c25f0628c31c4efc012..08b60dda8bcf53142a8527e3123d0e611fd02474 100644 (file)
@@ -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;
 }
 
index a40730ee465ce1021f9799afce67ec15afa41023..55488faf0815159ee781ae791e7e4cdff5bf635f 100644 (file)
@@ -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 */