Skip to content

Commit ea697a8

Browse files
scsi: sd: Fix optimal I/O size for devices that change reported values
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. Commit a83da8a ("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/[email protected] Cc: Bryan Gurney <[email protected]> Cc: <[email protected]> Reported-by: Bernhard Sulzer <[email protected]> Tested-by: Bernhard Sulzer <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 78c3e5e commit ea697a8

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/scsi/sd.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3169,9 +3169,11 @@ static int sd_revalidate_disk(struct gendisk *disk)
31693169
if (sd_validate_opt_xfer_size(sdkp, dev_max)) {
31703170
q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
31713171
rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
3172-
} else
3172+
} else {
3173+
q->limits.io_opt = 0;
31733174
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
31743175
(sector_t)BLK_DEF_MAX_SECTORS);
3176+
}
31753177

31763178
/* Do not exceed controller limit */
31773179
rw_max = min(rw_max, queue_max_hw_sectors(q));

0 commit comments

Comments
 (0)