歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

Linux 文件系統剖析

在文件系統方面,Linux® 可以算得上操作系統中的 “瑞士軍刀”。Linux 支持許多種文件系統,從日志型
文件系統到集群文件系統和加密文件系統。對於使用標准的和比較奇特的文件系統以及開發文件系統來說,Linux 是
極好的平台。本文討論 Linux 內核中的虛擬文件系統(VFS,有時候稱為虛擬文件系統交換器),然後介紹將文件

系統連接在一起的主要結構。


基本的文件系統體系結構

Linux 文件系統體系結構是一個對復雜系統進行抽象化的有趣例子。通過使用一組通用的 API 函數,Linux 可以在
許多種存儲設備上支持許多種文件系統。例如,read 函數調用可以從指定的文件描述符讀取一定數量的字節。read
函數不了解文件系統的類型,比如 ext3 或 NFS。它也不了解文件系統所在的存儲媒體,比如 AT Attachment Packet
Interface(ATAPI)磁盤、Serial-Attached SCSI(SAS)磁盤或 Serial Advanced Technology Attachment(SATA)
磁盤。但是,當通過調用 read 函數讀取一個文件時,數據會正常返回。本文講解這個機制的實現方法並介紹 Linux
文件系統層的主要結構。


什麼是文件系統?

首先回答最常見的問題,“什麼是文件系統”。文件系統是對一個存儲設備上的數據和元數據進行組織的機制。由
於定義如此寬泛,支持它的代碼會很有意思。正如前面提到的,有許多種文件系統和媒體。由於存在這麼多類型,
可以預料到 Linux 文件系統接口實現為分層的體系結構,從而將用戶接口層、文件系統實現和操作存儲設備的驅動
程序分隔開。


文件系統作為協議

另一種看待文件系統的方式是把它看作一個協議。網絡協議(比如 IP)規定了互聯網上傳輸的數據流的意義,同樣,
文件系統會給出特定存儲媒體上數據的意義。


掛裝

在 Linux 中將一個文件系統與一個存儲設備關聯起來的過程稱為掛裝(mount)。使用 mount 命令將一個文件系統
附著到當前文件系統層次結構中(根)。在執行掛裝時,要提供文件系統類型、文件系統和一個掛裝點。
為了說明 Linux 文件系統層的功能(以及掛裝的方法),我們在當前文件系統的一個文件中創建一個文件系統。實
現的方法是,首先用 dd 命令創建一個指定大小的文件(使用 /dev/zero 作為源進行文件復制)—— 換句話說,
一個用零進行初始化的文件,見清單 1。
清單 1. 創建一個經過初始化的文件
$ dd if=/dev/zero of=file.img bs=1k count=10000
10000+0 records in
10000+0 records out
$
現在有了一個 10MB 的 file.img 文件。使用 losetup 命令將一個循環設備與這個文件關聯起來,讓它看起來像一
個塊設備,而不是文件系統中的常規文件:
$ losetup /dev/loop0 file.img
$
這個文件現在作為一個塊設備出現(由 /dev/loop0 表示)。然後用 mke2fs 在這個設備上創建一個文件系統。這
個命令創建一個指定大小的新的 ext2 文件系統,見清單 2。
清單 2. 用循環設備創建 ext2 文件系統
$ mke2fs -c /dev/loop0 10000
mke2fs 1.35 (28-Feb-2004)
max_blocks 1024000, rsv_groups = 1250, rsv_gdb = 39
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
2512 inodes, 10000 blocks
500 blocks (5.00%) reserved for the super user
...
$
使用 mount 命令將循環設備(/dev/loop0)所表示的 file.img 文件掛裝到掛裝點 /mnt/point1。注意,文件系統
類型指定為 ext2。掛裝之後,就可以將這個掛裝點當作一個新的文件系統,比如使用 ls 命令,見清單 3。
清單 3. 創建掛裝點並通過循環設備掛裝文件系統
$ mkdir /mnt/point1
$ mount -t ext2 /dev/loop0 /mnt/point1
$ ls /mnt/point1
lost+found
$
如清單 4 所示,還可以繼續這個過程:在剛才掛裝的文件系統中創建一個新文件,將它與一個循環設備關聯起來,
再在上面創建另一個文件系統。
清單 4. 在循環文件系統中創建一個新的循環文件系統
$ dd if=/dev/zero of=/mnt/point1/file.img bs=1k count=1000
1000+0 records in
1000+0 records out
$ losetup /dev/loop1 /mnt/point1/file.img
$ mke2fs -c /dev/loop1 1000
mke2fs 1.35 (28-Feb-2004)
max_blocks 1024000, rsv_groups = 125, rsv_gdb = 3
Filesystem label=
...
$ mkdir /mnt/point2
$ mount -t ext2 /dev/loop1 /mnt/point2
$ ls /mnt/point2
lost+found
$ ls /mnt/point1
file.img lost+found
$
通過這個簡單的演示很容易體會到 Linux 文件系統(和循環設備)是多麼強大。可以按照相同的方法在文件上用循
環設備創建加密的文件系統。可以在需要時使用循環設備臨時掛裝文件,這有助於保護數據。


文件系統體系結構

既然已經看到了文件系統的構造方法,現在就看看 Linux 文件系統層的體系結構。本文從兩個角度考察 Linux 文
件系統。首先采用高層體系結構的角度。然後進行深層次討論,介紹實現文件系統層的主要結構。


高層體系結構

盡管大多數文件系統代碼在內核中(後面討論的用戶空間文件系統除外),但是圖 1 所示的體系結構顯示了用戶空
間和內核中與文件系統相關的主要組件之間的關系。


圖 1. Linux 文件系統組件的體系結構

用戶空間包含一些應用程序(例如,文件系統的使用者)和 GNU C 庫(glibc),它們為文件系統調用(打開、讀
取、寫和關閉)提供用戶接口。系統調用接口的作用就像是交換器,它將系統調用從用戶空間發送到內核空間中的
適當端點。
VFS 是底層文件系統的主要接口。這個組件導出一組接口,然後將它們抽象到各個文件系統,各個文件系統的行為
可能差異很大。有兩個針對文件系統對象的緩存(inode 和 dentry)。它們緩存最近使用過的文件系統對象。
每個文件系統實現(比如 ext2、JFS 等等)導出一組通用接口,供 VFS 使用。緩沖區緩存會緩存文件系統和相關
塊設備之間的請求。例如,對底層設備驅動程序的讀寫請求會通過緩沖區緩存來傳遞。這就允許在其中緩存請求,
減少訪問物理設備的次數,加快訪問速度。以最近使用(LRU)列表的形式管理緩沖區緩存。注意,可以使用 sync 命
令將緩沖區緩存中的請求發送到存儲媒體(迫使所有未寫的數據發送到設備驅動程序,進而發送到存儲設備)。


什麼是塊設備?

塊設備就是以塊(比如磁盤扇區)為單位收發數據的設備,它們支持緩沖和隨機訪問(不必順序讀取塊,而是可以
在任何時候訪問任何塊)等特性。塊設備包括硬盤、CD-ROM 和 RAM 盤。與塊設備相對的是字符設備,字符設備沒
有可以進行物理尋址的媒體。字符設備包括串行端口和磁帶設備,只能逐字符地讀取這些設備中的數據。
這就是 VFS 和文件系統組件的高層情況。現在,討論實現這個子系統的主要結構。

Copyright © Linux教程網 All Rights Reserved