diff mbox series

[v2] scsi: sd_zbc: Fix sd_zbc_report_zones() buffer allocation

Message ID 20190214060118.15255-1-damien.lemoal@wdc.com (mailing list archive)
State Mainlined
Commit 515ce60613128be7a176a8b82b20c7624f3b440d
Headers show
Series [v2] scsi: sd_zbc: Fix sd_zbc_report_zones() buffer allocation | expand

Commit Message

Damien Le Moal Feb. 14, 2019, 6:01 a.m. UTC
From: Masato Suzuki <masato.suzuki@wdc.com>

The function sd_zbc_do_report_zones() issues a REPORT ZONES command
with a buffer size calculated based on the number of zones requested
by the caller. This value should however not exceed the capabilities
of the hardware maximum command size, that is, should not exceed the
max_hw_sectors limit of the device. This problem leads to failures of
report zones commands when re-validating disks with some SAS HBAs.

Fix this by limiting a report zone command buffer size to the minimum
of the device max_hw_sectors and calculated value based on the
requested number of zones. This does not change the semantic of the
report_zones file operation as report zones can always return less
zone reports than requested. Short reports are handled using a loop
execution of the report_zones file operation in the function
blk_report_zones().

[Damien]
Before patch 'e76239a3748c ("block: add a report_zones method")',
report zones buffer allocation was limited to max_sectors when
allocated in blk_report_zones(). This however does not consider the
actual format of the device reply which is interface dependent.
Limiting the allocation based on the size of the expected reply format
rather than the size of the array of generic sturct blkzone passed by
blk_report_zones() makes more sense.

Fixes: e76239a3748c ("block: add a report_zones method")
Cc: stable@vger.kernel.org
Signed-off-by: Masato Suzuki <masato.suzuki@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
---

Changes from v1:
* Use queue_max_hw_sectors() instead of queue_max_sectors()

 drivers/scsi/sd_zbc.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

Comments

Martin K. Petersen Feb. 16, 2019, 3:10 a.m. UTC | #1
Damien,

> The function sd_zbc_do_report_zones() issues a REPORT ZONES command
> with a buffer size calculated based on the number of zones requested
> by the caller. This value should however not exceed the capabilities
> of the hardware maximum command size, that is, should not exceed the
> max_hw_sectors limit of the device. This problem leads to failures of
> report zones commands when re-validating disks with some SAS HBAs.

Applied to 5.0/scsi-fixes, thanks!
diff mbox series

Patch

diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index fff86940388b..a340af797a85 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -142,10 +142,12 @@  int sd_zbc_report_zones(struct gendisk *disk, sector_t sector,
 		return -EOPNOTSUPP;
 
 	/*
-	 * Get a reply buffer for the number of requested zones plus a header.
-	 * For ATA, buffers must be aligned to 512B.
+	 * Get a reply buffer for the number of requested zones plus a header,
+	 * without exceeding the device maximum command size. For ATA disks,
+	 * buffers must be aligned to 512B.
 	 */
-	buflen = roundup((nrz + 1) * 64, 512);
+	buflen = min(queue_max_hw_sectors(disk->queue) << 9,
+		     roundup((nrz + 1) * 64, 512));
 	buf = kmalloc(buflen, gfp_mask);
 	if (!buf)
 		return -ENOMEM;