diff options
author | Martin K. Petersen <martin.petersen@oracle.com> | 2017-04-04 10:42:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-21 03:31:21 -0400 |
commit | 08383b004426591502b86bfacdc638d85cedf26c (patch) | |
tree | 699f2650c7c381fc1fc08122de863c516a34c1ed | |
parent | 64e746983c4c8c88393866485cbca1782071aeb1 (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.c | 20 |
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 | */ | ||
2066 | static 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 | |||
2060 | static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, | 2076 | static 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"); |