1 引言

Linux 中允許眾多不同的檔案系統共存,如 ext2, ext3, vfat 等。通過使用同一套檔案 I/O 系統呼叫即可對 Linux 中的任意檔案進行操作而無需考慮其所在的具體檔案系統格式;更進一步,對檔案的操作可以跨檔案系統而執行。如圖 1 所示,我們可以使用 cp 命令從 vfat 檔案系統格式的硬碟拷貝資料到 ext3 檔案系統格式的硬碟;而這樣的操作涉及到兩個不同的檔案系統。


圖 1. 跨檔案系統的檔案操作
圖片示例_跨檔案系統的檔案操作

“一切皆是檔案”是 Unix/Linux 的基本哲學之一。不僅普通的檔案,目錄、字元裝置、塊裝置、套接字等在 Unix/Linux 中都是以檔案被對待;它們雖然型別不同,但是對其提供的卻是同一套操作介面。


圖 2. 一切皆是檔案
圖片示例_一切皆是檔案

而虛擬檔案系統正是實現上述兩點 Linux 特性的關鍵所在。虛擬檔案系統(Virtual File System, 簡稱 VFS),是 Linux 核心中的一個軟體層,用於給使用者空間的程式提供檔案系統介面;同時,它也提供了核心中的一個抽象功能,允許不同的檔案系統共存。系統中所有的檔案系統不但依賴 VFS 共存,而且也依靠 VFS 協同工作。

為了能夠支援各種實際檔案系統,VFS 定義了所有檔案系統都支援的基本的、概念上的介面和資料結構;同時實際檔案系統也提供 VFS 所期望的抽象介面和資料結構,將自身的諸如檔案、目錄等概念在形式上與VFS的定義保持一致。換句話說,一個實際的檔案系統想要被 Linux 支援,就必須提供一個符合VFS標準的介面,才能與 VFS 協同工作。實際檔案系統在統一的介面和資料結構下隱藏了具體的實現細節,所以在VFS 層和核心的其他部分看來,所有檔案系統都是相同的。圖3顯示了VFS在核心中與實際的檔案系統的協同關係。


圖3. VFS在核心中與其他的核心模組的協同關係
圖片示例_VFS在核心中與其他的核心模組的協同關係

VFS即虛擬檔案系統是Linux檔案系統中的一個抽象軟體層;因為它的支援,眾多不同的實際檔案系統才能在Linux中共存,跨檔案系統操作才能實現。VFS藉助它四個主要的資料結構即超級塊、索引節點、目錄項和檔案物件以及一些輔助的資料結構,向Linux中不管是普通的檔案還是目錄、裝置、套接字等都提供同樣的操作介面,如開啟、讀寫、關閉等。只有當把控制權傳給實際的檔案系統時,實際的檔案系統才會做出區分,對不同的檔案型別執行不同的操作。由此可見,正是有了VFS的存在,跨檔案系統操作才能執行,Unix/Linux中的“一切皆是檔案”的口號才能夠得以實現。

從本質上講,檔案系統是特殊的資料分層儲存結構,它包含檔案、目錄和相關的控制資訊。為了描述 這個結構,Linux引入了一些基本概念:

檔案 一組在邏輯上具有完整意義的資訊項的系列。在Linux中,除了普通檔案,其他諸如目錄、裝置、套接字等 也以檔案被對待。總之,“一切皆檔案”。

目錄 目錄好比一個資料夾,用來容納相關檔案。因為目錄可以包含子目錄,所以目錄是可以層層巢狀,形成 檔案路徑。在Linux中,目錄也是以一種特殊檔案被對待的,所以用於檔案的操作同樣也可以用在目錄上。

目錄項 在一個檔案路徑中,路徑中的每一部分都被稱為目錄項;如路徑/home/source/helloworld.c中,目錄 /, home, source和檔案 helloworld.c都是一個目錄項。

索引節點 用於儲存檔案的元資料的一個數據結構。檔案的元資料,也就是檔案的相關資訊,和檔案本身是兩個不同 的概念。它包含的是諸如檔案的大小、擁有者、建立時間、磁碟位置等和檔案相關的資訊。

超級塊 用於儲存檔案系統的控制資訊的資料結構。描述檔案系統的狀態、檔案系統型別、大小、區塊數、索引節 點數等,存放於磁碟的特定扇區中。

關於檔案系統的三個易混淆的概念:

建立 以某種方式格式化磁碟的過程就是在其之上建立一個檔案系統的過程。建立文現系統時,會在磁碟的特定位置寫入 關於該檔案系統的控制資訊。

註冊 向核心報到,宣告自己能被核心支援。一般在編譯核心的時侯註冊;也可以載入模組的方式手動註冊。註冊過程實 際上是將表示各實際檔案系統的資料結構struct file_system_type 例項化。

安裝 也就是我們熟悉的mount操作,將檔案系統加入到Linux的根檔案系統的目錄樹結構上;這樣檔案系統才能被訪問。

VFS依靠四個主要的資料結構和一些輔助的資料結構來描述其結構資訊,這些資料結構表現得就像是物件; 每個主要物件中都包含由操作函式表構成的操作物件,這些操作物件描述了核心針對這幾個主要的物件可以進行的操作。

.