Linux 下在 USB 固态硬盘上开启 trim

因为课程要使用旧版本的 ros ,为了免去不必要的麻烦就在 USB SSD 上装了 Ubuntu 16.04 LTS 。本来没有什么问题,在改 /etc/fstab 中的 EFI 分区时突然发现这块固态硬盘上没有开 trim ,于是尝试用 fstrim 手动 trim 一下,结果报了错。

$ sudo fstrim -v /run/media/azuk/ssd
fstrim: /run/media/telgar/ssd: the discard operation is not supported
$ lsblk --discard /dev/sdb
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sdb           0        0B       0B         0
├─sdb1        0        0B       0B         0
└─sdb2        0        0B       0B         0

我的 NVMe 硬盘盒通过 USB 3.0 接口接到电脑上,是通过 USB Attached SCSI (UAS) 协议完成通信的。 SCSI 中并没有 trim 这个 ATA 命令,只有与之对应的 SCSI 命令 unmap 。而看起来我的硬盘盒并不支持通过 SCSI/ATA Translation 将 trim 翻译为 unmap ,所以需要在 udev 里配置一下了。

首先,用 lsusb 获得设备的 Vendor ID 和 Product ID 。

$ lsusb
...
Bus 004 Device 002: ID 0bda:9210 Realtek Semiconductor Corp. RTL9210
...

创建 /etc/udev/rules.d/50-usb-ssd-trim.rules ,对应自己设备的 ID 输入一条规则:

ACTION=="add|change", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="9210", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"

重新插上设备,就能看到创建的规则生效啦!

$ lsblk --discard /dev/sdb
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sdb           0      512B       4G         0
├─sdb1        0      512B       4G         0
└─sdb2        0      512B       4G         0
$

然后就像普通的 ssd 一样用 fstrim 就好了。

References:

https://www.glump.net/howto/desktop/enable-trim-on-an-external-ssd-on-linux https://bbs.archlinux.org/viewtopic.php?id=244636 https://wiki.archlinux.org/index.php/Solid_state_drive#External_SSD_with_TRIM_support https://wiki.archlinux.org/index.php/Udev