Solid state drive (简体中文)
本文介绍专题操作固态硬盘和其他闪存的存储设备。如果要出于特定目的对SSD进行分区,请考虑针对闪存优化的文件系统列表。对于一般用途,您只需选择喜好的文件系统。
使用
TRIM
绝大多数SSD支持 ATA_TRIM 命令 以保持性能并降低损耗。本文展示了SSD装满数据前后的速度变化。
自 Linux 内核版本 3.8 开始,对 TRIM 的支持不断被添加到不同的文件系统中。见下表:
文件系统 | Continuous TRIM ( discard 选项) |
Periodic TRIM (fstrim) |
参考与备注 |
---|---|---|---|
Btrfs | 是 | 是 | |
exFAT | 是 | 是 | 从5.13版内核开始支持fstrim, [1] |
ext3 | 是 | 是 | |
ext4 | 是 | 是 | "discard, nodiscard(*)" in [2] |
F2FS | 是 | 是 | |
JFS | 是 | 是 | [3] |
NILFS2 | 是 | 是 | |
NTFS-3G | 否 | 是 | 从2015.3.14版本开始, [4] |
VFAT | 是 | 是 | 从4.19版内核开始支持fstrim, [5] |
XFS | 是 | 是 | [6][失效链接 2021-11-19 ⓘ] |
检验TRIM支持:
$ lsblk --discard
查看DISC-GRAN (discard granularity)和DISC-MAX (discard max bytes)列。非零数值表示对应设备支持TRIM。
# hdparm -I /dev/sda | grep TRIM
* Data Set Management TRIM supported (limit 1 block)
Periodic TRIM
util-linux包提供了fstrim.service
和fstrim.timer
两个Systemd unit文件。启用计时器(fstrim.timer
)会每周激活服务来在所有已挂载的支持discard操作的文件系统上执行fstrim(8)。
该计时器使用/var/lib/systemd/timers/stamp-fstrim.timer
(将在服务第一次启动时创建)的时间戳来判断上次运行的时间。因此,不必担心服务被太过频繁地调用。
该unit的状态与活动可通过journalctl查看。若要修改运行的周期或执行的指令,可编辑unit文件。
Continuous TRIM
fstrim
,就不必再启用Continuous TRIM。只需在periodic TRIM和Continuous TRIM中选择一个即可。除定期(若使用fstrim.timer
则默认为每周)执行TRIM指令外,也可每次在文件被删除后就立即执行TRIM指令(这被称为Continuous TRIM)。
ata_device_blacklist
。详见Wikipedia:Trim_(computing)#Disadvantages
要使用Continuous TRIM,在/etc/fstab
中对应挂载点指定discard
选项:
/dev/sda1 / ext4 defaults,discard 0 1
对于Ext4文件系统,也可用tune2fs将discard
设置为一个默认挂载选项:
# tune2fs -o discard /dev/sdXY
使用此方式代替/etc/fstab
中的条目对于可移动驱动器尤其有用。这样,在其他计算机上挂载分区时,就不需要每次修改/etc/fstab
了。
/proc/mounts
中列出。Trim整个设备
当在全新安装或想卖掉你的SSD时,你可能想Trim整个设备。可以使用blkdiscard命令,这将立即丢弃设备上所有的block。
# blkdiscard /dev/sdX
为LVM启用TRIM
由LVM逻辑卷上的文件系统产生的TRIM请求将直达对应物理卷。因此,无需额外的配置。
LVM操作(lvremove, lvreduce等)默认不会产生TRIM请求,以便使用vgcfgrestore(8)恢复之前的卷组(VG)设定。/etc/lvm/lvm.conf
中的issue_discards
设置决定是否在逻辑卷不再占用卷组空间时将discard发送给底层物理卷。
issue_discards
设置前,请仔细阅读/etc/lvm/lvm.conf
中的注释。issue_discards
设置不会影响由逻辑卷文件系统产生的TRIM请求(如在文件系统内删除文件)的传递,也不会影响thin pool中的空间管理。issue_discards
后,将不能再使用vgcfgrestore恢复卷组(VG)元数据。一旦执行LVM命令,将无法撤销。为dm-crypt启用TRIM
对非/
文件系统,为SSD上的块设备配置 /etc/crypttab
来把 discard
加入到选项列表中 (见 Dm-crypt/System configuration#crypttab)。
对于/
文件系统,遵循 Dm-crypt/TRIM support for SSD 的指示来将正确的内核参数加入到bootloader配置中。
提升性能
参照Improving performance#Storage devices中的提示来提高SSD性能。
物理块大小
大多数SSD将其扇区大小报告为512字节(与HDD兼容),但实际上具有更大的块大小 -- 通常是4kB、8kB甚至更大。由于被认为扇区大小为512字节,文件系统不能自动优化到物理块大小。为防止性能损失,应在创建文化系统时手动指定扇区大小。
作为手动指定扇区大小的替代,某些SSD可在格式化时更改块大小,因此其可能会汇报一个更接近其真实数值的块大小。
NVMe
使用Identify Namespace命令来查看指定的NVMe设备是否支持该特性。
# nvme id-ns /dev/nvme0n1
nlbaf : 0 [...] lbaf 0 : ms:0 lbads:9 rp:0 (in use)
nlbaf
是支持的LBA格式数减1,所以本例中只支持1种格式。支持的格式列举在其后。lbaf 0
表示支持LBA format #0。其lbads
(LBA data size)为9,表示块大小为29=512字节。如果设备支持4kB块大小,lbads
将会是12。rp
(相对性能)表示那种LBA格式具有最好的性能,0表示当前格式具有最好的性能。ms
(可能)是每个块中额外的元数据大小(Bytes),在Linux下,对其的支持并不完善,所以最好选择该值为0的格式。
要修改块大小,使用nvme format
命令并通过--lbaf
参数指定对应的lbaf值。
SATA
对于SATA设备,必须使用制造商提供的工具。 不是所有的SATA设备都支持修改块大小。
- Intel: 使用Intel Memory and Storage (MAS) 工具 (intel-mas-cli-toolAUR)及
-set PhysicalSectorSize=4096
参数。
安全
Hdparm 显示 "frozen" 状态
一些主板BIOS在初始化时发送了"security freeze"命令给连接上的存储设备。同样,一些SSD(和HDD) BIOS在工厂已设置为"security freeze"。二者都会导致设备的密码安全设置设为 frozen,如下面的输出:
:~# hdparm -I /dev/sda
Security: Master password revision code = 65534 supported not enabled not locked frozen not expired: security count supported: enhanced erase 4min for SECURITY ERASE UNIT. 2min for ENHANCED SECURITY ERASE UNIT.
如格式化设备或安装新系统之类的操作不受"security freeze"影响。
上面的输出显示了设备在启动时not locked,而frozen状态保护设备免于间谍软件侵害。它们试图在运行时设置密码来达到目的。
如果你想为"frozen"的设备设置密码,则必须要主板BIOS支持才可。许多笔记本都支持,这是因为这是 硬件加密 所必需的,但并非台式机/服务器主板所必需。例如,对于 Intel DH67CL/BL 主板,必须用跳线设置为"maintenance mode"来查看设置 (见 [13], [14])。
hdparm
来改变上述的lock安全设置,除非你十分清楚自己在干什么。如果你想擦除SSD,见 Securely wipe disk#hdparm 以及 下文。
SSD存储单元的清除
有时用户希望通过重置SSD单元到刚安装时的纯净状态以使其恢复到 出厂时的写入性能。即使是原生支持TRIM的SSD,其写入性能也会随时间变差。TRIM只在文件删除时起作用,而不是如增量保存一样的替代保障措施。
重置按wiki文章SSD memory cell clearing指示,三步之内即可轻松完成。如果重置的原因是为了擦除数据,你可能不想依靠SSD bios来安全执行。更多信息与例子见Securely wipe disk#Flash memory。
硬件加密
正如#Hdparm 显示 "frozen" 状态中提到的,在BIOS中为存储设备(SSD/HDD)设置密码可能在支持的设备上启动硬件加密。如果设备同时符合OPAL标准,硬件加密还可能在BIOS没有设置密码的功能上实现,见Self-encrypting drives。
故障排除
你遇到的问题可能是由于SSD固件而不是Linux产生的。在尝试排除故障前,请检查以下固件是否有更新:
即使是固件的bug,也可能在不更新固件的情况下避免。若没有固件更新可用,或你不想进行固件更新,以下内容可能有所帮助。
处理NCQ错误
部分SSD和SATA芯片组并不在Linux的原生命令队列(NCQ)下正常工作。dmesg错误提示看起来像这样:
[ 9.115544] ata9: exception Emask 0x0 SAct 0xf SErr 0x0 action 0x10 frozen [ 9.115550] ata9.00: failed command: READ FPDMA QUEUED [ 9.115556] ata9.00: cmd 60/04:00:d4:82:85/00:00:1f:00:00/40 tag 0 ncq 2048 in [ 9.115557] res 40/00:18:d3:82:85/00:00:1f:00:00/40 Emask 0x4 (timeout)
要在系统启动时禁用NCQ,在bootloader配置中添加内核命令行libata.force=noncq
。要仅为disk0 port9关闭NCQ,使用:libata.force=9.00:noncq
或者,可通过sysfs在不重启的情况下在指定设备上关闭NCQ:
# echo 1 > /sys/block/sdX/device/queue_depth
如果问题仍未得到解决或导致了其他问题,提交一个bug。
处理与SATA电源管理有关的错误
某些SSD(如Transcend MTS400)在SATA Active Link Power Management(ALPM)启用时会出现错误。 ALPM默认关闭,并被节能程序(如TLP, Laptop Mode Tools)启用。
如果在使用这些节能程序时遇到SATA相关错误,应将使用电池时与充电时的电源配置都设为max_performance
来关闭ALPM。
External SSD with TRIM support
一些USB转SATA芯片(如VL715、VL716等)以及在 IB-1817M-C31[失效链接 2021-11-19 ⓘ] 之类外接NVMe硬盘盒中使用的USB转PCIe芯片(如 智微(JMicron) JMS583 )支持类TRIM命令,可通过 USB Attached SCSI 驱动程序(在Linux下称为"uas")发送。
然而内核可能不会自动检测到这一功能,从而也不会使用它。假设需要的块设备为/dev/sdX,可以用以下命令确定是不是这种情况
# sg_readcap -l /dev/sdX
如果输出中有一行写着“Logical block provisioning: lbpme=0”,则由于没有设置LBPME位,内核认为该设备不支持Logical Block Provisioning Management 。
If this is the case, then you should next find out whether the "Vital Product Data" (VPD) page on "Logical Block Provisioning" of your device tells of supported mechanisms for unmapping data. You can do this using the command:
# sg_vpd -a /dev/sdX
Look for lines in the output that look like this:
Unmap command supported (LBPU): 1 Write same (16) with unmap bit supported (LBPWS): 0 Write same (10) with unmap bit supported (LBPWS10): 0
This example would tell you the device supports the "UNMAP" command.
Have a look at the output of
$ cat /sys/block/sdX/device/scsi_disk/*/provisioning_mode
If the kernel did not detect the capability of your device to unmap data, then this will likely return "full". Apart from "full", the kernel SCSI storage driver currently knows the following values for provisioning_mode:
unmap writesame_16 writesame_10 writesame_zero disabled
For the example above, you could now write "unmap" to "provisioning_mode" to ask the kernel to use that:
# echo "unmap" >/sys/block/sdX/device/scsi_disk/*/provisioning_mode
This should immediately enable you to use tools like "blkdiscard" on /dev/sdX or "fstrim" on filesystems mounted on /dev/sdX.
If you want to enable a "provisioning_mode" automatically when an external device of a certain vendor/product is attached, this can be automated via the "udev" mechanism. First find the USB Vendor and Product IDs:
$ cat /sys/block/sdX/../../../../../../idVendor $ cat /sys/block/sdX/../../../../../../idProduct
Then create or append to a udev rule file (example here using idVendor 152d and idProduct 0583):
# echo 'ACTION=="add|change", ATTRS{idVendor}=="152d", ATTRS{idProduct}=="0583", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"' >>/etc/udev/rules.d/10-uas-discard.rules
(You can also use the lsusb
command to look for the relevant idVendor/idProduct.)
固件升级
ADATA
ADATA 在其支持页面上提供了Linux (i686)版的工具。在选择型号之后会出现到最新固件的链接。最新的Linux上的升级工具打包有固件,并必须以root权限运行。必须首先给二进制文件设置合适的权限。
Crucial
Crucial 提供了以ISO镜像文件升级固件的选项。镜像可以在选择产品和下载"Manual Boot File"之后找到。
dd
命令将镜像复制到设备上,由于MBR不会被设置,将无法从该设备启动。M4 Crucial model用户可通过smartctl
检查是否有需要的固件更新。
$ smartctl --all /dev/sdX
==> WARNING: This drive may hang after 5184 hours of power-on time: https://www.tomshardware.com/news/Crucial-m4-Firmware-BSOD,14544.html See the following web page for firmware updates: https://www.crucial.com/usa/en/support-ssd
建议看见这个警告的用户备份所有重要数据并立即升级。参见该指引来使用ISO镜像和grub来更新Crucial MX100的固件。
Intel
对于无法使用Windows版本Intel® Solid-State Drive Toolbox[失效链接 2021-05-17 ⓘ]软件的系统,Intel提供了一个基于Linux live系统的固件更新工具。
此外,还可用使用Intel Memory and Storage (MAS) Tool(intel-mas-cli-toolAUR)命令行工具来在Linux下刷入固件。其PDF用户指南[失效链接 2021-11-19 ⓘ]。
一个检查固件状态的例子:
# intelmas show -intelssd 0
DevicePath : /dev/nvme0n1 DeviceStatus : Healthy Firmware : 002C FirmwareUpdateAvailable : The selected Intel SSD contains current firmware as of this tool release.
若有多个SSD,请将-intelssd 0
修改为对应的值(1
对应第二块SSD,以此类推)。
如果有可用的更新,可通过intelmas load -intelssd 0
来应用。PDF用户指南建议进行应用操作后重启并再进行一次。所有设备的最新固件都作为MAS工具的一部分发布,无需单独下载。
Kingston
适用于基于Sandforce设备的KUF工具可从kingston_fw_updaterAUR获取。
Mushkin
不怎么出名的 Mushkin 牌固态硬盘也使用 Sandforce 控制器,提供了Linux版的升级工具 (和 Kingston 的几乎一样)。
OCZ
OCZ 在论坛上提供了Linux (i686 and x86_64) 版的升级工具。
Samsung
Samsung 注意到使用他们的 Magician Software 是"不支持的",但是是可能的。显然 Magician Software 可以把USB做成以升级固件启动。最简单的方式是使用他们提供的用于升级固件的可启动的ISO镜像。可从这里获取。
用户更喜欢从USB的live Linux系统上升级固件(而不是在Microsoft Windows下用三星的 "Magician" 软件)。参见这里。
在Linux下更新
此外,固件可在不使用USB启动盘的情况下直接更新。首先,从这里下载适用于Windows的最新固件(一个磁盘镜像,以Samsung_SSD_840_EVO_EXT0DB6Q.iso
为例)。
设置磁盘镜像:
$ udisksctl loop-setup -r -f Samsung_SSD_840_EVO_EXT0DB6Q.iso
这会将ISO映射到一个loop设备,假设为/dev/loop0
。执行:
$ udisksctl mount -b /dev/loop0
获取需要镜像中需要的内容:
$ mkdir Samsung_SSD_840_EVO_EXT0DB6Q $ cp -r /run/media/$USER/CDROM/isolinux/ Samsung_SSD_840_EVO_EXT0DB6Q
卸载镜像:
$ udisksctl unmount -b /dev/loop0 $ cd Samsung_SSD_840_EVO_EXT0DB6Q/isolinux
固件包含在一个FreeDOS镜像中,用上文的方法将其挂载:
$ udisksctl loop-setup -r -f btdsk.img $ udisksctl mount -b /dev/loop1 $ cp -r /run/media/$USER/C04D-1342/ Samsung_SSD_840_EVO_EXT0DB6Q $ cd Samsung_SSD_840_EVO_EXT0DB6Q/C04D-1342/samsung
使用magician获取目标SSD的编号:
# magician -L
假设编号为0,执行:
# magician --disk 0 -F -p DSRD
确认固件已被更新:
# magician -L
最后,重启计算机。
SanDisk
SanDisk 制作ISO固件镜像来允许用户在 SanDisk SSD 工具包不支持的系统上升级。必须找到正确的SSD 型号以及它的容量(例如 60GB, 或者 256GB)。烧制合适的ISO固件镜像之后,只需重启电脑启动到新创立的CD/DVD启动盘(也可以是USB)。
ISO镜像必须只包含一个linux内核和一个initrd.解压到 /boot
分区并用 GRUB 或者 Syslinux 启动它来升级。
目前我找不到列出固件升级的单独页面(恕我直言网站简直一团糟),但这里有一些相关链接:
SanDisk Extreme SSD Firmware Release notes and Manual Firmware update version R211
SanDisk Ultra SSD Firmware release notes and Manual Firmware update version 365A13F0
另见
- Discussion on Reddit about installing Arch on an SSD
- See the Flashcache article for advanced information on using solid-state with rotational drives for top performance.
- Speed Up Your SSD By Correctly Aligning Your Partitions (using GParted)
- Re: Varying Leafsize and Nodesize in Btrfs
- Re: SSD alignment and Btrfs sector size
- Erase Block (Alignment) Misinformation?
- Is alignment to erase block size needed for modern SSD's?
- Btrfs support for efficient SSD operation (data blocks alignment)
- SSD, Erase Block Size & LVM: PV on raw device, Alignment