Skip to content

Commit 28a0bc4

Browse files
scsi: sd: Implement blacklist option for WRITE SAME w/ UNMAP
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. Cc: <stable@vger.kernel.org> 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>
1 parent d0b7a90 commit 28a0bc4

4 files changed

Lines changed: 17 additions & 4 deletions

File tree

drivers/scsi/scsi_scan.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
956956
if (*bflags & BLIST_NO_DIF)
957957
sdev->no_dif = 1;
958958

959+
if (*bflags & BLIST_UNMAP_LIMIT_WS)
960+
sdev->unmap_limit_for_ws = 1;
961+
959962
sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT;
960963

961964
if (*bflags & BLIST_TRY_VPD_PAGES)

drivers/scsi/sd.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
715715
break;
716716

717717
case SD_LBP_WS16:
718-
max_blocks = min_not_zero(sdkp->max_ws_blocks,
719-
(u32)SD_MAX_WS16_BLOCKS);
718+
if (sdkp->device->unmap_limit_for_ws)
719+
max_blocks = sdkp->max_unmap_blocks;
720+
else
721+
max_blocks = sdkp->max_ws_blocks;
722+
723+
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);
720724
break;
721725

722726
case SD_LBP_WS10:
723-
max_blocks = min_not_zero(sdkp->max_ws_blocks,
724-
(u32)SD_MAX_WS10_BLOCKS);
727+
if (sdkp->device->unmap_limit_for_ws)
728+
max_blocks = sdkp->max_unmap_blocks;
729+
else
730+
max_blocks = sdkp->max_ws_blocks;
731+
732+
max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);
725733
break;
726734

727735
case SD_LBP_ZERO:

include/scsi/scsi_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ struct scsi_device {
192192
unsigned no_dif:1; /* T10 PI (DIF) should be disabled */
193193
unsigned broken_fua:1; /* Don't set FUA bit */
194194
unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */
195+
unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
195196

196197
atomic_t disk_events_disable_depth; /* disable depth for disk events */
197198

include/scsi/scsi_devinfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
#define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */
3030
#define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */
3131
#define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */
32+
#define BLIST_UNMAP_LIMIT_WS 0x80000000 /* Use UNMAP limit for WRITE SAME */
3233

3334
#endif

0 commit comments

Comments
 (0)