固态硬盘
本文介绍如何管理固态硬盘等基于闪存的存储设备。如果出于特定目的要对SSD进行分区,请考虑针对闪存优化的文件系统。对于一般用途,您只需选择喜好的文件系统并启用#TRIM。
使用[编辑 | 编辑源代码]
TRIM[编辑 | 编辑源代码]
在机械硬盘上,只需在文件系统层面处理文件的删除即可[1]。但在固态硬盘上,每次写操作都会对相应闪存单元产生一定磨损,因此主控会使用算法来将写操作平衡到整块闪存上,这被称作耗损平均技术。在删除文件后通知主控对应的存储单元为可用状态将有助于这个过程。在不使用NVMe DEALLOCATE, SAS UNMAP或ATA_TRIM命令的情况下,由于主控不知道被删除的文件对应的空间已空闲,很快闪存上将没有“空闲”空间。在执行写入操作时,主控将需要反复搬运数据以空出一个最小擦除单元并擦除该单元以写入数据,导致写入用时增加(详见:写入放大)。此文展示了SSD装满数据前后的速度变化。
自 Linux 内核版本 3.8 开始,对 TRIM 的支持不断被添加到不同的文件系统中。见下表:
文件系统 | Continuous TRIM ( discard 选项) |
Periodic TRIM (fstrim) |
参考与备注 |
---|---|---|---|
Btrfs | 是 | 是 | 从6.2版内核开始,默认启用了异步discard。 |
exFAT | 是 | 是 | 从5.13版内核开始支持fstrim, [4] |
ext3 | 是 | 是 | |
ext4 | 是 | 是 | "discard, nodiscard(*)" in [5] |
F2FS | 是 | 是 | |
JFS | 是 | 是 | [6] |
NILFS2 | 是 | 是 | |
NTFS | 是 | 否 | ntfs3内核驱动仅支持continuous TRIM。 |
否 | 是 | NTFS-3G仅支持periodic TRIM。 | |
VFAT | 是 | 是 | 从4.19版内核开始支持fstrim, [7] |
XFS | 是 | 是 | [8] |
要检查TRIM支持,执行:
$ lsblk --discard
若DISC-GRAN (discard granularity)和DISC-MAX (discard max bytes)列上的数值不为零,则表示对应设备支持TRIM。
对于SATA SSD,可通过hdparm包检测TRIM支持:以root用户执行hdparm -I /dev/sda | grep TRIM
。
hdparm
不支持NVMe SSD。
Periodic TRIM[编辑 | 编辑源代码]
util-linux包提供了fstrim.service
和fstrim.timer
两个systemd unit文件。启用fstrim.timer
计时器会在每周激活服务,在所有已挂载的支持discard操作的文件系统上执行fstrim(8)。
该计时器使用/var/lib/systemd/timers/stamp-fstrim.timer
(将在服务第一次启动时创建)的时间戳来判断上次运行的时间。因此,不必担心服务被过于频繁地调用(类似anacron)。
该unit的状态与活动可通过journalctl查看。若要修改运行的周期或执行的指令,可编辑unit文件。
Continuous TRIM[编辑 | 编辑源代码]
除定期执行TRIM指令外(若使用fstrim.timer
则默认为每周),也可每次在文件被删除后就立即执行TRIM指令(这被称为Continuous TRIM)。
ata_device_blacklist
)。因此,在这些设备上,系统可能会强制发送非队列的(non-queued)TRIM指令。详见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命令,
为LVM启用TRIM[编辑 | 编辑源代码]
由LVM逻辑卷上的文件系统产生的TRIM请求将直达对应物理卷,无需额外的配置。
LVM操作(lvremove, lvreduce等)默认不会产生TRIM请求,以便使用vgcfgrestore(8)恢复之前的卷组设定。/etc/lvm/lvm.conf
中的issue_discards
设置决定是否在逻辑卷不再占用卷组空间时将discard发送给底层物理卷。
issue_discards
设置前,请仔细阅读/etc/lvm/lvm.conf
中的注释。issue_discards
设置不会影响由逻辑卷文件系统产生的TRIM请求(如在文件系统内删除文件)的传递,也不会影响thin pool中的空间管理。issue_discards
后,将不能再使用vgcfgrestore恢复卷组元数据。一旦执行LVM命令,将无法撤销。为dm-crypt启用TRIM[编辑 | 编辑源代码]
对非/
文件系统,可修改/etc/crypttab
,在相应设备的options中加入discard
选项。(见 Dm-crypt/System configuration#crypttab)。
对于/
文件系统,依照 Dm-crypt/TRIM support for SSD 中的步骤来将正确的内核参数加入到bootloader配置中。
提升性能[编辑 | 编辑源代码]
参见Improving performance#Storage devices。
物理块大小[编辑 | 编辑源代码]
参见 Advanced Format#Solid state drives。
清空SSD[编辑 | 编辑源代码]
TRIM只在删除文件时起作用,而在增量保存等替换操作上无能为力。因此,即使在支持TRIM的SSD上,写入性能也会随时间降低。你可能想将SSD存储单元恢复到出厂时的状态,来使其恢复出厂时的写入性能。
要清除存储单元,依照SSD memory cell clearing中的步骤。
安全[编辑 | 编辑源代码]
Hdparm 显示 "frozen" 状态[编辑 | 编辑源代码]
一些主板BIOS在初始化时发送了"security freeze"命令给连接的SATA存储设备。同样,一些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状态(未设置HDD密码),其frozen状态可防止恶意软件在运行时对设备设置密码。
如果你想为"frozen"的设备设置密码,则主板BIOS必须支持该功能。因为支持设备密码是硬件加密所必需的,许多笔记本都支持该功能,但台式机/服务器主板则不然。例如,对于 Intel DH67CL/BL 主板,必须用跳线设置为"maintenance mode"来查看该设置 (见 [10], [11])。
hdparm
来改变上述的lock安全设置,除非你十分清楚自己在干什么。如果你想擦除SSD,见 Securely wipe disk#hdparm 以及上文。
从睡眠中唤醒时设置SSD为"frozen"状态[编辑 | 编辑源代码]
当从睡眠中唤醒时,SSD很可能失去"frozen"状态,这导致其可被ATA SECURE ERASE命令擦除。
要防止这一问题,可以在每次唤醒后运行一个脚本:
/usr/lib/systemd/system-sleep/ssd-freeze.sh
#!/bin/sh if [ "$1" = 'post' ]; then sleep 1 if hdparm --security-freeze /dev/disk/by-id/ata-name-of-disk; then logger "$0: SSD freeze command executed successfully" else logger "$0: SSD freeze command failed" fi fi
硬件加密[编辑 | 编辑源代码]
正如#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,在引导加载程序配置中添加内核命令行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。
支持TRIM的外接SSD[编辑 | 编辑源代码]
一些USB转SATA芯片(如VL715、VL716等)以及在外接NVMe硬盘盒(如IB-1817M-C31[失效链接 2022-09-23 ⓘ]))中使用的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 。此时,你应该检查设备的"Logical Block Provisioning"中的"Vital Product Data"页是否显示了支持的unmapping data机制。你可以执行以下命令:
# sg_vpd -a /dev/sdX
查看有无类似下面的输出:
Unmap command supported (LBPU): 1 Write same (16) with unmap bit supported (LBPWS): 0 Write same (10) with unmap bit supported (LBPWS10): 0
上例中,设备支持"UNMAP"命令。
此外,查看如下命令的输出:
$ cat /sys/block/sdX/device/scsi_disk/*/provisioning_mode
如果输出为"full",则表明内核没有检测到该设备支持unmap data。 除了"full"外,内核的SCSI存储驱动目前接受以下provisioning_mode的值:
unmap writesame_16 writesame_10 writesame_zero disabled
对于上例,要使内核使用"unmap"模式,你可以向"provisioning_mode"中写入"unmap":
# echo "unmap" >/sys/block/sdX/device/scsi_disk/*/provisioning_mode
之后,你应该能立刻在对应设备上使用blkdiscard等工具,并在其文件系统上使用fstrim。
如果你想对于特定制造商的所有产品或特定产品,当通过USB其连接时,都能自动设置provisioning_mode,可配置udev。
首先,找到对应设备的Vendor ID和Product ID:
$ cat /sys/block/sdX/../../../../../../idVendor $ cat /sys/block/sdX/../../../../../../idProduct
然后,创建或修改相应的udev规则(本例中使用idVendor 152d和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
(也可以使用lsusb
命令来查看idVendor/idProduct。)
固件更新[编辑 | 编辑源代码]
如果设备制造商支持,建议使用fwupd工具来更新固件。
ADATA[编辑 | 编辑源代码]
ADATA不支持在Linux下更新SSD固件。可以在此处下载仅支持Windows的SSD ToolBox工具。也可从此处下载ADATA XPG来对SSD进行监控、TRIM、基准测试或更新固件。
Crucial[编辑 | 编辑源代码]
Crucial 提供了以ISO镜像文件升级固件的选项。选择产品后,下载"Manual Boot File"可获取ISO镜像。
dd
命令将镜像复制到设备上,由于MBR不会被设置,将无法从该设备启动。要解决这一问题,可安装syslinux包并执行isohybrid path/to/image.iso
。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软件的系统,Intel提供了一个基于Linux live系统的固件更新工具。
此外,还可用使用Intel Memory and Storage (MAS) Tool(intel-mas-cli-toolAUR)命令行工具在Linux下刷入固件。(其PDF用户指南)
例如,要检查固件状态:
# 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提供Command Line Online Update Tool (CLOUT)。相关软件包可在AUR找到:ocz-ssd-utilityAUR、ocztoolboxAUR、oczcloutAUR。
Samsung[编辑 | 编辑源代码]
除了使用Magician软件外,也有其它方法升级固件(尽管Samsung认为这是”不受支持“的)。Magician软件可以创建包含固件更新的启动盘,然而Samsung不再为消费级SSD提供该软件。此外,Samsung提供的可引导的ISO镜像也能用来更新固件。还可以使用magician工具(samsung_magician-consumer-ssdAUR)。Magician只支持三星品牌的SSD,不支持Samsung为其它OEM(如联想)制造的SSD。
如果你想通过在Linux下创建的Live USB来更新固件(而不是在Microsoft Windows下使用Samsung的Magician软件),参见[12]。
在Linux下更新[编辑 | 编辑源代码]
此外,固件可在不使用USB启动盘的情况下直接更新。首先,从这里下载适用于对应SSD的最新固件(一个ISO镜像)。
initrd
镜像,见#较旧的SSD。从ISO镜像中解压Linux initrd
镜像(将samsung_ssd_firmware替换为对应的ISO镜像文件名):
$ bsdtar xf samsung_ssd_firmware.iso initrd
解压root/fumagician/
。该目录中包含固件更新文件:
$ bsdtar xf initrd root/fumagician
最后,以root权限运行root/fumagician/fumagician
,确认成功更新固件后,重启计算机。
较旧的SSD[编辑 | 编辑源代码]
有些SSD固件ISO中包含FreeDOS镜像而不是Linux initrd
镜像,故需要采取不同的更新方法。下表展示了这些SSD及固件的相对路径:
SSD型号 | FreeDOS镜像路径 | 固件包路径 |
---|---|---|
470, 830 | BTDSK.IMG |
SSR/
|
840 | isolinux/btdsk.img |
samsung/DSRD/
|
840 EVO (mSATA), Pro | ISOLINUX/BTDSK.IMG
|
首先,从ISO镜像中解压FreeDOS镜像(将samsung_ssd_firmware替换为对应的ISO镜像文件名,freedos_image_path替换为FreeDOS镜像路径,下同):
$ bsdtar xf samsung_ssd_firmware.iso freedos_image_path
将FreeDOS镜像挂载到/mnt/
:
# mount freedos_image_path /mnt
利用Magician SSD management utility获取SSD对应的Disk Number:
# magician --list
更新SSD固件(将firmware_package_path替换为对应的固件包路径):
# magician --disk Disk Number --firmware-update --fwpackage-path /mnt/firmware_package_path
最后,以root权限执行magician --list
,检查输出中Firmware对应的固件版本是否成功更新,并重启计算机。
SanDisk[编辑 | 编辑源代码]
对于SanDisk SSD Toolkit不支持的操作系统,SanDisk制作了ISO镜像来进行固件更新。
你必须选择对应SSD型号和容量的固件。烧录ISO镜像后,从创建的CD/DVD启动盘启动计算机即可(可能可以使用USB启动盘)。
此外,由于ISO镜像只包含了Linux内核及initrd,也可以将内核及initrd提取到/boot
下,并用GRUB或Syslinux启动来更新固件。
另见:
- SanDisk Extreme SSD Firmware Release notes 和 Manual Firmware update version R211
- SanDisk Ultra SSD Firmware release notes 和 Manual Firmware update version 365A13F0
- SanDisk Ultra+ SSD Firmware release notes 和 Manual Firmware update version X2316RL - 使用
smartctl -a /dev/sdX
检查是否使用了"H2"或"HP"模式。
另见[编辑 | 编辑源代码]
- Discussion on Reddit about installing Arch on an SSD
- 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