固态硬盘
本文档涵盖了针对固态硬盘(SSD)和其他基于闪存的存储设备的特殊操作主题。
如果您想为特定目的对 SSD 进行分区,考虑《针对闪存、固态媒体优化的文件系统列表》可能会有所帮助。
用法
TRIM
与硬盘不同,硬盘仅在文件系统级别处理文件删除[1],固态硬盘(SSD)则可以通过通知磁盘控制器哪些内存块可以被重新使用来获益。由于固态硬盘的闪存单元每次写入操作都会磨损一点,磁盘控制器会使用算法将写入操作分散到所有单元上:这个过程称为磨损均衡。如果没有 NVMe DEALLOCATE、SAS UNMAP 或 ATA_TRIM 命令(大多数固态硬盘都支持),一旦没有空闲内存块,磁盘控制器就需要更长的时间来执行写入操作,因为它必须移动数据来擦除一个单元才能写入(参见 Wikipedia:写入放大):TechSpot 的基准测试显示了在固态硬盘填满数据之前和之后性能的影响。
从 Linux 内核版本 3.8 开始,TRIM 的支持在不同的文件系统中不断添加。以下表格提供了一个概览
| 文件系统 | 连续 TRIM ( discard 选项) |
定期 TRIM (fstrim) |
参考 和注释 |
|---|---|---|---|
| Bcachefs | 是 | 否 | |
| Btrfs | 是 | 是 | 自内核 6.2 起,异步 discard 默认启用。 |
| exFAT | 是 | 是 | fstrim 自内核 5.13 起支持[4] |
| ext3 | 是 | 是 | |
| ext4 | 是 | 是 | "discard, nodiscard(*)" 在[5] |
| F2FS | 是 | 是 | |
| JFS | 是 | 是 | [6] |
| NILFS2 | 是 | 是 | |
| NTFS | 是 | 否 | ntfs3 内核驱动程序仅支持连续 TRIM。 |
| 否 | 是 | NTFS-3G 驱动程序仅支持定期 TRIM。 | |
| VFAT | 是 | 是 | fstrim 自内核 4.19 起支持[7] |
| XFS | 是 | 是 | [8] |
| Swap | 是 | 否 | 严格来说不是“文件系统”,但 TRIM 仍然相关。“once”选项提供启动时计划的 TRIM。参见swapon(8)。 |
要验证 TRIM 支持,请运行
$ lsblk --discard
并检查 DISC-GRAN (discard granularity) 和 DISC-MAX (discard max bytes) 列的值。非零值表示支持 TRIM。
仅限 SATA SSD,hdparm 包可以通过 hdparm -I /dev/sda | grep TRIM 以root 用户身份检测 TRIM 支持。但是 hdparm 不支持 NVMe SSD。
定期 TRIM
该util-linux 包提供了 fstrim.service 和 fstrim.timer systemd 单元文件。启用计时器将每周激活一次服务。该服务在所有支持 discard 操作的设备上运行已挂载文件系统的fstrim(8)。
计时器依赖于 /var/lib/systemd/timers/stamp-fstrim.timer 的时间戳(首次调用时创建),以了解自上次运行以来是否已过一周。因此,无需担心过于频繁的调用,其工作方式类似于 anacron。
要查询单元活动和状态,请参阅journalctl。要更改计时器的周期或运行的命令,请编辑提供的单元文件。
连续 TRIM
除了偶尔发出 TRIM 命令(默认情况下,如果使用 fstrim.timer,则每周一次)之外,还可以选择在每次删除文件时都发出 TRIM 命令。后者称为连续 TRIM。
__ata_dev_quirks 条目以及 ATA_QUIRK_NO_NCQ_TRIM,由于严重的数据损坏,这些设备的排队 TRIM 命令执行已被列入黑名单。在这种情况下,根据设备的不同,系统可能被迫向固态硬盘发送非排队的 TRIM 命令而不是排队的 TRIM 命令。详情请参阅 Wikipedia:Trim (computing)#Disadvantages。在 /etc/fstab 中挂载时使用 discard 选项会在设备操作中启用连续 TRIM。例如
/dev/disk/by-designator/root / ext4 defaults,discard 0 1
在 ext4 文件系统上,也可以使用 tune2fs 将 discard 标志设置为 默认挂载选项
# tune2fs -o discard /dev/sdXY
使用默认挂载选项而不是 /etc/fstab 中的条目对于外置驱动器特别有用,因为这样的分区也会在其他机器上以默认选项挂载。这样,就不需要在每台机器上编辑 /etc/fstab 了。
/proc/mounts 中列出。TRIM 整个设备
如果您想一次性 TRIM 整个 SSD,例如用于新安装或要出售驱动器,可以使用 blkdiscard 命令。
TRIM 未分区空间
fdisk 只能 TRIM 分区之间的空闲扇区,以便这些扇区可以用于磨损均衡。使用 T 命令,然后在出现的提示符下按 f。
或者在 sfdisk 中使用 --discard-free 选项
# sfdisk --discard-free /dev/sdXY
LVM
从文件系统传递到逻辑卷的 TRIM 请求会自动传递到物理卷。无需额外配置。
默认情况下,没有 LVM 操作(lvremove、lvreduce 和所有其他操作)会向物理卷发出 TRIM 请求。这是为了允许使用vgcfgrestore(8) 恢复以前的卷组配置。/etc/lvm/lvm.conf 中的 issue_discards 设置控制着当逻辑卷不再使用物理卷空间时,是否将 discards 发送到底层物理卷。
issue_discards 设置之前,请仔细阅读 /etc/lvm/lvm.conf 中的注释。它不会以任何方式影响从文件系统传递到磁盘的 TRIM 请求(例如,文件系统内的文件删除),也不会影响 Thin Pool 中的空间管理。issue_discards 将阻止使用 vgcfgrestore 进行卷组元数据恢复。在错误地发出 LVM 命令的情况下将没有恢复选项。dm-crypt
请遵循dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD) 中的说明来为 LUKS 和纯 dm-crypt 设备启用 discard 支持。
swap
要为 swap 空间启用 discard,请在 fstab 中为 swap 设备条目添加 discard 选项,或在调用 swapon 时传递 --discard。
使用 GPT 分区自动挂载时,discard 不会自动为 swap 分区启用。
有关 swap 何时被 discard 的讨论,请参见swapon(8):discard=once 或 discard=pages。如果指定了 discard 但没有指定模式,则默认启用两者。
最大化性能
遵循提高性能#存储设备中的技巧来最大化您的驱动器的性能。
SSD 内存单元清除
有时,用户可能希望完全重置 SSD 的单元,使其恢复到安装时的初始状态,从而恢复其工厂默认写入性能。即使是支持原生 TRIM 的 SSD,写入性能也可能随着时间的推移而下降:TRIM 只能防止文件删除,而不能防止增量保存等替换操作。
可以通过遵循固态硬盘/内存单元清除中指定的相应过程来完成重置,无论是针对 SATA 还是 NVMe SSD。
安全
冻结模式
某些主板固件在初始化时会向 SATA 设备发出 ATA SECURITY FREEZE LOCK 命令,将驱动器设置为冻结模式,使其进入 SEC2 状态(安全禁用,未锁定,冻结)。同样,一些 SSD(和 HDD)在出厂时就处于此状态。这可以在 hdparm 和 smartctl 的输出中看到
# 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.
# smartctl -g security /dev/sda
ATA Security is: Disabled, frozen [SEC2]
格式化设备或安装操作系统的操作不受冻结模式的影响。
上面的 hdparm 输出显示设备在启动时未被 HDD-密码锁定,而冻结状态可以防止恶意软件尝试通过在运行时设置密码来锁定设备。
如果您打算自己为“冻结”设备设置密码,则需要支持该功能的母板 BIOS。许多笔记本电脑都支持,因为这是硬件加密所必需的,但对于台式机/服务器主板来说,支持可能并不简单。例如,对于 Intel DH67CL/BL 主板,必须通过物理跳线将主板设置为“维护模式”才能访问设置。[10]
如果您打算擦除 SSD,请参阅安全擦除磁盘#hdparm和/内存单元清除。
从睡眠唤醒后将 SATA SSD 设置为冻结模式
从 S3 睡眠唤醒时,SATA SSD 很可能已恢复到 SEC1 状态(安全禁用,未锁定,未冻结),使其容易受到 ATA SECURITY ERASE UNIT 命令的影响,例如/内存单元清除中描述的命令。
为了防止此问题,可以在从睡眠唤醒后运行一个脚本
/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
如果系统有多个存储设备和/或便携式 USB 驱动器,另一个选择是改编Hdparm#使用 udev 规则的持久化配置以对所有驱动器(包括 HDD)发出 --security-freeze。
硬件加密
如#冻结模式中所述,在 BIOS 中为存储设备(SSD/HDD)设置密码也可能初始化支持硬件加密的设备。如果设备还符合 OPAL 标准,即使没有相应的 BIOS 功能来设置密码,也可以实现这一点。请参阅自加密驱动器。
故障排除
您遇到的问题可能是固件 bug,与 Linux 无关,因此在尝试解决影响 SSD 设备的任何问题之前,您应该首先检查以下更新是否可用:
- SSD 的固件
- 主板的BIOS/UEFI 固件
即使是固件 bug,也有可能避免它,所以如果没有固件更新,或者您不愿更新固件,那么以下方法可能会有帮助。
解决 NCQ 错误
某些 SSD 和 SATA 芯片组与 Linux 本地命令队列 (NCQ) 工作不正常。在日志中,标志性的错误如下所示:
ata9: exception Emask 0x0 SAct 0xf SErr 0x0 action 0x10 frozen ata9.00: failed command: READ FPDMA QUEUED ata9.00: cmd 60/04:00:d4:82:85/00:00:1f:00:00/40 tag 0 ncq 2048 in res 40/00:18:d3:82:85/00:00:1f:00:00/40 Emask 0x4 (timeout)
要在启动时禁用 NCQ,请在引导加载程序配置中将 libata.force=noncq 添加到内核命令行。要仅为端口 9 上的磁盘 0 禁用 NCQ,请使用:libata.force=9.00:noncq
或者,您可以在不重启的情况下通过 sysfs 为特定驱动器禁用 NCQ
# echo 1 > /sys/block/sdX/device/queue_depth
如果这(以及更新固件)不能解决问题或导致其他问题,则提交 bug 报告。
解决 SATA 电源管理相关错误
一些 SSD(例如 Transcend MTS400 或 Crucial M550 SSD)在启用SATA 主动链路电源管理 (ALPM)时,与某些 SATA 控制器存在问题。
ALPM 自 linux-4.16 起默认启用,或者可能由节能守护程序(例如TLP、Laptop Mode Tools)在运行时启用。有关详细信息,请参阅电源管理#SATA 主动链路电源管理。
支持 TRIM 的外置 SSD
许多 USB-to-SATA 桥接芯片(如 VL715、VL716 等)以及 USB-to-PCIe 桥接芯片(如外置 NVMe 硬盘盒中使用的JMicron JMS583,例如IB-1817M-C31)支持可以通过USB Attached SCSI驱动程序(Linux 下称为“uas”)发送的类 TRIM 命令。
但是内核可能不会自动检测到此功能,因此可能不会使用它。假设您要处理的块设备是 /dev/sdX,您可以使用来自sg3_utils 的命令来确定是否如此。
# sg_readcap -l /dev/sdX
如果其输出中有一行显示 Logical block provisioning: lbpme=0,那么您就知道内核假定设备不支持“逻辑块分配管理”,因为 (LBPME) 位未设置。
如果是这种情况,那么您应该接下来找出您的设备的“关键产品数据”(VPD) 页关于“逻辑块分配”是否说明了支持的取消映射数据机制。您可以使用以下命令来执行此操作:
# 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”。除了“full”之外,内核 SCSI 存储驱动程序当前知道 provisioning_mode 的以下值:
unmap writesame_16 writesame_10 writesame_zero disabled
对于上面的例子,您现在可以向“provisioning_mode”写入“unmap”,以要求内核使用该模式
# echo "unmap" >/sys/block/sdX/device/scsi_disk/*/provisioning_mode
这应该会立即使您能够对 /dev/sdX 上的工具(如 blkdiscard)或 /dev/sdX 上挂载的文件系统上的 fstrim 使用。
如果您想在连接特定供应商/产品的外置设备时自动启用“provisioning_mode”,可以通过“udev”机制来实现。首先找到 USB 供应商和产品 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 工具更新固件。
检查您当前的固件版本
# smartctl -i /dev/ssd_device
ADATA
ADATA 不支持在 Linux 下更新 SSD 固件。ADATA 通过其支持页面和 ADATA XPG支持页面提供一个名为 SSD ToolBox 的 Windows 独占实用程序,用于监控、TRIM、基准测试和更新 ADATA SSD 固件。
Crucial
Crucial 提供使用 ISO 映像更新固件的选项。在 SSD 支持页面上选择产品后,下载“Manual Boot File”即可找到这些映像。
dd 命令将映像复制到某个设备,则MBR将不存在,使该设备无法启动。安装syslinux并运行 isohybrid path/to/image.iso。M4 Crucial 型号的所有者可以通过 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 固件。
除了可启动 ISO 之外,micron-storage-executive-cliAUR 是一个用于刷新固件的命令行工具,还提供额外的 SSD 信息。
Intel
Intel 为与 Windows Intel® Memory and Storage Tool (GUI) 软件不兼容的操作系统提供了一个基于 Linux Live 系统的固件更新工具。
还有一个较新的 Linux 命令行实用程序,可以重新刷新固件,称为 Intel Memory and Storage (MAS) Tool,可作为intel-mas-cli-toolAUR 提供。还有一个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.
如果系统中只有一个 Intel SSD,则可以省略 -intelssd 0,或者为第二个 SSD 传递 1,以此类推。
如果可用更新,则通过运行 intelmas load -intelssd 0 来执行。PDF 用户指南建议在 Linux 中需要执行此过程两次,中间进行一次电源循环。所有设备的最新固件作为 MAS Tool 本身的一部分分发,因此无需单独下载。
Kingston
Sandforce 基于的驱动器可以使用 KFU 工具,kingston_fw_updaterAUR。
Mushkin
不太为人所知的 Mushkin 品牌固态硬盘也使用 Sandforce 控制器,并且有一个 Linux 实用程序(几乎与 Kingston 的相同)来更新固件。
OCZ
OCZ 提供一个适用于 Linux 的命令行在线更新工具 (CLOUT)。现有软件包为ocz-ssd-utilityAUR、ocztoolboxAUR 和oczcloutAUR。
Samsung
虽然三星认为非 Magician 软件的固件更新方法是“不受支持”的,但它们仍然可以工作。Magician 软件可以创建一个包含固件更新的可启动 USB 驱动器,但是三星不再为消费级 SSD 提供该软件。三星还提供了预制的可启动 ISO 映像,可用于更新固件。另一个选项是使用由samsung_magician-consumer-ssdAUR提供的三星 magician 实用程序。Magician 仅支持三星品牌 SSD;为 OEM 制造的三星 SSD(例如,联想)则不支持。
倾向于从 Linux 下创建的 Live USB 运行固件更新(不使用 Microsoft Windows 下的三星 Magician 软件)的用户可以参考[11]以获取更多详细信息。请注意,此博客文章详细介绍了使用主引导记录 (MBR) 创建可启动 USB 驱动器,而某些较新主板(例如Intel NUC)已不再支持此功能。
在 Linux 下更新
SSD 固件可以原生地更新(无需创建可启动 USB 棒),如下所示。首先访问三星下载页面,转到“Samsung SSD Firmware”部分,然后下载您的 SSD 的最新固件—它应该是一个 ISO 映像。
initrd Linux 映像。请参阅#较旧的 SSD。从 ISO 映像中提取 initrd Linux 映像
$ bsdtar xf samsung_ssd_firmware.iso initrd
提取 root/fumagician/。此目录包含固件更新文件
$ bsdtar xf initrd root/fumagician
最后,以 root 权限运行 root/fumagician/fumagician,如果固件已成功更新,则重启您的系统。
如果重启后固件版本未更改,请运行 root/fumagician/fumagician 2> log 并搜索日志文件中的错误。例如,如果日志显示“unzip is not available”,请安装 unzip 或从 initrd 中提取它。
较旧的 SSD
一些 SSD 固件 ISO 映像包含 FreeDOS 映像而不是 initrd Linux 映像,因此更新 SSD 固件所需的步骤与上述不同。下表列出了这些 SSD(及其相关路径)
| SSD 型号 | FreeDOS 映像路径 | 固件包路径 |
|---|---|---|
| 470, 830 | BTDSK.IMG |
SSR/
|
| 840 | isolinux/btdsk.img |
samsung/DSRD/
|
| 840 EVO (mSATA), Pro | ISOLINUX/BTDSK.IMG
|
首先,从 ISO 映像中提取 FreeDOS 映像
$ bsdtar xf samsung_ssd_firmware.iso freedos_image_path
将 FreeDOS 映像挂载到 /mnt/
# mount freedos_image_path /mnt
从 Magician SSD 管理实用程序中获取 SSD 的磁盘号(在 *Disk Number* 下)
# magician --list
通过提供固件包路径来更新指定磁盘的 SSD 固件
# magician --disk disk_num --firmware-update --fwpackage-path /mnt/firmware_package_path
最后,通过检查 magician --list(以 root 权限运行)的输出中 *Firmware* 下的版本来验证固件是否已成功更新。如果更新成功,则重启您的系统。
SanDisk
SanDisk 提供 ISO 固件映像,允许在 SanDisk SSD Toolkit 不支持的操作系统上更新 SSD 固件。
必须选择适用于正确 *SSD 型号*和其容量(例如 60GB,或 256GB)的固件。刻录 ISO 固件映像后,只需重新启动 PC 以使用新创建的 CD/DVD 启动盘启动(可能可以从 USB 棒启动)。
ISO 映像仅包含一个 Linux 内核和一个 initrd。将它们提取到 /boot 分区,并使用 GRUB 或 Syslinux 引导它们来更新固件。
参见
- SanDisk Extreme SSD 手动固件更新版本 R211
- SanDisk Ultra SSD 手动固件更新版本 365A13F0
- SanDisk Ultra+ SSD 手动固件更新版本 X2316RL - 作为 root 用户使用
smartctl -i dev/disk/by-id/*SanDisk!(*part*)来确定使用的是“H2”还是“HP”型号。