7

I just bought a SATA SSD and a USB-SATA adapter. I chose an adapter with UASP support, because I thought it would make it possible to run a TRIM/DISCARD command, and I think it is important for the lifetime of the SSD.

When I connect the adapter to my Debian-based computer, the linux kernel detects it as expected and enables communication with the UAS protocol. Here is what the kernel reports:

[23886.083296] usb 2-1: new SuperSpeed Gen 1 USB device number 6 using xhci_hcd
[23886.104497] usb 2-1: New USB device found, idVendor=174c, idProduct=55aa, bcdDevice= 1.00
[23886.104508] usb 2-1: New USB device strings: Mfr=2, Product=3, SerialNumber=1
[23886.104513] usb 2-1: Product: 00SSD1
[23886.104518] usb 2-1: Manufacturer: CT500MX5
[23886.104522] usb 2-1: SerialNumber: 12345678D9DA
[23886.110042] scsi host1: uas
[23886.110883] scsi 1:0:0:0: Direct-Access     CT500MX5 00SSD1           0    PQ: 0 ANSI: 6
[23886.111967] scsi 1:0:0:0: Attached scsi generic sg1 type 0
[23886.112698] sd 1:0:0:0: [sdb] 976773168 512-byte logical blocks: (500 GB/466 GiB)
[23886.112702] sd 1:0:0:0: [sdb] 4096-byte physical blocks
[23886.112841] sd 1:0:0:0: [sdb] Write Protect is off
[23886.112846] sd 1:0:0:0: [sdb] Mode Sense: 43 00 00 00
[23886.113013] sd 1:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[23886.113224] sd 1:0:0:0: [sdb] Optimal transfer size 33553920 bytes not a multiple of physical block size (4096 bytes)

lsusb confirms that the uas driver is used:

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/7p, 5000M
    |__ Port 1: Dev 6, If 0, Class=Mass Storage, Driver=uas, 5000M

But I can’t run blkdiscard on this device:

# blkdiscard -f /dev/sdb
blkdiscard: /dev/sdb contains existing partition (dos).
blkdiscard: Operation forced, data will be lost!
blkdiscard: /dev/sdb: BLKDISCARD ioctl failed: Operation not supported

lsblk confirms that the block device does not support discarding:

# lsblk -D /dev/sdb
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sdb           0        0B       0B         0
`-sdb1        0        0B       0B         0

Where does the problem come from? Is there any hope I can run TRIM/DISCARD with this setup?

2

1 Answer 1

12

After some reading (thanks harrymc for the link in the comment), I think I can now understand much better what’s going on.

First of all, it was naive to think that using an UASP-enabled USB-SATA bridge with a recent SATA SSD (that supports TRIMming) would obviously support UNMAPping.

The reality is that an UASP-enabled USB-SATA bridge has two main functions:

  • the first one is the UAS interface, which is an USB interface to encapsulate SCSI commands,
  • the second one is a translator that converts SCSI commands to ATA commands.

The set of commands defined by the SCSI protocol is quite big and not all SCSI devices support all commands. Hence, there are several commands that can be used to UNMAP. A SCSI-ATA translator might support one of them, perhaps several of them, but might also support none. In the latter case, it would not be possible to UNMAP block of the SSD. Fortunately, my the SCSI-ATA translator in my USB-SATA bridge does support the UNMAP command.

Because of the richness of the SCSI command set, a driver has to know what features are supported by a device. This is done with some information pages, called VPD (Vital Product Data) pages, provided by the device to the driver. The “first” page is the “Supported VPD pages” page that lists the pages that the device supports.

Normally, the driver would query the “first” page, and then query the interesting pages, if they are supported. As for the ability to UNMAP, the interesting page is the “Logical block provisioning” page.

With linux, one can query the “Supported VPD pages” and “Logical block provisioning” pages like this:

# sg_vpd -p sv /dev/sdb
Supported VPD pages VPD page:
  Supported VPD pages [sv]
  Unit serial number [sn]
  Device identification [di]
  Block limits (SBC) [bl]
  Block device characteristics (SBC) [bdc]
  Logical block provisioning (SBC) [lbpv]
# sg_vpd -p lbpv /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
  Logical block provisioning read zeros (LBPRZ): 0
  Anchored LBAs supported (ANC_SUP): 0
  Threshold exponent: 0 [threshold sets not supported]
  Descriptor present (DP): 0
  Minimum percentage: 0 [not reported]
  Provisioning type: 0 (not known or fully provisioned)
  Threshold percentage: 0 [percentages not supported]

Here, one can see that “my” SCSI-ATA translator supports the unmap command but does not support the Write same (16) or Write same (10) commands with unmap bit.

Normally, the driver would read those pages and configure the device accordingly. Unfortunately, there apparently is a history of broken USB devices that lock-up or brick when some VPD pages are queried. Hence, the developpers of the linux kernel decided by default to not query VPD pages for USB-attached SCSI devices, and not set up advances features such as UNMAP.

The good news is that it is still possible to set up those features from userspace, using the special file /sys/block/sdb/device/scsi_disk/1:0:0:0/provisioning_mode (the path may vary). When I plug my adapter, it reads “full”, but I can set it to “unmap” since my device supports the unmap command. The other supported values are “writesame_16”, “writesame_10”, “writesame_zero” and “disabled”.

One can go further and set up an udev rule to configure that device automatically:

ACTION=="add|change", ATTRS{idVendor}=="174c", ATTRS{idProduct}=="55aa", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"

(the idVendor, idProduct and provisioning_mode depend on the USB-SATA bridge)

Anyway, I cannot recommend doing this since a mistake might brick your device, and even trying to read the VPD pages with sg_vpd might.

I also don’t know how useful it is to set up the discard_max_bytes setting, as suggested by the great Enabling TRIM on an external SSD on a Raspberry Pi article.

Some good news again, there is a patch that bypasses the restriction for USB-attached SCSI devices in some cases where it looks safe to do so, and I guess it should do it for most recent UASP-enabled USB-SATA bridges. I have not (yet) given it a try; it apparently hasn’t made its way to linux 6.0-rc4; I don’t know whether there are plans to request its merge in the near future.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .