3.2.97-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Martin K. Petersen" martin.petersen@oracle.com
commit 28a0bc4120d38a394499382ba21d6965a67a3703 upstream.
SBC-4 states:
"A MAXIMUM UNMAP LBA COUNT field set to a non-zero value indicates the maximum number of LBAs that may be unmapped by an UNMAP command"
"A MAXIMUM WRITE SAME LENGTH field set to a non-zero value indicates the maximum number of contiguous logical blocks that the device server allows to be unmapped or written in a single WRITE SAME command."
Despite the spec being clear on the topic, some devices incorrectly expect WRITE SAME commands with the UNMAP bit set to be limited to the value reported in MAXIMUM UNMAP LBA COUNT in the Block Limits VPD.
Implement a blacklist option that can be used to accommodate devices with this behavior.
Reported-by: Bill Kuzeja William.Kuzeja@stratus.com Reported-by: Ewan D. Milne emilne@redhat.com Reviewed-by: Ewan D. Milne emilne@redhat.com Tested-by: Laurence Oberman loberman@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com [bwh: Backported to 3.2: - Keep using literals for SD_MAX_WS{16,10}_BLOCKS - Adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/scsi/scsi_scan.c | 3 +++ drivers/scsi/sd.c | 16 ++++++++++++---- include/scsi/scsi_device.h | 1 + include/scsi/scsi_devinfo.h | 1 + 4 files changed, 17 insertions(+), 4 deletions(-)
--- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -957,6 +957,9 @@ static int scsi_add_lun(struct scsi_devi if (*bflags & BLIST_RETRY_HWERROR) sdev->retry_hwerror = 1;
+ if (*bflags & BLIST_UNMAP_LIMIT_WS) + sdev->unmap_limit_for_ws = 1; + transport_configure_device(&sdev->sdev_gendev);
if (sdev->host->hostt->slave_configure) { --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -523,11 +523,21 @@ static void sd_config_discard(struct scs break;
case SD_LBP_WS16: - max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); + if (sdkp->device->unmap_limit_for_ws) + max_blocks = sdkp->max_unmap_blocks; + else + max_blocks = sdkp->max_ws_blocks; + + max_blocks = min_not_zero(max_blocks, 0xffffffff); break;
case SD_LBP_WS10: - max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); + if (sdkp->device->unmap_limit_for_ws) + max_blocks = sdkp->max_unmap_blocks; + else + max_blocks = sdkp->max_ws_blocks; + + max_blocks = min_not_zero(max_blocks, (u32)0xffff); break;
case SD_LBP_ZERO: --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -152,6 +152,7 @@ struct scsi_device { unsigned no_read_capacity_16:1; /* Avoid READ_CAPACITY_16 cmds */ unsigned is_visible:1; /* is the device visible in sysfs */ unsigned broken_fua:1; /* Don't set FUA bit */ + unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ struct list_head event_list; /* asserted events */ --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -30,4 +30,5 @@ #define BLIST_RETRY_HWERROR 0x400000 /* retry HARDWARE_ERROR */ #define BLIST_MAX_512 0x800000 /* maximum 512 sector cdb length */ #define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */ +#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */ #endif