文件系統

出自 Arch Linux 中文维基

根據維基百科

文件系統控制數據的讀和寫。如果沒有文件系統,儲存介質裡的信息就會變成一塊無法理解的數據。通過把數據分塊、命名,不同的信息就可以被隔離、分辨。每組數據被命名為「文件」是取自紙質信息系統的命名方式。而「文件系統」是指用於管理信息的分組和命名的結構和邏輯規則。

文件系統有很多,每個磁盤分區可以而且只可以使用其中的某一個。每種文件系統有自己的優缺點和獨有特性。以下內容是目前所支持的文件系統類型的概述,相應的連結會提供更加詳細的信息。

文件系統類型[編輯 | 編輯原始碼]

filesystems(5) 包含一個簡單介紹,詳細比較參考 Wikipedia:Comparison of file systems。內核已經加載和內置的文件系統可以通過 /proc/filesystems 查看。通過 ls /lib/modules/$(uname -r)/kernel/fs 可以查看所有的內核模塊。

in-tree 和 FUSE 文件系統
文件系統 創建命令 工具 Archiso [1] 內核文檔 [2] 說明
Btrfs mkfs.btrfs(8) btrfs-progs [https://docs.kernel.org/filesystems/btrfs.html btrfs.html 可靠性
VFAT mkfs.fat(8) dosfstools vfat.html Windows 9x 的文件系統
exFAT mkfs.exfat(8) exfatprogs 從 Linux 內核 5.4 開始,內核原生支持該文件系統 [3]
mkexfatfs(8) exfat-utils N/A (FUSE-based)
F2FS mkfs.f2fs(8) f2fs-tools f2fs.html 基於閃存的設備
ext3 mkfs.ext3(8) e2fsprogs ext3.html
ext4 mkfs.ext4(8) e2fsprogs ext4.html
HFS mkfs.hfsplus(8) hfsprogsAUR hfs.html Classic Mac OS 文件系統
HFS+ mkfs.hfsplus(8) hfsprogsAUR hfsplus.html macOS (8-10.12) 文件系統
JFS mkfs.jfs(8) jfsutils jfs.html
NILFS2 mkfs.nilfs2(8) nilfs-utils nilfs2.html 原始閃存設備,如 SD 卡
NTFS ntfs3.html Windows NT 文件系統。從 Linux 5.15 起可用的新驅動
ntfs-3g[4] ntfs.html 舊驅動。寫入支持很有限。官方支持的內核構建時不包含CONFIG_NTFS_FS,因此不可用。
mkfs.ntfs(8) N/A (FUSE-based) 有較多功能的 FUSE 驅動。
ReiserFS mkfs.reiserfs(8) reiserfsprogs ReiserFS 已經從 Linux 5.18 中棄用並且計劃於2025年從內核中移除。
UDF mkfs.udf(8) udftools udf.html
XFS mkfs.xfs(8) xfsprogs

xfs.html
xfs-delayed-logging-design.html
xfs-self-describing-metadata.html

ZFS zfs-linuxAUR N/A (OpenZFS 移植)
注意: 內核中有 NTFS 驅動(參考ntfs.html),但是文件寫入支持很有限。
代碼在單獨倉庫的文件系統
文件系統 創建命令 內核補丁 用戶空間工具 說明
APFS mkapfs(8) linux-apfs-rw-dkms-gitAUR apfsprogs-gitAUR macOS (10.13 和更新) 文件系統,只讀,實驗版本.
Bcachefs bcachefs(8) linux-bcachefs-gitAUR bcachefs-tools-gitAUR
Reiser4 mkfs.reiser4(8) reiser4progsAUR
ZFS zfs-linuxAUR, zfs-dkmsAUR zfs-utilsAUR OpenZFS port

文件系統日誌[編輯 | 編輯原始碼]

以上除了 ext2 、FAT16/32(即VFAT)、Reiser4(可選開啟)、Btrfs 和 ZFS 以外的文件系統都使用文件系統日誌。文件系統日誌通過在數據更改寫入儲存設備前把變更寫入日誌來提供故障恢復能力。當出現系統崩潰或電源故障的時候,這些文件系統能夠更快的恢復到可用狀態,並且在恢復過程中更不容易出現錯誤。日誌活動在文件系統中專用的一部分空間裏進行。

並非所有的日誌技術都相同。ext3 和 ext4 提供 data-mode journaling,同時記錄數據本身和元數據(也有可以只記錄元數據變化)。這個模式對性能影響很大,默認是禁用的。

與此類似,Reiser4 的名為 "transaction models" 的模式不僅改變了它所提供的功能,也改變了它的日誌模式。這種日誌記錄模式使用了特別的日誌技術,wandering logs,來確定使用哪種寫入策略:寫入儲存器兩次; write-anywhere,純粹的 copy-on-write(和 btrfs 的類似,不過用的是另一種樹設計);hybrid,在前兩種之間智能切換。

注意: Reiser4 通過 node41 插件提供類似 ext4 的只記錄元數據的日誌模式,同時這個插件還實現了元數據和內聯校驗和,並且可根據其掛載的時候所選擇的 transaction model 來確定它所提供的 wandering logs 行為。

其它文件系統提供僅提供記錄元數據日誌的 ordered-mode journaling。儘管都能在崩潰後將文件系統恢復到正常狀態,data-mode journaling 提供了最大程度的數據安全防護,但代價是性能有所降低,因為數據會被寫兩次(第一次到日誌,第二次到磁盤)——而 Reiser4 通過 「wandering logs" 避免了這樣的重複。可以根據數據的重要性選擇文件系統。

Reiser4 是僅有的被設計成所有的操作都是完全 atomic 的同時還提供元數據和內聯數據的校驗和的文件系統——文件操作要麼完全完成,要麼就根本沒有發生,所以不會因為操作執行到一半而導致數據損壞。因此它發生數據丟失的可能性相比其他文件系統要低得多。

基於 copy-on-write (也叫 write-anywhere)的文件系統,比如Reiser4、Btrfs 和 ZFS 不需要用傳統的日誌保護元數據,因為元數據永遠不會被原地更新。雖然 Btrfs 還在使用日誌樹,但這個樹僅僅是為了加快 fdatasync/fsync 的速度。

基於 FUSE 的文件系統[編輯 | 編輯原始碼]

參考 FUSE

堆棧式文件系統[編輯 | 編輯原始碼]

  • eCryptfs — The Enterprise Cryptographic Filesystem,一個 Linux 磁盤加密軟件。它被設計為與POSIX兼容的文件系統級加密層,目標是在作業系統級別提供類似 GnuPG 的功能。
https://ecryptfs.org || ecryptfs-utils
  • mergerfs — 基於 FUSE 的聯合文件系統。
https://github.com/trapexit/mergerfs || mergerfsAUR
  • mhddfs — 多機械硬盤 FUSE 文件系統, 基於 FUSE 的聯合文件系統。
http://mhddfs.uvw.ru || mhddfsAUR
  • overlayfs — OverlayFS 是為 Linux 設計的聯合文件系統服務,實現了聯合掛載其他文件系統的功能。
https://docs.kernel.org/filesystems/overlayfs.html || linux
  • Unionfs:為 Linux、FreeBSD and NetBSD 設計的文件系統服務, 實現了聯合掛載其他文件系統的功能。[5]
  • unionfs-fuse — Unionfs 的用戶空間實現.
https://github.com/rpodgorny/unionfs-fuse || unionfs-fuse

只讀文件系統[編輯 | 編輯原始碼]

  • SquashFS — SquashFS 是一個壓縮的只讀文件系統,它壓縮文件、inodes和目錄,而且最高支持 1 MB 大小的 block 來實現更強力的壓縮。
http://squashfs.sourceforge.net/ || squashfs-tools

集群文件系統[編輯 | 編輯原始碼]

  • Ceph — 統一的分佈式存儲系統,旨在實現出色的性能,可靠性和可擴展性。
https://ceph.com/ || cephAUR
  • Glusterfs — 支持擴展到幾PB的集群文件系統。
https://www.gluster.org/ || glusterfs
  • IPFS — 一種點對點超媒體協議,使網絡更快,更安全,更開放。 IPFS旨在取代HTTP並為我們所有人構建更好的網絡。 它使用 block 來存儲文件的一部分,每個網絡節點僅存儲它感興趣的內容,提供去重的、分佈式的可擴展文件系統。 (alpha階段)
https://ipfs.io/ || kubo
  • MooseFS — MooseFS 是一個容錯、高可用性和高性能的向外擴展的擴展網絡分佈式文件系統。
https://moosefs.com || moosefs
  • OpenAFS — AFS分佈式文件系統的開源實現
https://www.openafs.org || openafsAUR
  • OrangeFS:OrangeFS 是一個向外擴展的網絡文件系統,為透明、並行地訪問基於多個伺服器的磁盤儲存而設計。它為並行分佈式應用提供了優化的 MPI-IO。它使 Linux 客戶端、Windows、Hadoop 和 WebDAV 使用並列儲存器變得簡便。它與POSIX兼容,而且是 Linux kernel (4.6+)的一部分。[6]
  • Sheepdog:用於卷和容器服務的分佈式對象存儲系統,能智能地管理磁盤和節點。[7]
  • Tahoe-LAFS — Tahoe Least-Authority Filesystem 是一個免費、開放、安全、去中心化、容錯、點對點的分佈式 data store 和分佈式文件系統。
https://tahoe-lafs.org/ || tahoe-lafsAUR

查看現有文件系統[編輯 | 編輯原始碼]

lsblk 查看:

$ lsblk -f
NAME   FSTYPE LABEL     UUID                                 MOUNTPOINT
sdb                                                          
└─sdb1 vfat   Transcend 4A3C-A9E9

如果文件系統存在,那 FSTYPE 列會顯示它的名字;如果它被mount了,掛載點會顯示在 MOUNTPOINT 那一列。

創建文件系統[編輯 | 編輯原始碼]

文件系統可以創建在一個分區上、邏輯容器如 LVMRAID,或者 dm-crypt 上或普通文件上(參考 Loop設備)。這裏描述創建在分區上的情況。

注意: 文件系統可以直接寫入到設備上,這樣的設備叫做 superfloppy 或者 無分區磁盤。這樣做會帶來一些約束,特別是用它來 啟動 系統。
警告:
  • 創建新文件系統之後,之前存放在該分區的數據會丟失且通常無法找回。請備份所有要保留的數據.
  • 某個分區用來幹什麼通常會限制能用什麼文件系統,比如 EFI分區 就只能用 mkfs.vfat 創建的 FAT32,而包含 /boot 的分區的文件系統要考慮 boot loader 是否支持。

創建文件系統之前,目標分區必須處於未掛載狀態。如果你要格式化的分區包含了一個已掛載的文件系統,在 lsblk 命令的 MOUNTPOINT 列中可以看到它。

$ lsblk -f
NAME   FSTYPE   LABEL       UUID                                 MOUNTPOINT
sda
├─sda1                      C4DA-2C4D                            
├─sda2 ext4                 5b1564b2-2e2c-452c-bcfa-d1f572ae99f2 /mnt
└─sda3                      56adc99b-a61e-46af-aab7-a6d07e504652 

你可以使用 umount 加上分區的掛載點來卸載這個文件系統:

# umount /mountpoint

查看掛載了的所有文件系統,參考#列出掛載的文件系統

mkfs(8) 創建新的文件系統,類型參見#文件系統類型。如果安裝了其他特殊的工具,按照它們的說明來做。比如,以下命令在 /dev/sda1 上創建了一個 ext4 文件系統:

# mkfs.ext4 /dev/sda1

此外,你可以使用 mkfs。這是 mkfs.fstype 工具的統一入口。上面的命令等價於:

# mkfs -t ext4 /dev/sda1
提示:
  • mkfs.ext4 的時候可以用 -L 選項來給文件系統設置一個 標籤e2label 用來對已經存在的文件系統改標籤。
  • 文件系統在創建之後是有條件地 改變大小(resized)的。比如 XFS 可以擴容,但是不能縮小。參考 Resize capabilities

創建完成之後新的文件系統就可以掛載到某個目錄了。

掛載文件系統[編輯 | 編輯原始碼]

如果要手動掛載一個設備上的文件系統到某個目錄,用 mount(8)。下面這個例子把 /dev/sda1 掛載到 /mnt

# mount /dev/sda1 /mnt

掛載之後,在 /mnt 下面就能看見 /dev/sda1 裏面的內容。掛載之前 /mnt 文件夾裡的內容在掛載之後將會變得不可見,直到 unmount 掉 /dev/sda1

fstab 描述了如果某個設備存在的話系統應該怎麼自動掛載它。如果要修改 /etc/fstab,請閱讀 fstab

如果 /etc/fstab 裡描述了一個設備的掛載參數,而用 mount 時只給了設備名字或者掛載點,fstab 裡的參數就會自動補上。比如,/etc/fstab 裡指示 /dev/sda1 應該掛載到 /mnt,那下面的命令就會把 /dev/sda1 掛載到 /mnt,即使你沒有顯式指明:

# mount /dev/sda1

或者

# mount /mnt

mount 接受很多參數,這些參數依賴於文件系統是否支持。要改變這些參數的話,可以通過以下形式:

列出掛載的文件系統[編輯 | 編輯原始碼]

findmnt(8) :

$ findmnt

findmnt 支持很多參數,可以利用它們來篩選輸出或者獲得更多信息。比如把某個掛載點或者設備作為參數,它就會只輸出這個下面掛載了什麼。

$ findmnt /dev/sda1

findmnt/etc/fstab/etc/mtab/proc/self/mounts 文件裡收集信息。

卸載文件系統[編輯 | 編輯原始碼]

umount(8) 來卸載文件系統。參數可以是包含文件系統的設備(比如/dev/sda1),也可以是掛載點(比如/mnt):

# umount /dev/sda1

或者

# umount /mnt

參閱[編輯 | 編輯原始碼]