Discard over USB

The aim of this article is to Article description::enable discard/trim operational for block devices connected via the systems USB bus.

What it does
Trim and discard are two different names for the same thing.

The mount option is called discard, the command does the same thing but not as it happens. Both inform the underlying block device about space that the filesystem was using but has been returned to the free pool. In general this is a good thing as FLASH based devices can only change memory cells in one direction. They must be erased before they can be rewritten. Erase is a slow operation, much slower than write, so discard gives the block device the information it needs to erase the discarded blocks in good time before they need to be rewritten. This in turn maintains the write performance of the device.

Why is USB special
With NVME or SATA connected FLASH devices, trim/discard just works. When a USB adapter is involved trim is usually disabled by default and need to be enable before it can be used.

Readers who have moved a FLASH based block device to a USB enclosure may have noticed a dmesg warning "Discard is not supported".

Prerequsites

 * A USB3 link to the FLASH device. USB2 cannot support trim.
 * A USB3 to FLASH bridge that actually supports trim

Testing that trim is supported
To get the required tools:

Find the USB attached storage
Plug the drive in and inspect the end of dmesg.

If there is only one drive it will be.

The remainder of this document will use. Readers are expected to adjust that to suit their own individual circumstances.

Investigate support
Notice the  section in the prior output. That shows that trim is disabled even if its supported. It needs to show as unmap.

The Unmap entries are important here. Make a note of the Maximum unmap LBA count: value to use it later.

A report like Maximum unmap LBA count: 0 [Unmap command not implemented] Maximum unmap block descriptor count: 0 [Unmap command not implemented] Optimal unmap granularity: 0 blocks [not reported] means that trim is not supported, so stop there.

The Logical block length from that output is necessary to take note of.

Enabling trim
Change the provisioning_mode to unmap

Using the Maximum unmap LBA count and Logical block length, multiply the two numbers together to arrive at the discard_max_bytes for the device.

Set this with

Verify That the changes happened by checking for provisioning_mode:unmap.

provisioning_mode:disabled indicates that trim is not supported. Revert provisioning_mode to full and stop.

That's trim enabled until the next boot.

Testing trim support
Be sure that the filesystem(s) to be trimmed are mounted.

This will list each filesystem with the space that it trimmed. It will be slow the first time as the entire free space pool will be trimmed. We have to trust that the drive will not erase already erased space.

Auto enabling trim
The above manual changes will not be preserved across reboots. (e)udev users need to write a rule.

Discover the the Vendor and Device ID of the USB device that represents the FLASH device.

Here, the SATA 6Gb/s bridge makes it easy to spot. The ID required is ID 174c : 55aa. That's the VendorID and DeviceID parts in order.

Use that in a udev rule

Reboot to test. should trim all the filesystem again.

Closing notes
There is a debate over using the discard option in /etc/fstab or running fstrim in a weekly or monthly cron job. The debate centers around the write amplification caused by performing needless erases cycles. As its non trivial to investigate the trim behavior of individual devices, this author recommends either the cron job approach or making fstrim part of the routine tidying up after a @world update.