VFS與Ext2文件系統------《深入Linux內核架構》筆記

1. VFS簡介(Virtual File System, 虛擬文件系統)

在Linux內核中支持40多種文件系統,其來源也多種多樣:來自MS-DOSFAT文件系統, UFS(Berkeley UNIX), Ext2/3/4, 用於CD-ROMiso9660, 網絡文件系統(codaNFS)和虛擬的文件系統(proc)

Linux爲了向用戶空間(C標準庫)提供標準的接口,將所有的文件系統,抽象爲統一的文件系統接口----VFS。圖1-1 Linux文件系統的結構。


1-1 Linux文件系統的結構

Linux,文件系統主要分爲下面3種:

(1)基於磁盤的文件系統(Disk-based Filesystem) 是在非易失介質上存儲文件的經典方法,用以在多次會話之間保持文件的內容。如Ext2/3/4 Reiserfs, FAT等。

(2)虛擬文件系統(Virtual Filesystem) 在內核中生成,是一種用戶應用程序與內核通信的方法。如proc,它不許要在任何類的硬件設備上分配存儲空間,所有的信息都是動態在內存中開闢和存儲。

(3)網絡文件系統(Network Filesystem) 是基於磁盤的文件系統和虛擬文件系統之間的折中。這種文件系統允許訪問另一臺計算機上的數據,該計算機通過網絡連接到本地計算機。在這種情況下,數據實際上存儲在一個不同系統的硬件設備上。

由於VFS抽象層的存在,用戶空間進程不會看到本地文件系統與網絡文件系統之間的區別。

2. VFS的模型與結構

VFS不僅爲文件系統提供了方法和抽象,還支持文件系統中對象(或文件)的統一視圖。並非每一種文件系統都支持VFS中的所有抽象,如FAT,因爲其設計沒有考慮到此類對象。定義一個最小的通用模型,來支持內核中所有文件系統都實現的那些功能,這是不實際的。因爲這樣會損失許多本質性的功能特性,或者導致這些特性只能通過特定文件系統的路徑訪問。

VFS的方案完全相反:提供一種結構模型,包含了一個強大文件系統所具備的所有組件。但該模型只存在於虛擬中,必須使用各種對象和函數指針與每種文件系統適配。所有文件系統的實現都必須提供與VFS定義的結構配合的例程,以彌合兩種視圖之間的差異。

VFS是由基於經典文件系統的結構衍化而來,所以VFSExt類文件系統類似,從而在處理Ext類文件系統的時候,ExtVFS之間的轉換,幾乎不會損失時間。圖1-2 底層爲Ext2VFS結構


圖 1-2 底層爲Ext2VFS結構

圖1-2中綠色方框的部分爲Ext2實現的部分,而Ext2中用戶表示目錄的結構爲ext2_dir_entry_2

  1. struct ext2_dir_entry_2 {  
  2.     __le32  inode;      /* Inode number */  
  3.     __le16  rec_len;        /* Directory entry length */  
  4.     __u8    name_len;   /* Name length */  
  5.     __u8    file_type;  
  6.     char    name[EXT2_NAME_LEN];    /* File name */  
  7. };  

其保存在inode->imapping所指向的空間中。對於dentry_operations,Ext2無須實現本地化,因爲採用默認的dentry_operations已能完成所需工作。例,對於FAT,由於在比較兩個文件名是否相等時,需要忽略大小寫,則必須實現本地化,參見msdos_dentry_operations。圖1-2中所涉及的結構體請參考書中的第89Linux內核源代碼

以下以查詢一個目錄爲例(path_lookup函數),進行簡要說明。其中底層文件系統爲Ext2

1. 首先,內核使用nameidata實例規定查找起點,如果名稱以/開始,則使用當前根目錄的dentryvfsmount實例;否則,從當前進程的task_struct獲得當前的工作目錄。

2. 檢查當前路徑分量對應的cur_inode的權限,計算路徑中next_dir的散列值,。

3. 處理...,該任務委託給follow_dotdot函數。

4. 根據2中的散列值和cur_inode的dentry,通過d_hash函數計算出next_dir的dentrydentry緩存中可能存在其的鏈表,遍歷鏈表,如果存在,跳至i,如果不存在需要調用real_lookup通過cur_inode查找。

5. real_lookup函數通過dentry->i_op->lookup調用ext2_lookup函數實現對cur_inode->i_mapping內存空間的遍歷,來查找目錄是否存在於該cur_inode中。如果存在,新建next_dir的dentry項,並存入dentry緩存,跳至i;不存在,返回錯誤。

i. next_dir的inode更新cur_inode,並得到一下個需要查找的目錄,返回2。如果查找完畢,則成功。

注:在通過當前目錄查找某個子目錄是否存在的時候,使用了ext2_lookup函數直接遍歷該目錄的數據域,如果是文本文件會咋樣呢?文本文件在建立的時候對其對應的inodei_op域的初始化爲ext2_file_inode_operations。所以文本文件的inode->i_op->lookup將爲NULL

文中部分內容涉及自己對文件系統的理解,難免有不足之處,請多諒解。

發佈了132 篇原創文章 · 獲贊 38 · 訪問量 42萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章