Linux核心中的虛拟檔案系統用來管理挂接各種具體檔案系統。具體的檔案系統可設計成可加載子產品,在系統需要時進行加載。
挂載具體檔案系統時,VFS讀取它的超級塊,得到具體檔案系統的拓撲結構,并将這些資訊映射到VFS超級塊結構中。
當程序或shell指令通路目錄和檔案時,shell指令及應用程式分解成系統調用,系統調用進入核心空間,周遊虛拟檔案系統的VFS節點(inode),而VFS節點指向了具體檔案系統的節點。通過底層塊I/O函數調用IDE接口,再通過塊驅動程式通路塊裝置(如硬碟),得到檔案資料。檔案系統的運作流程如圖所示。
Linux的目錄和檔案實際上都是一種檔案,目錄應稱為目錄檔案,一個目錄檔案就是一個目錄項的清單,其中的每一個目錄項都有一個資料結構來描述。每個目錄的頭兩項總是标準目錄項“.”和“..”,分别指向目錄、父目錄的inode。
VFS超級塊是在這些檔案系統中描整個檔案系統資訊的全局資料結構。VFS超級塊是各種邏輯檔案系統在安裝時建立,并在這些檔案系統解除安裝時自動删除。可見,VFS超級塊确實隻存在于記憶體中。
超級塊結構super_block列出如下:
為保持從目錄通路inode的高效率,Linux維護了表達路徑與inode對應的關系的dentry結構。dentry結構描述了路徑資訊并連結到結點inode。每個檔案有一個dentry結構,被檔案系統使用過的目錄将會存入dentry結構中。這樣,同一目錄被再次通路時,可直接從dentry中得到,不必重複通路存儲檔案系統的裝置。
dentry結構列出如下:
VFS中的每個檔案、目錄檔案等都有惟一的VFS inode表示。每個VFS inode中的資訊通過檔案系統從實際檔案系統中得到。
結構inode列出如下:
程序是通過檔案描述符而不是檔案名來通路檔案的,檔案描述符實際上是一個整數,規定每個程序最多能同時使用NR_OPEN個檔案描述符,這個值在fs.h中定義為256.每個程序用一個file_struct的結構來記錄檔案描述符的使用情況,它是程序的私有資料。
每個檔案都有一個32位的整數來表示下一個讀寫的位元組位置,即檔案位置。每次打開一個檔案,預設是從檔案的開始處操作,可以通過系統調用lseek對這個檔案位置進行修改。
在程序的task_struct中的檔案系統相關的資料成員,列出如下:
結構fs_struct給出了檔案系統資訊,列出如下:
結構files_struct是使用者打開檔案描述符表,它給出了檔案描述符的使用情況,其file結構成員給出了每個檔案描述符的資訊,結構files_struct分析如下:
結構files_struct中成員fd_array主要是一個256項的file結構數組,數組的下标是檔案描述符,而其内容就是對應的file結構。在一個程序啟動後,檔案描述符0,1,2,已經被配置設定并可供使用:0表示标準輸入裝置,1表示标準輸出裝置,2表示标準錯誤輸出裝置。是以,能使用的第一個檔案描述符是3.
結構file儲存打開檔案的資訊,通過檔案描述符查找檔案描述符數組fd_arrayfile可得到file結構。結構file分析如下:
VFS畢竟是虛拟的,它無法 設計具體檔案系統的細節,是以,必須在VFS和具體結構檔案系統之間有一些接口。VFS的資料結構就好像是一個标準,具體檔案系統要想被Linux支援,就必須提供VFS标準應具有的結構及操作函數。實際上,具體檔案系統在使用前,必須将自己的結構及操作函數映射到VFS中,這樣才能被通路到。
結構super_operations是對檔案系統超級塊進行操作的函數集。這個結構分析如下:
結構inode_operations定義了節點的操作函數集,分析如下:
結構file_operations中存有對檔案進行操作的函數,這個結構分析如下:
Linux能支援多種檔案系統并且保持很高的性能,這是因為檔案系統有各種各種的緩存,組織成了各種hash表,有效地提高了通路速度。檔案系統使用的各種緩存如下:
為加速對實體裝置的通路,Linux維護一組緩沖區,用做對塊裝置上的資料的塊緩存。需要使用塊裝置上的資料時,系統把資料塊調入塊緩存中。下次再通路該資料塊時,不必通路實體裝置了。常用的資料塊會一直留在塊緩存中,這樣減少了通路裝置的時間。
Linux以struct buffer_head規定的資料格式封裝緩存。buffer_head結構對塊緩存進行管理,多個塊緩存組成了塊緩存頁,每頁中的塊緩存buffer_head結構形成了一個環形連結清單,頁的私有資料指針指向這個環形連結清單的頭部。
結構buffer_head包含了用于描述緩沖區内容的資訊,例如,所在裝置号,起始實體塊号,包含在緩沖區的位元組數,還包含了緩沖區狀态,例如,是否有用資料,是否正在使用,重新利用之前是否要寫回磁盤等。
結構buffer_head分析如下:
塊緩存獨立于任何類型的檔案系統。檔案系統中凡涉及磁盤讀寫,幾乎都要通過塊緩存;有些甚至直接利用緩沖區緩存儲存資訊。
每個塊緩存由兩部分組成:第一部分稱為塊緩存首部,用資料結構buffer_head表示;第二部分是塊緩存資料區,結構buffer_head與塊緩存資料分别存儲,結構buffer_head用b_page來指明資料區所在的頁,b_size表示資料的大小。