]> git.proxmox.com Git - pve-kernel-jessie.git/blob - sd-fix-rw_max.patch
sd: Fix rw_max for devices that report an optimal xfer size
[pve-kernel-jessie.git] / sd-fix-rw_max.patch
1 From 6b7e9cde49691e04314342b7dce90c67ad567fcc Mon Sep 17 00:00:00 2001
2 From: "Martin K. Petersen" <martin.petersen@oracle.com>
3 Date: Thu, 12 May 2016 22:17:34 -0400
4 Subject: sd: Fix rw_max for devices that report an optimal xfer size
5
6 For historic reasons, io_opt is in bytes and max_sectors in block layer
7 sectors. This interface inconsistency is error prone and should be
8 fixed. But for 4.4--4.7 let's make the unit difference explicit via a
9 wrapper function.
10
11 Fixes: d0eb20a863ba ("sd: Optimal I/O size is in bytes, not sectors")
12 Cc: stable@vger.kernel.org # 4.4+
13 Reported-by: Fam Zheng <famz@redhat.com>
14 Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
15 Reviewed-by: Christoph Hellwig <hch@lst.de>
16 Tested-by: Andrew Patterson <andrew.patterson@hpe.com>
17 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
18 ---
19 drivers/scsi/sd.c | 8 ++++----
20 drivers/scsi/sd.h | 5 +++++
21 2 files changed, 9 insertions(+), 4 deletions(-)
22
23 diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
24 index f459dff..60bff78 100644
25 --- a/drivers/scsi/sd.c
26 +++ b/drivers/scsi/sd.c
27 @@ -2867,10 +2867,10 @@ static int sd_revalidate_disk(struct gendisk *disk)
28 if (sdkp->opt_xfer_blocks &&
29 sdkp->opt_xfer_blocks <= dev_max &&
30 sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS &&
31 - sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_CACHE_SIZE)
32 - rw_max = q->limits.io_opt =
33 - sdkp->opt_xfer_blocks * sdp->sector_size;
34 - else
35 + logical_to_bytes(sdp, sdkp->opt_xfer_blocks) >= PAGE_SIZE) {
36 + q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
37 + rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
38 + } else
39 rw_max = BLK_DEF_MAX_SECTORS;
40
41 /* Combine with controller limits */
42 diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
43 index 654630b..765a6f1 100644
44 --- a/drivers/scsi/sd.h
45 +++ b/drivers/scsi/sd.h
46 @@ -151,6 +151,11 @@ static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blo
47 return blocks << (ilog2(sdev->sector_size) - 9);
48 }
49
50 +static inline unsigned int logical_to_bytes(struct scsi_device *sdev, sector_t blocks)
51 +{
52 + return blocks * sdev->sector_size;
53 +}
54 +
55 /*
56 * A DIF-capable target device can be formatted with different
57 * protection schemes. Currently 0 through 3 are defined:
58 --
59 cgit v0.12
60