[PATCH] scsi: Fix incorrect writesame_16 provisioning mode for some devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch addresses an issue when 'writesame_16' provisioning mode
could be incorrectly set for some storage devices that support
logical block provisioning (LBPME=1) but with some other operation
than 'writesame_16' specified in a VPD.

Prior to this patch, the read_capacity_16() function used to set
block provisioning mode to 'writesame_16' for all devices that have
the LBPME bit enabled, without checking the logical provisioning VPD
page for the correct command to be used. Setting the provisioning
mode in the read_capacity_16() function seems unnecessary for
multiple reasons:
1. the correct mode is then detected and set by the
   sd_read_block_provisioning() and sd_read_block_limits() functions
2. it can result in an incorrect provisioning mode to be enabled for
   some devices that use some other block provisioning mode than
   'writesame_16'.

Prior to applying this patch, my 5TB WD Black P10 USB external hard
drive was detected to support TRIM (verified by lsblk -D). However,
any TRIM attempt (fstrim, blkdiscard) resulted in I/O errors in
dmesg, and the TRIM operation did not seem to unmap any blocks.
The problem was that the kernel used 'writesame_16' even though
the hard drive supported 'unmap' command instead.

$ cat /sys/block/sdb/device/scsi_disk/6\:0\:0\:0/provisioning_mode
writesame_16

$ sudo sg_vpd -a /dev/sdb
Logical block provisioning VPD page (SBC):
  Unmap command supported (LBPU): 1
  Write same (16) with unmap bit supported (LBPWS): 0
  Write same (10) with unmap bit supported (LBPWS10): 0

The drive uses Bulk-Only USB interface instead of UASP. Because
of it, read_capacity_10() is used first. But because the capacity
of the drive is 5TB, read_capacity_16() is tried next. This
function set the provisioning mode to 'writesame_16' since the
drive reports LBPME=1. But because the drive is connected via USB,
the VPD page is ignored (skip_vpd_pages is set to true in
scsiglue.c), the correct provisioning mode (unmap) is never
set, and an incorrect provisioning mode (writesame_16) was kept
instead.

This was not an issue on my internal SSD which supports 'writesame_16'
discard command. In that case, read_capacity_16() set the discard mode
to 'writesame_16' (which happened to be the correct one in this case),
and shortly after that, sd_read_block_provisioning() and
sd_read_block_limits() set the discard mode to 'writesame_16' again.

After applying this patch, my USB hard drive is treated as if it
didn't support the discard operation (because VPD is not checked
in the case of a USB device that does not support UASP).
This is better than issuing invalid commands to the device.

$ cat /sys/block/sdb/device/scsi_disk/*/provisioning_mode
full

Signed-off-by: David Sebek <dasebek@xxxxxxxxx>
---
 drivers/scsi/sd.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index cb3c37d1e009..2ad4abc1cbc2 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2416,8 +2416,6 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
 
 		if (buffer[14] & 0x40) /* LBPRZ */
 			sdkp->lbprz = 1;
-
-		sd_config_discard(sdkp, SD_LBP_WS16);
 	}
 
 	sdkp->capacity = lba + 1;
-- 
2.31.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux