aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin K. Petersen <martin.petersen@oracle.com>2017-04-04 10:42:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-21 03:31:21 -0400
commit08383b004426591502b86bfacdc638d85cedf26c (patch)
tree699f2650c7c381fc1fc08122de863c516a34c1ed
parent64e746983c4c8c88393866485cbca1782071aeb1 (diff)
scsi: sd: Fix capacity calculation with 32-bit sector_t
commit 7c856152cb92f8eee2df29ef325a1b1f43161aff upstream. We previously made sure that the reported disk capacity was less than 0xffffffff blocks when the kernel was not compiled with large sector_t support (CONFIG_LBDAF). However, this check assumed that the capacity was reported in units of 512 bytes. Add a sanity check function to ensure that we only enable disks if the entire reported capacity can be expressed in terms of sector_t. Reported-by: Steve Magnani <steve.magnani@digidescorp.com> Cc: Bart Van Assche <Bart.VanAssche@sandisk.com> Reviewed-by: Bart Van Assche <Bart.VanAssche@sandisk.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/scsi/sd.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e0796b2e0d2f..931af0793951 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2057,6 +2057,22 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
2057 2057
2058#define READ_CAPACITY_RETRIES_ON_RESET 10 2058#define READ_CAPACITY_RETRIES_ON_RESET 10
2059 2059
2060/*
2061 * Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set
2062 * and the reported logical block size is bigger than 512 bytes. Note
2063 * that last_sector is a u64 and therefore logical_to_sectors() is not
2064 * applicable.
2065 */
2066static bool sd_addressable_capacity(u64 lba, unsigned int sector_size)
2067{
2068 u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9);
2069
2070 if (sizeof(sector_t) == 4 && last_sector > U32_MAX)
2071 return false;
2072
2073 return true;
2074}
2075
2060static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, 2076static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
2061 unsigned char *buffer) 2077 unsigned char *buffer)
2062{ 2078{
@@ -2122,7 +2138,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
2122 return -ENODEV; 2138 return -ENODEV;
2123 } 2139 }
2124 2140
2125 if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) { 2141 if (!sd_addressable_capacity(lba, sector_size)) {
2126 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " 2142 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
2127 "kernel compiled with support for large block " 2143 "kernel compiled with support for large block "
2128 "devices.\n"); 2144 "devices.\n");
@@ -2208,7 +2224,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
2208 return sector_size; 2224 return sector_size;
2209 } 2225 }
2210 2226
2211 if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) { 2227 if (!sd_addressable_capacity(lba, sector_size)) {
2212 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a " 2228 sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
2213 "kernel compiled with support for large block " 2229 "kernel compiled with support for large block "
2214 "devices.\n"); 2230 "devices.\n");