本文介紹如何管理固態硬碟(SSD)等基於快閃記憶體的存儲設備。
如果要針對特定目的對 SSD 進行分區,請參考針對快閃記憶體優化的文件系統清單。
使用
TRIM
在機械硬碟上,刪除操作是在文件系統層級上處理的[1],而 SSD 會向硬碟主控通知特定區域的空間可以被再次使用。由於每次寫入操作都會對快閃記憶體單元一定磨損,因此主控會使用算法來將寫操作平衡到快閃記憶體的所有單元上,這被稱作耗損平均技術。在不使用 NVMe DEALLOCATE,SAS UNMAP 或 ATA_TRIM 命令(多數 SSD 都支持)的情況下,如果沒有空餘的存儲塊,主控就需要反覆搬運數據以空出一個最小擦除單元,並擦除該單元以寫入數據,導致寫入耗時增加(詳見:寫入放大)。關於 SSD 空間占滿前後的性能對比可參考 TechSpot 的評測。
自 Linux 內核版本 3.8 開始,對 TRIM 的支持不斷被添加到不同的文件系統中。見下表:
文件系統 | 持續性 TRIM ( discard 選項) |
定期 TRIM (fstrim) |
參考與備註 |
---|---|---|---|
Bcachefs | 是 | 否 | |
Btrfs | 是 | 是 | 從 6.2 內核版本開始默認啟用異步 discard |
exFAT | 是 | 是 | 從 5.13 內核版本開始支持 fstrim [4] |
ext3 | 是 | 是 | |
ext4 | 是 | 是 | 「discard, nodiscard(*)」 [5] |
F2FS | 是 | 是 | |
JFS | 是 | 是 | [6] |
NILFS2 | 是 | 是 | |
NTFS | 是 | 否 | ntfs3 內核驅動僅支持持續性 TRIM |
否 | 是 | NTFS-3G 驅動僅支持定期 TRIM | |
VFAT | 是 | 是 | 從 4.19 內核版本開始支持 fstrim [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包 檢測 TRIM 支持:以根用戶執行 hdparm -I /dev/sda | grep TRIM
。注意:hdparm
不支持 NVMe SSD。
定期 TRIM
util-linux包 提供了 fstrim.service
和 fstrim.timer
兩個 systemd 單元文件。啟用 fstrim.timer
計時器會在每周激活服務,在所有已掛載的支持 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 命令,具體請參考 Wikipedia:Trim_(computing)#Disadvantages。要使用持續性 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
由 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
為 LUKS 和普通 dm-crypt 設備啟用 discard 的步驟請參考 dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD)。
swap
可以通過將 discard
選項添加到 fstab 中的 swap 設備條目或調用 swapon
時傳遞 --discard
選項為 swap 啟用 discard。
在使用 Systemd#GPT分區自動掛載 時,discard 不會被自動應用到 swap 分區。
See swapon(8) for discussion on when swap is discarded: discard=once
or discard=pages
. If discard
is specified without a specific mode, the default is to enable both.
提升性能
參見性能優化#存儲設備。
清空 SSD
有時用戶可能會想將 SSD 的存儲單元重置回出廠狀態,從而恢復到出廠時的寫入性能。由於 TRIM 只對文件刪除有用,而對替換操作(如增量保存)無能為力,因此就算 SSD 帶有原生 TRIM 支持,其寫入性能還是會隨時間逐漸下降。
無論是 SATA 還是 NVMe SSD,都可以參考 固態硬碟/Memory cell clearing 中的對應步驟進行重置。
安全
凍結(Frozen)模式
有些主板的固件會在初始化時向 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 密碼鎖定,frozen 凍結狀態可防止惡意軟體在運行時對設備設置密碼進行鎖定。
如果你想手動為「凍結」的設備設置密碼,需要主板 BIOS 支持該功能的。由於硬體加密的需要,很多筆記本都支持該功能,但台式機/伺服器主板上則不然。以 Intel DH67CL/BL 主板為例,需要通過板上跳線將主板設為「維護模式」才能訪問該設置。[10]
如果你想擦除 SSD,請參考 Securely wipe disk#hdparm 和 /Memory cell clearing。
從睡眠中喚醒時設置 SATA SSD 為凍結模式
當從 S3 睡眠狀態喚醒時,SATA SSD 很可能會回到 SEC1 狀態(禁用安全、非鎖定、非凍結),導致其有可能受 /Memory cell clearing 中描述的 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 規則使配置持久化 為所有硬碟(包括機械硬碟)指定 --security-freeze
。
硬體加密
正如#凍結(Frozen)模式中提到的,在設備支持的情況下,在 BIOS 中為存儲設備(SSD/HDD)設置密碼可能同時會啟用硬體加密。如果設備同時符合 OPAL 標準,即使 BIOS 沒有設置密碼的功能,硬體加密也可能啟動,具體請參考 Self-encrypting drives。
故障排除
你遇到的問題可能是由於 SSD 固件而不是 Linux 產生的。在嘗試排除故障前,請檢查固件是否有更新:
即使是固件的 bug,也可能在不更新固件的情況下避免。若沒有固件更新可用,或你不想進行固件更新,以下內容可能有所幫助。
處理 NCQ 錯誤
部分 SSD 和 SATA 晶片組在 Linux 的原生命令隊列(NCQ)下不能正常工作。通過 journal 可看到如下錯誤信息:
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
。例如,要僅為硬碟 0 埠 9 禁用 NCQ,可以使用:libata.force=9.00:noncq
或者,可通過 sysfs 在不重啟的情況下為指定設備禁用 NCQ:
# echo 1 > /sys/block/sdX/device/queue_depth
如果更新固件並完成操作後問題仍未解決或導致了其他問題,請提交 bug 報告。
處理與 SATA 電源管理有關的錯誤
某些 SSD(如 Transcend MTS400 或 Crucial M550)搭配特定 SATA 控制器時,在 ALPM 啟用時會出現故障。
Linux 從 4.16 版本開始默認啟用,也可能會被節能守護進程(例如 TLP 和 Laptop Mode Tools)啟用。更多信息請參考電源管理#SATA 活動鏈路電源管理。
支持 TRIM 的外接 SSD
有多個 USB 轉 SATA 橋接晶片(如 VL715,VL716 等)及 USB 轉 PCIe 橋接晶片(如 IB-1817M-C31 外置 NVMe 硬碟盒使用的 JMicron JMS583)支持類似 TRIM 的命令,這些命令可通過 USB Attached SCSI 驅動程序(在 Linux 下稱為"uas")發送。
然而內核可能不會自動檢測到並啟用這一功能。 假設有問題的設備為 /dev/sdX,可以通過 sg3_utils包 使用以下命令確定是否為這種情況:
# sg_readcap -l /dev/sdX
如果輸出中有一行寫著「Logical block provisioning: lbpme=0」,就意味著由於沒有設置 LBPME 位,內核認為該設備不支持「Logical Block Provisioning Management」。
在這種情況下,就需要找出設備上的「Logical Block Provisioning」中的「Vital Product Data」(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
對於以上示例,現在可以通過將「unmap」寫入到「provisioning_mode」讓內核使用「unmap」模式:
# echo "unmap" >/sys/block/sdX/device/scsi_disk/*/provisioning_mode
現在就可以在 /dev/sdX 上使用 blkdiscard 等工具,或是對 /dev/sdX 上的文件系統上使用 fstrim。
如果想在特定廠商或產品設備連接時自動啟用一個「provisioning_mode」,可以使用 udev。首先找到 USB Vendor 和 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 工具來更新固件。
檢查當前固件版本:
# smartctl -i /dev/ssd_device
威剛(ADATA)
威剛不支持在 Linux 下更新 SSD 固件。可以在支持頁下載僅支持 Windows 的 SSD ToolBox 工具,也可從支持頁下載 ADATA XPG 來對 SSD 進行監控、TRIM、基準測試或更新固件。
英睿達(Crucial)
英睿達提供了以 ISO 鏡像文件升級固件的選項。在 SSD 支持頁選擇產品後,下載「Manual Boot File」可獲取 ISO 鏡像。
dd
命令將鏡像複製到設備上,由於沒有配置 MBR,將導致無法從該設備啟動。要解決這一問題,可安裝 syslinux包 並執行 isohybrid path/to/image.iso
。Crucial M4 用戶可通 過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 軟體的系統,英特爾提供了一個基於 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.
如果只有一個 Intel SSD,可以省略 -intelssd 0
;如果要指定第二塊 SSD,則修改為 -intelssd 1
,依此類推。
如果有可用的更新,可通過 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 軟體外,也有其它方法升級固件(儘管三星認為這是「不受支持」的)。Magician 軟體可以創建包含固件更新的啟動盤,然而三星不再為消費級 SSD 提供該軟體。此外,三星提供的可引導 ISO 鏡像也能用來更新固件。另外一種方法是使用 magician 工具(samsung_magician-consumer-ssdAUR)。Magician 只支持三星品牌的 SSD,不支持三星為其它 OEM(如聯想)製造的 SSD。
如果你想通過在 Linux 下創建的 Live USB 來更新固件(而不是在 Windows 下使用三星的 Magician 軟體),參見[11]。注意,該文章描述的通過 MBR 創建可啟動 U 盤的方法在一些新主板上(例如 Intel NUC)不再受支持。
在 Linux 下更新
以下方法可以原生(不使用可啟動 U 盤)更新 SSD 固件。首先,訪問三星的下載頁,進入」Samsung SSD Firmware「一節,然後下載適用於你的 SSD 的最新固件(ISO 鏡像)。
initrd
Linux 鏡像,請跳到#較舊的 SSD 一節。從 ISO 鏡像中解壓 Linux initrd
鏡像(將 samsung_ssd_firmware 替換為對應的 ISO 鏡像文件名):
$ bsdtar xf samsung_ssd_firmware.iso initrd
解壓 root/fumagician/
。該目錄中包含固件更新文件:
$ bsdtar xf initrd root/fumagician
最後,以根用戶權限運行 root/fumagician/fumagician
,確認成功更新固件後,重啟計算機。
如果重啟後固件版本沒有變化,可以執行 root/fumagician/fumagician 2> log
並檢查日誌裡的報錯。例如,如果日誌裡寫著 'unzip is not available',就說明需要安裝 unzip 或從 initrd 中提取 unzip。
較舊的 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 的 Disk Number 獲取 SSD 對應的硬碟編號:
# magician --list
更新 SSD 固件(將 firmware_package_path 替換為對應的固件包路徑):
# magician --disk Disk Number --firmware-update --fwpackage-path /mnt/firmware_package_path
最後,以根用戶權限執行 magician --list
,檢查輸出中 Firmware 對應的固件版本是否成功更新,並重啟計算機。
閃迪(SanDisk)
對於 SanDisk SSD Toolkit 不支持的作業系統,閃迪提供了 ISO 鏡像來進行固件更新。
你必須選擇對應 SSD 型號和容量(例如 60GB 或 256GB)正確的固件。燒錄 ISO 鏡像後,從創建的 CD/DVD 啟動盤啟動計算機即可(或許能使用 USB 啟動盤)。
此外,由於 ISO 鏡像只包含了 Linux 內核及 initrd,也可以將它們提取到 /boot
分區下,並用 GRUB 或 Syslinux 啟動來更新固件。
另見:
- SanDisk Extreme SSD Manual Firmware update version R211
- SanDisk Ultra SSD Manual Firmware update version 365A13F0
- SanDisk Ultra+ SSD Manual Firmware update version X2316RL - 以根用戶權限執行
smartctl -i dev/disk/by-id/*SanDisk!(*part*)
檢查是否使用了「H2」或「HP」型號。