複製鏈接
請複製以下鏈接發送給好友

虛擬文件系統

鎖定
虛擬文件系統(VFS)是由Sun microsystems公司在定義網絡文件系統(NFS)時創造的。它是一種用於網絡環境的分佈式文件系統,是允許和操作系統使用不同的文件系統實現的接口。虛擬文件系統(VFS)是物理文件系統與服務之間的一個接口層,它對Linux的每個文件系統的所有細節進行抽象,使得不同的文件系統在Linux核心以及系統中運行的其他進程看來,都是相同的。嚴格説來,VFS並不是一種實際的文件系統。它只存在於內存中,不存在於任何外存空間。VFS在系統啓動時建立,在系統關閉時消亡。
中文名
虛擬文件系統
外文名
Virtual File Systems
領    域
計算機操作系統

虛擬文件系統簡介

虛擬文件系統 Virtual File Systems(VFS)
Linux 是近年來發展起來的一種新型的操作系統,其最重要的特徵之一就是支持多種文件系統,使其更加靈活,從而與許多其它的操作系統共存。Linux支持ext,ext2,xia,minix,umsdos,msdes,fat32 ,ntfs,proc,stub,ncp,hpfs,affs 以及 ufs 等多種文件系統。為了實現這一目的,Linux 對所有的文件系統採用統一的文件界面,用户通過文件的操作界面來實現對不同文件系統的操作。對於用户來説,我們不要去關心不同文件系統的具體操作過程,而只是對一個虛擬的文件操作界面來進行操作,這個操作界面就是 Linux 的虛擬文件系統(VFS ) 。形象地説,Linux 的內核好象一個 PC 機的母板,VFS 就是上面的一個插槽,具體的文件系統就是一塊塊的接 121 卡。因此,每一個文件系統之間互不干擾,而只是調用相應的程序來實現其功能。在 Linux 的內核文件中,VFS 和具體的文件系統程序都放在 Linux\FS 中,其中每一種文件系統對應一個子目錄,另外還有一些共用的 VFS 程序。在具體的實現上,每個文件系統都有自己的文件操作數據結構file—operations。所以,VFS 作為 ILinux內核中的一個軟件層,用於給用户空間的程序提供文件系統接口,同時也提供了內核中的一個抽象功能,允許不同的文件系統很好地共存。VFS 使 Linux 同時安裝、支持許多不同類型的文件系統成為可能。VFS 擁有關於各種特殊文件系統的公共界面,如超級塊、inode、文件操作函數入口等。實際文件系統的細節,統一由 VFS 的公共界面來索引,它們對系統核心和用户進程來説是透明的。

虛擬文件系統Linux虛擬文件系統簡介

虛擬文件系統虛擬

"虛擬"二字主要有兩層含義: [1] 
1, 在同一個目錄結構中, 可以掛載着若干種不同的文件系統. VFS隱藏了它們的實現細節, 為使用者提供統一的接口; [1] 
2, 目錄結構本身並不是絕對的, 每個進程可能會看到不一樣的目錄結構. 目錄結構是由"地址空間(namespace)"來描述的, 不同的進程可能擁有不同的namespace, 不同的namespace可能有着不同的目錄結構(因為它們可能掛載了不同的文件系統)。 [1] 

虛擬文件系統Inode

含義: 索引節點, 對應設備上存放的一個文件。 [1] 
創建: 1)在超級塊被載入時, 作為根的inode一併被載入; 2)通過mknod調用創新新的索引節點; 3)在尋找文件路徑的過程中, 從設備中讀取, 並初始化(跟super_block一樣, inode結構中一部分信息是保存在設備中的, 一部分則是在內在中初始化的)。 [1] 
函數: i_op, 索引節點函數集, 主要包含對子inode的創建, 刪除等操作. f_op, 文件函數集, 主要包含對本inode的讀寫等操作. 在inode被創建後, 1)如果是特殊文件, 則根據對應文件的類型(包括塊設備, 字符設備, fifo, 等等)賦予特定的函數集(並不直接與設備和文件系統類型相關); 2)否則, 對應的文件系統類型會提供相應的函數集, 並且目錄和文件函數集很可能不同。 [1] 

虛擬文件系統操作已打開的文件

VFS的使用者是進程(用户訪問文件系統總是需要啓動進程). 描述進程的task_struct結構中files指針指向了一個files_struct結構, 後者描述了進程已打開的文件集合。 [1] 
files_struct結構維護了一個已打開文件所對應的file結構的指針數組, 數組下標被用作用户程序操作已打開文件的句柄(通常稱作fd). files_struct還維護着已使用的fd位圖, 以便在需要打開文件時, 為其分配一個未使用的fd。 [1] 
詳細見參考文獻。

虛擬文件系統功能

VFS的功能包括:紀錄可用的文件系統的類型;將設備同對應的文件系統聯繫起來;處理一些面向文件的通用操作;涉及到針對文件系統的操作時,VFS把它們影射到與控制文件、目錄以及inode相關的物理文件系統。
當某個進程發佈了一個面向文件的系統調用時,核心將調用VFS中相應的函數,這個函數處理一些與物理結構無關的操作,並且把它重定向為真實文件系統中相應的函數調用,後者則用來處理那些與物理結構相關的操作。
VFS與實際文件系統的封裝關係如下圖所示:
VFS
MINIX FS
VFSinode緩存
VFS目錄緩存
EXT FS
EXT2 FS
MSDS FS
緩衝存儲
圖4 VFS與實際文件系統的封裝關係
VFS的源代碼集中在/usr/src/linux/fs目錄下,關於它的數據結構的描述在文件/usr/src/lunux/include/linux/fs.h中。

虛擬文件系統超級塊

VFS使用了與EXT2文件系統類似的方式:超級塊和索引節點inode描述文件系統。
VFS超級塊是各種邏輯文件系統在安裝時建立的,並在這些文件系統卸載時自動刪除,它只存在於內存中。VFS中保存了系統中掛接的文件系統的鏈表以及這些文件系統對應的VFS超級塊。系統啓動後所有被初始化的文件系統都要向VFS登記。每個已安裝的文件系統由一個VFS 超塊表示,它包含如下信息:
⑴Device:表示文件系統所在塊設備的設備標誌符。例如系統中第一個IDE 硬盤的設備標誌符為0x301。
⑵Inode pointers:這個mounted inode指針指向文件系統中第一個inode。而covered inode指針指向此文件系統安裝目錄的inode。根文件系統的VFS超塊不包含covered指針
⑶Blocksize:以字節記數的文件系統塊大小,如1024 字節。
⑷Superblock operations:指向此文件系統一組超塊操縱例程的指針。這些例程被VFS 用來讀寫inode和超塊。
⑸File System type:這是一個指向已安裝文件系統的file_system_type結構的指針
⑹File System specific:指向文件系統所需信息的指針。

虛擬文件系統其它相關

虛擬文件系統The VFS Inode

和EXT2 文件系統相同,VFS 中的每個文件、目錄等都用且只用一個VFS inode表示。每個VFS inode 中的信息通過文件系統相關例程從底層文件系統中得到。VFS inode僅存在於核心內存並且保存只要對系統有用,它們就會被保存在在VFS inode cache中。每個VFS inode包含下列域:
⑴device:包含此文件或此VFS inode 代表的任何東西的設備的設備標誌符。
⑵inode number:文件系統中唯一的inode號。在虛擬文件系統中device和inode號的組合是唯一的。
⑶mode:和EXT2 中的相同, 表示此VFS inode 的存取權限。
⑷user ids:所有者的標誌符。
⑸times:VFS inode 創建、修改和寫入時間。
⑹block size:以字節計算的文件塊大小,如1024 字節。
⑺inode operations:指向一組例程地址的指針。這些例程和文件系統相關且對此inode 執行操作,如截斷此inode表示的文件。
⑻count:使用此VFS inode 的系統部件數。一個count為0 的inode可以被自由的丟棄或重新使用。
⑼lock: 用來對某個VFS inode加鎖,如用於讀取文件系統時。
⑽dirty:表示這個VFS inode是否已經被寫過,如果是則底層文件系統需要更新。

虛擬文件系統註冊文件系統

用户可以通過兩種途徑向內核註冊文件系統:一是在編譯內核時確定可支持的文件系統類型,並在系統初始化時通過內嵌的函數調用在VFS中進行註冊;二是把某個文件系統當作一個模塊,利用模塊的加載和卸載特徵向註冊表登記類型或從註冊表註銷。
文件系統類型的註冊函數為:int register filesystem (struct file_system_type *fs)
每個文件系統都有一個初始化例程,文件系統通過它在VFS中進行註冊,即填寫file_system_type數據結構。該結構包含了文件系統的名稱及一個指向對應VFS超級塊讀取例程的地址。所有已註冊文件系統的file_system_type結構形成了一個註冊鏈表,如下圖所示:
file_system_type file_system_type file_system_type
*read_super()
name
owner
kem_mnt
next
*read_super()
name
owner
kem_mnt
next
*read_super()
name
owner
kem_mnt
next
圖5
file_system_type的數據結構在include/linux/fs.h中定義如下:
struct file_system_type {
const char *name;
//文件系統的類型名,如EXT2。這些名稱出現在Linux中的/proc/filesystems中且必須是唯一的。
int fs_flags;
//fs_flags的取值可能有很多種。例如,文件系統標識FS_REQUIRES_DEV表示文件系統只能加載在一個塊設備上;FS_SINGLE表示文件系統只能有一個超級塊;FS_NOMOUNT表示文件系統不能安裝在用户空間上。
struct super_block *(*read_super) (struct super_block *, void *, int);
//read_super所指的函數用於讀出該文件系統在外存的超級塊。
struct module *owner;
//如果實現該文件系統的程序段是由module動態載入的,則指向該module;如果實現該文件系統的程序段是在內核編譯時生成的,則owner = NULL。
struct vfsmount * kem_mnt;
//只為標識為FS_SINGLE的文件系統使用(For kernel mount)
struct file_system_type * next;
//文件系統類型鏈表的後續指針
};

虛擬文件系統安裝文件系統

文件系統註冊後便在設備上按一定格式建立文件系統,但是此時設備上的文件和節點都還不是可訪問的,還不能按照一定的路徑名訪問其中特定的節點或文件。只有把它安裝到文件系統中某個節點上,才能使設備上的文件和節點可被訪問。因此註冊了wej系統只代表Linux系統支持這種文件系統的應用,要真正使用該文件系統還必須安裝它。
文件系統的安裝必須調用mount命令,把其他子系統安裝到已經存在於文件系統的空閒節點上。該命令使用系統的mount()調用:asmlinkage ling sys_mount(char * dev_name, char * dir_name, char * type, unsigned long flags, void * data)
其中dev_name是要安裝的文件系統的磁盤分區的路徑名,如/dev/hda5。參數dir_name是要安裝的文件系統的目錄名;type指定磁盤分區上的文件系統類型;flags指定該文件系統如何被安裝;data是指向任意的信息結構的指針,其內容依賴於被安裝的特定文件系統類型。
使用mount命令後,VFS通過file_systems在file_system_type鏈表中根據指定的文件系統名稱搜索文件系統類型信息。而函數get_fs_type()根據具體文件系統的類型名在內核中找到相應的file_system_type結構:
struct file_system_type *get_fs_type(const char *name)
{
struct file_system_type *fs;
read_lock(&file_systems_lock);
fs = *(find_filesystem(name));
if (!fs && (request_module(name) == 0)) {
read_lock(&file_systems_lock);
fs = *(find_filesystem(name));
if (fs && !try_inc_mod_count(fs->owner))
fs = NULL;
read_unlock(&file_systems_lock);
}
return fs;
}
其中函數find_filesystem(name)掃描file_system對列,找到所需文件系統類型的數據結構。

虛擬文件系統卸載文件系統

超級用户卸載文件系統使用umount命令。
卸載過程必須檢查文件系統及其超級塊的狀態。如果文件系統正被其他進程使用該文件系統就不能被卸載。如果文件系統的文件或目錄正在使用,則VFS索引節點緩存中可能包含相應的VFS索引節點。檢查代碼在該緩存中,根據文件系統所在的設備標識符查找是否有來自該文件系統的VFS索引節點。如果有且使用計數大於0則説明該文件系統正在使用,不能被刪除。如果文件系統的超級塊為“髒”,即被修改,則應先將它寫回到磁盤上。
文件系統允許在被刪除後,對應的VFS超級塊被釋放,vfsmount數據結構從vfsmntlist鏈表中斷開並被釋放。
參考資料