summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@wdc.com>2017-09-05 20:55:35 +0900
committerMartin K. Petersen <martin.petersen@oracle.com>2017-09-25 15:36:40 -0400
commitb7af62a945706e32b987f1dd0cc86bb41a8210c3 (patch)
tree15df12bb5e5557b5663ed18a90831a30c8f24830 /drivers/scsi/sd.c
parentff6e88f193c654449bf222450553a7fa16a75ca7 (diff)
downloadlinux-b7af62a945706e32b987f1dd0cc86bb41a8210c3.tar.bz2
scsi: sd: Align maximum write same blocks to physical block size
Reporting a maximum number of blocks that is not aligned on the device physical size would cause a large write same request to be split into physically unaligned chunks by __blkdev_issue_write_zeroes() and __blkdev_issue_write_same(), even if the caller of these functions took care to align its request to physical sectors. Make sure the maximum reported is aligned to the device physical block size. This is only an optional optimization for regular disks, but this is mandatory to avoid failure of large write same requests directed at sequential write required zones of host-managed ZBC disks. [mkp: tweaked commit message] Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 11c1738c2100..3ef221493d6c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -898,6 +898,26 @@ static void sd_config_write_same(struct scsi_disk *sdkp)
else
sdkp->zeroing_mode = SD_ZERO_WRITE;
+ if (sdkp->max_ws_blocks &&
+ sdkp->physical_block_size > logical_block_size) {
+ /*
+ * Reporting a maximum number of blocks that is not aligned
+ * on the device physical size would cause a large write same
+ * request to be split into physically unaligned chunks by
+ * __blkdev_issue_write_zeroes() and __blkdev_issue_write_same()
+ * even if the caller of these functions took care to align the
+ * large request. So make sure the maximum reported is aligned
+ * to the device physical block size. This is only an optional
+ * optimization for regular disks, but this is mandatory to
+ * avoid failure of large write same requests directed at
+ * sequential write required zones of host-managed ZBC disks.
+ */
+ sdkp->max_ws_blocks =
+ round_down(sdkp->max_ws_blocks,
+ bytes_to_logical(sdkp->device,
+ sdkp->physical_block_size));
+ }
+
out:
blk_queue_max_write_same_sectors(q, sdkp->max_ws_blocks *
(logical_block_size >> 9));