跳至內容
出自 Arch Linux 中文维基

本文介紹如何管理固態硬碟(SSD)等基於快閃記憶體的存儲設備。

如果要針對特定目的對 SSD 進行分區,請參考針對快閃記憶體優化的文件系統清單

對於一般用途,您只需選擇喜好的文件系統並啟用 #TRIM

使用

TRIM

在機械硬碟上,刪除操作是在文件系統層級上處理的[1],而 SSD 會向硬碟主控通知特定區域的空間可以被再次使用。由於每次寫入操作都會對快閃記憶體單元一定磨損,因此主控會使用算法來將寫操作平衡到快閃記憶體的所有單元上,這被稱作耗損平均技術。在不使用 NVMe DEALLOCATE,SAS UNMAPATA_TRIM 命令(多數 SSD 都支持)的情況下,如果沒有空餘的存儲塊,主控就需要反覆搬運數據以空出一個最小擦除單元,並擦除該單元以寫入數據,導致寫入耗時增加(詳見:寫入放大)。關於 SSD 空間占滿前後的性能對比可參考 TechSpot 的評測

注意:如果要使用 TRIM,只能在定期 TRIM 和持續性 TRIM 間二選一。Linux 社區認為持續性 TRIM 不是首選的 TRIM 方法,例如 Ubuntu 就默認使用定期 TRIM [2],Debian 也不建議使用持續性 TRIM,紅帽建議儘可能選擇使用定期 TRIM [3]

自 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 功能前,請確保 SSD 支持 TRIM,否則可能導致數據丟失!

要檢查 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.servicefstrim.timer 兩個 systemd 單元文件。啟用 fstrim.timer 計時器會在每周激活服務,在所有已掛載的支持 discard 操作的文件系統上執行 fstrim(8)

該計時器使用 /var/lib/systemd/timers/stamp-fstrim.timer(將在服務第一次啟動時創建)的時間戳來判斷上次運行的時間。因此,不必擔心服務被過於頻繁地調用(類似 anacron)。

單元的狀態與活動記錄可通過 journalctl 查看。若要修改運行的周期或執行的指令,可編輯單元文件。

持續性 TRIM

除定期執行 TRIM 指令外(若使用 fstrim.timer 則默認為每周一次),也可每次在文件被刪除後就立即執行 TRIM 指令(這被稱為持續性 TRIM)。

警告:SATA 3.1 前,所有 TRIM 指令都是非隊列化的,因此使用持續性 TRIM 將造成系統頻繁卡頓,這種情況下應使用 #定期 TRIM。另外,某些設備(具體請參考 Linux 源碼中的 __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
注意:不能在 /etc/fstab 中為 XFS / 分區指定 discard 掛載選項。根據此帖子,必須使用 rootflags=discard 內核參數

對於Ext4文件系統,也可用 tune2fsdiscard 設置為一個默認掛載選項

# tune2fs -o discard /dev/sdXY

對於可行動裝置,由於配置後的分區在其它設備上也會使用默認掛載選項,使用此方式而不是在 /etc/fstab 中新增條目尤其有用。這樣,在其他計算機上掛載分區時,就不需要每次修改 /etc/fstab 了。

注意:此默認掛載選項不會在 /proc/mounts 中列出。

Trim 整個設備

當在全新安裝或想賣掉你的 SSD 時,你可能想 Trim 整個設備,這時候可以使用 blkdiscard 命令。

LVM

由 LVM 邏輯卷上的文件系統產生的 TRIM 請求將直達對應物理卷,無需額外的配置。

LVM 操作(lvremovelvreduce等)默認不會產生 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

警告:dm-crypt 支持將 discard 請求傳遞到底層塊設備上。這不一定能提升 SSD 的性能[9],而且還有安全風險,因此默認不被啟用。

為 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.

警告:對於使用 mdadm 的 RAID 配置,為 swapon 啟用 discard 會導致系統在啟動和運行時鎖死。

提升性能

參見性能優化#存儲設備

清空 SSD

有時用戶可能會想將 SSD 的存儲單元重置回出廠狀態,從而恢復到出廠時的寫入性能。由於 TRIM 只對文件刪除有用,而對替換操作(如增量保存)無能為力,因此就算 SSD 帶有原生 TRIM 支持,其寫入性能還是會隨時間逐漸下降。

無論是 SATA 還是 NVMe SSD,都可以參考 固態硬碟/Memory cell clearing 中的對應步驟進行重置。

注意:如果你想通過清除存儲單元來清除數據,靠 SSD 控制器來執行該操作可能並不安全可靠。如果你不信任 SSD 製造商或擔心固件中潛在的 bug,可以參考 Securely wipe disk#Flash memory 中的信息和範例進行手動擦除。

安全

凍結(Frozen)模式

有些主板的固件會在初始化時向 SATA 設備發送 ATA SECURITY FREEZE LOCK 命令,將硬碟設為凍結模式(即切換到 SEC2 狀態,禁用安全、非鎖定並凍結)。同樣,有些 SSD 和 HDD 在出廠時也會設成該狀態。可以通過 hdparmsmartctl 的輸出確認該現象:

# 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]

警告:除非你十分清楚自己在幹什麼,否則不要試圖用 hdparm 來改變上述的 lock 安全設置。

如果你想擦除 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 版本開始默認啟用,也可能會被節能守護進程(例如 TLPLaptop Mode Tools)啟用。更多信息請參考電源管理#SATA 活動鏈路電源管理

支持 TRIM 的外接 SSD

本文或本章節的語言、語法或風格需要改進。參考:幫助:風格

原因:Several style and formatting problems, especially too many explicit commands - see Help:Style#File editing requests.(在Talk:固態硬碟討論)

有多個 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、基準測試或更新固件。

警告:不建議嘗試通過 Wine 來更新固件,Wine 不是被設計來處理硬體接口操作的。使用 Wine 可能使固件更新不完整,導致 SSD 變磚。

英睿達(Crucial)

英睿達提供了以 ISO 鏡像文件升級固件的選項。在 SSD 支持頁選擇產品後,下載「Manual Boot File」可獲取 ISO 鏡像。

注意:英睿達提供的 ISO 鏡像似乎不是 hybrid 格式。如果直接使用 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) Toolintel-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-utilityAURocztoolboxAURoczcloutAUR

三星(Samsung)

除了使用 Magician 軟體外,也有其它方法升級固件(儘管三星認為這是「不受支持」的)。Magician 軟體可以創建包含固件更新的啟動盤,然而三星不再為消費級 SSD 提供該軟體。此外,三星提供的可引導 ISO 鏡像也能用來更新固件。另外一種方法是使用 magician 工具(samsung_magician-consumer-ssdAUR)。Magician 只支持三星品牌的 SSD,不支持三星為其它 OEM(如聯想)製造的 SSD。

注意:對於這些信息,三星提供得並不十分明確。他們似乎有 4 個不同的固件更新頁面,每個都介紹了不同的更新方法。

如果你想通過在 Linux 下創建的 Live USB 來更新固件(而不是在 Windows 下使用三星的 Magician 軟體),參見[11]。注意,該文章描述的通過 MBR 創建可啟動 U 盤的方法在一些新主板上(例如 Intel NUC)不再受支持。

在 Linux 下更新

以下方法可以原生(不使用可啟動 U 盤)更新 SSD 固件。首先,訪問三星的下載頁,進入」Samsung SSD Firmware「一節,然後下載適用於你的 SSD 的最新固件(ISO 鏡像)。

注意:若 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 分區下,並用 GRUBSyslinux 啟動來更新固件。

另見:

另見