mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 06:10:56 +00:00
scsi: sd: Fix optimal I/O size for devices that change reported values
commitea697a8bf5
upstream. Some USB bridge devices will return a default set of characteristics during initialization. And then, once an attached drive has spun up, substitute the actual parameters reported by the drive. According to the SCSI spec, the device should return a UNIT ATTENTION in case any reported parameters change. But in this case the change is made silently after a small window where default values are reported. Commita83da8a450
("scsi: sd: Optimal I/O size should be a multiple of physical block size") validated the reported optimal I/O size against the physical block size to overcome problems with devices reporting nonsensical transfer sizes. However, this validation did not account for the fact that aforementioned devices will return default values during a brief window during spin-up. The subsequent change in reported characteristics would invalidate the checking that had previously been performed. Unset a previously configured optimal I/O size should the sanity checking fail on subsequent revalidate attempts. Link: https://lore.kernel.org/r/33fb522e-4f61-1b76-914f-c9e6a3553c9b@gmail.com Cc: Bryan Gurney <bgurney@redhat.com> Cc: <stable@vger.kernel.org> Reported-by: Bernhard Sulzer <micraft.b@gmail.com> Tested-by: Bernhard Sulzer <micraft.b@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
621f2ded60
commit
d500b06031
1 changed files with 3 additions and 1 deletions
|
@ -3210,9 +3210,11 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
|||
if (sd_validate_opt_xfer_size(sdkp, dev_max)) {
|
||||
q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
|
||||
rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
|
||||
} else
|
||||
} else {
|
||||
q->limits.io_opt = 0;
|
||||
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
|
||||
(sector_t)BLK_DEF_MAX_SECTORS);
|
||||
}
|
||||
|
||||
/* Do not exceed controller limit */
|
||||
rw_max = min(rw_max, queue_max_hw_sectors(q));
|
||||
|
|
Loading…
Reference in a new issue