Enable Trim on an External SSD on Linux

Published: 

Last week I bought a Sabrent Rocket Pro USB-connected SSD storage device. The product page for this line of SSDs on Amazon says clearly that it supports Linux and it supports the Trim function, but I had a problem with that, out of the box.

Trim is a relatively new feature in storage device interfaces whereby the host (the computer) can tell the storage device "these sectors contain discarded data; they can be recycled." Under most circumstances, a magnetic hard drive does not need to know this information, and any hard drive supporting Trim might simply ignore the command. But with storage devices based on flash memory, such as SSDs, it is critical that the Trim or Discard command be called for every discarded sector after files are deleted. (In normal operation, this may not happen immediately; Ubuntu Linux likes to trim all online filesystems once per week.)

If you don't regularly trim deleted sectors on an SSD, a "write amplification" effect can cause your device to wear out faster than it normally would. (See the above Wikipedia link.)

Problem

When I ran lsblk --discard to see if my new SSD was initialized in the kernel with Trim support, I got the following at the command prompt:

lsblk --discard /dev/sda
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda           0        0B       0B         0
└─sda1        0        0B       0B         0

If you don't know which device to name in the lsblk command, first run lsblk with no options and you should be able to determine which device you want to look at from the list.

It seems that Linux doesn't support Trim over USB, out of the box. I discovered a page on the always-useful Arch Linux wiki that says "Several USB-SATA Bridge Chips, like VL715, VL716 etc, support TRIM," but... your device might come up as not supporting trim when you plug it in. I guess Linux has some sort of whitelist built-in for Trim over USB, and any new device not on the list gets Trim disabled.

Solution

If you have a Sabrent Rocket Pro USB SSD, or you have some other USB-connected SSD and you are sure the enclsoure supports Tim, then do the following:

1. Identify the Vendor ID and Product ID

Run lsusb with the device plugged in. If you aren't sure which device in the list is your SSD, unplug it and run lsusb again and see which device disappeared. (Don't forget to unmount the filesystem before you unplug it.)

Every device has an ID value in the list. For example, mine is "152d:0583". The Vendor ID is the first part and the Product ID is the second part.

2. Create a udev rule

sudo nano /etc/udev/rules.d/50-usb-ssd-trim.rules

Enter this rule in the text editor:

ACTION=="add|change", ATTRS{idVendor}=="152d", ATTRS{idProduct}=="0583", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"

Make sure you fill in your Vendor ID and Product ID you got from the previous step, when you create the rule file. Ctrl+X saves and closes the file, in Nano.

Now, the next time you plug in your device, Trim should work.

lsblk --discard /dev/sda
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda           0        4K      32G         0
└─sda1        0        4K      32G         0

3. Check that your filesystem supports trim

You can run the trim command on all discarded sectors manually:

sudo fstrim /media/NAME-OF-MY-SSD

If fstrim gives you an error message, but lsblk has a value for the DISC-GRAN or DISC-MAX columns, then most likely your SSD's current filesystem has a driver in Linux that doesn't support the Trim command. In this case, you should probably reformat it with a filesystem that does support Trim, such as ext4, f2fs, or ntfs. That is beyond the scope of this howto guide.

4. Actually trim your SSD manually on a regular basis

Ubuntu is configured to NOT trim deleted sectors the moment you delete them, because doing so could potentially lock up the device completely for a few seconds, and it can be a real drag on performance. Instead, Ubuntu runs fstrim --all from a cron job once per week. For details on how your Linux OS behaves, check your documentation.

Your OS is probably using the same behavior as Ubuntu, and as such, it's entirely possible that that weekly fstrim --all command could miss your external USB SSD device because it wasn't plugged in when the command ran.

To deal with this problem, just be sure to run the fstrim command manually as shown in the previous section, once or week or once per month -- depending on how heavily you use the device.

Sources

I consulted the following pages, to solve this problem and write this howto guide:

Comments

Add Comment

* Required information
5000
Powered by Commentics

Comments (1)

I had the same problem with JMicron JMS576 adapter in Ubuntu 20.04.1, kernel 5.13.0-28-generic SMP x86_64.

Manual procedure worked fine but udev rule produced strange result - non-zero value for DISC-MAX (correct) and zero value for DISC-GRAN (wrong):

NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda 0 0B 4G 0
└─sda1 0 0B 4G 0

fstrim seemed to work in this case but kernel log was filled by messages "Error: discard_granularity is 0" Problem was fixed by updating udev rule (it is just workaround):

ACTION=="add|change", ATTRS{idVendor}=="152d", ATTRS{idProduct}=="0583", SUBSYSTEM=="block", ATTR{../../scsi_disk/*/provisioning_mode}="unmap"