Linux 檔案系統剖析
在檔案系統方面,Linux® 可以算得上作業系統中的 “瑞士軍刀”。Linux 支援許多種檔案系統,從日誌型檔案系統到叢集檔案系統和加密檔案系統。對於使用標準的和比較奇特的檔案系統以及開發檔案系統來說,Linux 是極好的平臺。本文討論 Linux 核心中的虛擬檔案系統(VFS,有時候稱為虛擬檔案系統交換器),然後介紹將檔案系統連線在一起的主要結構。[@more@]
Linux 檔案系統體系結構是一個對複雜系統進行抽象化的有趣例子。通過使用一組通用的 API 函式,Linux 可以在許多種儲存裝置上支援許多種檔案系統。例如,read
函式呼叫可以從指定的檔案描述符讀取一定數量的位元組。read
函式不瞭解檔案系統的型別,比如 ext3 或 NFS。它也不瞭解檔案系統所在的儲存媒體,比如 AT Attachment Packet Interface(ATAPI)磁碟、Serial-Attached SCSI(SAS)磁碟或 Serial Advanced Technology Attachment(SATA)磁碟。但是,當通過呼叫 read
函式讀取一個檔案時,資料會正常返回。本文講解這個機制的實現方法並介紹 Linux 檔案系統層的主要結構。
|
首先回答最常見的問題,“什麼是檔案系統”。檔案系統是對一個儲存裝置上的資料和後設資料進行組織的機制。由於定義如此寬泛,支援它的程式碼會很有意思。正如前面提到的,有許多種檔案系統和媒體。由於存在這麼多型別,可以預料到 Linux 檔案系統介面實現為分層的體系結構,從而將使用者介面層、檔案系統實現和操作儲存裝置的驅動程式分隔開。
|
在 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
命令將緩衝區快取中的請求傳送到儲存媒體(迫使所有未寫的資料傳送到裝置驅動程式,進而傳送到儲存裝置)。
|
這就是 VFS 和檔案系統元件的高層情況。現在,討論實現這個子系統的主要結構。
Linux 以一組通用物件的角度看待所有檔案系統。這些物件是超級塊(superblock)、inode、dentry 和檔案。超級塊在每個檔案系統的根上,超級塊描述和維護檔案系統的狀態。檔案系統中管理的每個物件(檔案或目錄)在 Linux 中表示為一個 inode。inode 包含管理檔案系統中的物件所需的所有後設資料(包括可以在物件上執行的操作)。另一組結構稱為 dentry,它們用來實現名稱和 inode 之間的對映,有一個目錄快取用來儲存最近使用的 dentry。dentry 還維護目錄和檔案之間的關係,從而支援在檔案系統中移動。最後,VFS 檔案表示一個開啟的檔案(儲存開啟的檔案的狀態,比如寫偏移量等等)。
VFS 作為檔案系統介面的根層。VFS 記錄當前支援的檔案系統以及當前掛裝的檔案系統。
可以使用一組註冊函式在 Linux 中動態地新增或刪除檔案系統。核心儲存當前支援的檔案系統的列表,可以通過 /proc 檔案系統在使用者空間中檢視這個列表。這個虛擬檔案還顯示當前與這些檔案系統相關聯的裝置。在 Linux 中新增新檔案系統的方法是呼叫 register_filesystem
。這個函式的引數定義一個檔案系統結構(file_system_type
)的引用,這個結構定義檔案系統的名稱、一組屬性和兩個超級塊函式。也可以登出檔案系統。
在註冊新的檔案系統時,會把這個檔案系統和它的相關資訊新增到 file_systems 列表中(見圖 2 和 linux/include/linux/mount.h)。這個列表定義可以支援的檔案系統。在命令列上輸入 cat /proc/filesystems
,就可以檢視這個列表。
圖 2. 向核心註冊的檔案系統
VFS 中維護的另一個結構是掛裝的檔案系統(見圖 3)。這個結構提供當前掛裝的檔案系統(見 linux/include/linux/fs.h)。它連結下面討論的超級塊結構。
圖 3. 掛裝的檔案系統列表
超級塊結構表示一個檔案系統。它包含管理檔案系統所需的資訊,包括檔案系統名稱(比如 ext2)、檔案系統的大小和狀態、塊裝置的引用和後設資料資訊(比如空閒列表等等)。超級塊通常儲存在儲存媒體上,但是如果超級塊不存在,也可以實時建立它。可以在 ./linux/include/linux/fs.h 中找到超級塊結構(見圖 4)。
圖 4. 超級塊結構和 inode 操作
超級塊中的一個重要元素是超級塊操作的定義。這個結構定義一組用來管理這個檔案系統中的 inode 的函式。例如,可以用 alloc_inode
分配 inode,用 destroy_inode
刪除 inode。可以用 read_inode
和 write_inode
讀寫 inode,用 sync_fs
執行檔案系統同步。可以在 ./linux/include/linux/fs.h 中找到 super_operations
結構。每個檔案系統提供自己的 inode 方法,這些方法實現操作並向 VFS 層提供通用的抽象。
inode 表示檔案系統中的一個物件,它具有惟一識別符號。各個檔案系統提供將檔名對映為惟一 inode 識別符號和 inode 引用的方法。圖 5 顯示 inode 結構的一部分以及兩個相關結構。請特別注意 inode_operations
和 file_operations
。這些結構表示可以在這個 inode 上執行的操作。inode_operations
定義直接在 inode 上執行的操作,而 file_operations
定義與檔案和目錄相關的方法(標準系統呼叫)。
圖 5. inode 結構和相關聯的操作
inode 和目錄快取分別儲存最近使用的 inode 和 dentry。注意,對於 inode 快取中的每個 inode,在目錄快取中都有一個對應的 dentry。可以在 ./linux/include/linux/fs.h 中找到 inode
和 dentry
結構。
除了各個檔案系統實現(可以在 ./linux/fs 中找到)之外,檔案系統層的底部是緩衝區快取。這個元件跟蹤來自檔案系統實現和物理裝置(通過裝置驅動程式)的讀寫請求。為了提高效率,Linux 對請求進行快取,避免將所有請求傳送到物理裝置。快取中快取最近使用的緩衝區(頁面),這些緩衝區可以快速提供給各個檔案系統。
|
本文沒有討論 Linux 中可用的具體檔案系統,但是值得在這裡稍微提一下。Linux 支援許多種檔案系統,包括 MINIX、MS-DOS 和 ext2 等老式檔案系統。Linux 還支援 ext3、JFS 和 ReiserFS 等新的日誌型檔案系統。另外,Linux 支援加密檔案系統(比如 CFS)和虛擬檔案系統(比如 /proc)。
最後一種值得注意的檔案系統是 Filesystem in Userspace(FUSE)。這種檔案系統可以將檔案系統請求通過 VFS 傳送回使用者空間。所以,如果您有興趣建立自己的檔案系統,那麼通過使用 FUSE 進行開發是一種不錯的方法。
|
|
儘管檔案系統的實現並不複雜,但它是可伸縮和可擴充套件的體系結構的好例子。檔案系統體系結構已經發展了許多年,併成功地支援了許多不同型別的檔案系統和許多目標儲存裝置型別。由於使用了基於外掛的體系結構和多層的函式間接性,Linux 檔案系統在近期的發展很值得關注。
學習
- 您可以參閱本文在 developerWorks 全球站點上的 英文原文。
- proc 檔案系統提供了一種通過虛擬檔案系統在使用者空間和核心之間進行通訊的新方式。“使用 /proc 檔案系統來訪問 Linux 核心的內容”(developerWorks,2006 年 3 月)介紹了 /proc 虛擬檔案系統並演示它的使用方法。
- Linux 系統呼叫介面可以在使用者空間和核心之間傳遞控制,從而呼叫核心 API 函式。“使用 Linux 系統呼叫的核心命令”(developerWorks,2007 年)介紹了 Linux 系統呼叫介面。
- Yolinux.com 維護 Linux 檔案系統、叢集檔案系統和效能計算叢集的列表。還可以在 File systems HOWTO 中找到 Linux 檔案系統的完整列表。Xenotime 也描述了許多檔案系統。
- 關於 Linux 使用者空間程式設計的更多資訊,請參考本文作者所著的 GNU/Linux Application Programming 。
- 在 developerWorks Linux 專區 中可以找到為 Linux 開發人員準備的更多參考資料,還可以查閱 最流行的文章和教程。
- 查閱 developerWorks 上的所有 Linux 技巧 和 Linux 教程。
- 隨時關注 developerWorks 技術活動和網路廣播。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10130206/viewspace-1037581/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux系統篇-檔案系統&虛擬檔案系統Linux
- Linux檔案系統Linux
- linux 檔案系統Linux
- Linux系統檔案系統及檔案基礎篇Linux
- 分散式檔案系統(HDFS)與 linux系統檔案系統 對比分散式Linux
- Linux AUFS 檔案系統Linux
- linux的檔案系統Linux
- 論Linux檔案系統Linux
- linux檔案系統概述Linux
- Linux(五)——檔案系統Linux
- 【Linux】XFS檔案系統Linux
- Linux檔案系統 (轉)Linux
- Linux 檔案系統-ext3 檔案系統介紹(轉)Linux
- 細說GNU/Linux系統的檔案及檔案系統(轉)Linux
- 『學了就忘』Linux檔案系統管理 — 57、Linux檔案系統介紹Linux
- Linux檔案系統-目錄和檔案管理Linux
- Linux檔案系統詳解Linux
- Linux檔案系統、目錄Linux
- linux之路(五)檔案系統Linux
- 【Linux】檔案系統目錄Linux
- Linux 檔案系統詳解Linux
- linux檔案系統簡析Linux
- Linux檔案系統簡介Linux
- linux檔案系統概論Linux
- linux磁碟和檔案系統Linux
- linux檔案系統基礎Linux
- 導覽Linux系統檔案系統型別Linux型別
- Linux系統程式設計【4】——檔案系統Linux程式設計
- linux系統檢視分割槽檔案系統Linux
- Linux 建立檔案系統及掛載檔案系統詳解一薦Linux
- 【Linux】Linux檔案系統管理6 線上擴充套件、收縮lvm檔案系統Linux套件LVM
- Linux檔案系統的實現Linux
- Linux EXT2 檔案系統Linux
- Linux 檔案系統基本介紹Linux
- Linux 檢視系統檔案命令Linux
- Linux雜記-根檔案系統Linux
- Linux系統網路檔案配置Linux
- 二、Linux檔案系統結構Linux