Linux ? 的最顯著特征是靈活性和擴(kuò)展性,例如它的虛擬文件系統(tǒng)交換器(VFS)。您可以在各種設(shè)備上創(chuàng)建文件系統(tǒng),包括傳統(tǒng)的磁盤(pán)、USB flash 驅(qū)動(dòng)、內(nèi)存以及其他儲(chǔ)存設(shè)備。您還可以在另一個(gè)文件系統(tǒng)環(huán)境中嵌入文件系統(tǒng)。探索導(dǎo)致 VFS 如此強(qiáng)大的因素,并了解 VFS 的主要接口和進(jìn)程。 Linux 文件系統(tǒng)的靈活性和擴(kuò)展性支持直接源于一組抽象接口。這組接口的核心就是虛擬文件系統(tǒng)交換器(VFS)。 VFS 為上層應(yīng)用程序提供一組標(biāo)準(zhǔn)接口,用于對(duì)不同的文件系統(tǒng)執(zhí)行文件 I/O。這組接口在一個(gè)或多個(gè)底層設(shè)備上支持多個(gè)并發(fā)文件系統(tǒng)。另外,這些文件系統(tǒng)可以不是靜態(tài)的,可以根據(jù)儲(chǔ)存設(shè)備而變化。 VF與VFS 您還可以看到 VFS 還被定義為虛擬文件系統(tǒng)(virtual file system),但定義為虛擬文件系統(tǒng)轉(zhuǎn)換器(virtual file system switch)更能說(shuō)明其作用,因?yàn)樘摂M層跨多個(gè)文件系統(tǒng)轉(zhuǎn)換(即多路復(fù)用)請(qǐng)求。/proc 文件系統(tǒng)在這里帶來(lái)很多的混淆,因?yàn)樗ǔR脖环Q為虛擬文件系統(tǒng)。 例如,一個(gè)典型的 Linux 桌面在可用硬盤(pán)上支持 ext3 文件系統(tǒng),并且在可用的 CD-ROM(或者稱為 CD-ROM 文件系統(tǒng) 或 CDFS)上支持 ISO 9660 文件系統(tǒng)。因?yàn)?CD-ROM 是可以插入和移除的,所以 Linux 內(nèi)核必須適應(yīng)這些包含不同內(nèi)容和結(jié)構(gòu)的新文件系統(tǒng)??梢酝ㄟ^(guò)網(wǎng)絡(luò)文件系統(tǒng)(Network File System,NFS)訪問(wèn)遠(yuǎn)程文件系統(tǒng)。在此時(shí),Linux 還可以掛載來(lái)自本地硬盤(pán)的 Windows?/Linux 雙引導(dǎo)系統(tǒng)的 NT File System (NTFS) 分區(qū),并且能夠向其讀寫(xiě)數(shù)據(jù)。 最后,可移除的 USB flash 啟動(dòng)(UFD)是可以熱插拔的,它構(gòu)成另一個(gè)文件系統(tǒng)。概而言之,可以在這些設(shè)備中使用同一組文件 I/O 接口,從而允許底層的文件系統(tǒng)和物理設(shè)備能夠從用戶中抽象出來(lái)(見(jiàn)圖 1)。 圖 1. 在不同文件系統(tǒng)和儲(chǔ)存設(shè)備之間提供統(tǒng)一接口的抽象層
![]() 分層抽象 現(xiàn)在,我們向 Linux VFS 提供的抽象特性添加一些具體的架構(gòu)。圖 2 從 VFS 的角度顯示 Linux 結(jié)構(gòu)的高級(jí)視圖。在 VFS 之上的是標(biāo)準(zhǔn)的內(nèi)核系統(tǒng)調(diào)用接口(SCI)。這個(gè)接口允許用戶空間發(fā)出要求轉(zhuǎn)換到內(nèi)核的調(diào)用(在不同地址空間中)。在這個(gè)域中,調(diào)用 POSIX open 調(diào)用的用戶空間應(yīng)用程序經(jīng)過(guò) GNU C 庫(kù)(glibc)進(jìn)入內(nèi)核和系統(tǒng)調(diào)用去多元化(de-multiplexing)。最后,使用 sys_open 調(diào)用 VFS。 圖 2. VFS 的分層架構(gòu)
![]() 早期的VFS實(shí)現(xiàn) Linux 并不是第一個(gè)包含虛擬層以支持通用文件模型的操作系統(tǒng)。早期的 VFS 實(shí)現(xiàn)包括 Sun 的 VFS(SunOS version 2.0,大約出現(xiàn)在 1985 年),以及 IBM 和 Microsoft? 的 “Installable File System” for IBM OS/2。這些虛擬化文件系統(tǒng)層的方法為 Linux VFS 鋪平了道路。 VFS 提供抽象層,從而將 POSIX API 與特定文件系統(tǒng)如何實(shí)現(xiàn)該行為的細(xì)節(jié)分離開(kāi)來(lái)。這里的關(guān)鍵之處是,不管底層文件系統(tǒng)是 ext3 還是 Btrfs,Open、Read、Write 或 Close API 系統(tǒng)調(diào)用都能正常工作。VFS 提供一個(gè)由底層文件系統(tǒng)(它們必須為各種 POSIX API 函數(shù)實(shí)現(xiàn)行為)繼承的通用文件模型。另一個(gè)在 VFS 范圍之外的深層抽象隱藏了底層物理設(shè)備(可能是磁盤(pán)、磁盤(pán)分區(qū)、網(wǎng)絡(luò)儲(chǔ)存實(shí)體、內(nèi)存或其他能夠儲(chǔ)存信息的媒介 —— 即使是暫時(shí)性的)。 除了從底層文件系統(tǒng)抽象文件操作的細(xì)節(jié)之外,VFS 還將底層塊設(shè)備綁定到可用的文件系統(tǒng)。讓我們看看 VFS 的內(nèi)部結(jié)構(gòu)及其工作原理。 VFS的內(nèi)部結(jié)構(gòu) 在查看 VFS 子系統(tǒng)的總體架構(gòu)之前,我們先看看所使用的主要對(duì)象。這個(gè)小節(jié)探索了超塊(superblock)、索引節(jié)點(diǎn)(或 inode)、目錄條目(或 dentry)和文件對(duì)象。在這里,其他一些組成部分也很重要,比如緩存。不過(guò)我將在后面的總體架構(gòu)中討論它們。 超塊 超塊(superblock)是關(guān)于文件系統(tǒng)的高級(jí)元數(shù)據(jù)的容器。超塊是存在于磁盤(pán)上(實(shí)際上位于磁盤(pán)的多個(gè)位置上,以提供冗余)的結(jié)構(gòu)。它是處理磁盤(pán)上的文件系統(tǒng)的基礎(chǔ),因?yàn)樗x文件系統(tǒng)的管理參數(shù)(例如,塊的總數(shù)、空閑塊和根索引節(jié)點(diǎn))。 在磁盤(pán)上,超塊向內(nèi)核提供關(guān)于磁盤(pán)上的文件系統(tǒng)的結(jié)構(gòu)的信息。在內(nèi)存中,超塊為管理活動(dòng)的(已掛載)文件系統(tǒng)提供必要的信息和狀態(tài)。因?yàn)?Linux 支持同時(shí)掛載多個(gè)并發(fā)文件系統(tǒng),所以在一個(gè)列表中維護(hù)每個(gè) super_block 結(jié)構(gòu)(super_blocks 在 ./linux/fs/super.c 中定義,結(jié)構(gòu)在 /linux/include/fs/fs.h 中定義)。 圖 3 提供了超塊及其元素的簡(jiǎn)化視圖。super_block 結(jié)構(gòu)是指封裝了其他信息的許多其他結(jié)構(gòu)。例如,file_system_type 結(jié)構(gòu)維護(hù)文件系統(tǒng)的名稱(比如 ext3)以及各種鎖和函數(shù),以獲取和刪除 super_block。file_system_type 對(duì)象由常見(jiàn)的 register_file system 和 unregister_file system 函數(shù)管理(見(jiàn) ./linux/fs/file systems.c)。super_operations 結(jié)構(gòu)為讀寫(xiě)節(jié)點(diǎn)和高級(jí)操作(比如重新掛載)定義大量函數(shù)。根目錄條目(dentry)對(duì)象也緩存在這里,因?yàn)樗俏募到y(tǒng)所在的塊設(shè)備。最后,提供許多用于管理節(jié)點(diǎn)的列表,包括 s_inodes(列出所有節(jié)點(diǎn)的列表)、s_dirty(列出所有臟節(jié)點(diǎn)的列表)、s_io 和 s_more_io 以及 s_files(列出特定文件系統(tǒng)的所有打開(kāi)文件的列表)。 圖 3. super_block 結(jié)構(gòu)及其元素的簡(jiǎn)化視圖
![]() 注意,在內(nèi)核內(nèi)部,另一個(gè)稱為 vfsmount 的管理對(duì)象提供關(guān)于已掛載的文件系統(tǒng)的信息。這些對(duì)象的列表引用超塊,并定義掛載點(diǎn)、文件系統(tǒng)所在的 /dev 設(shè)備的名稱以及其他高級(jí)附加信息。 索引節(jié)點(diǎn)(inode) Linux 通過(guò)一個(gè)稱為 inode(index node 的縮寫(xiě))的對(duì)象管理文件系統(tǒng)中的所有對(duì)象。一個(gè) inode 可以引用一個(gè)文件、目錄或另一個(gè)對(duì)象的符號(hào)鏈接。注意,因?yàn)槲募糜诒硎酒渌愋偷膶?duì)象(比如設(shè)備或內(nèi)存),所以也使用 inode 來(lái)表示它們。 我在這里所指的 inode 是 VFS 層 inode(常駐 inode)。每個(gè)文件系統(tǒng)也包含一個(gè)位于磁盤(pán)上的 inode,并且提供關(guān)于特定文件系統(tǒng)的特定對(duì)象的細(xì)節(jié)。 VFS inode 使用 slab 分配器進(jìn)行分配(來(lái)自 inode_cache;參考資料 部分提供一個(gè)介紹 slab 分配器的鏈接)。inode 由描述 inode、inode 內(nèi)容和可能在 inode 上發(fā)生的各種操作的數(shù)據(jù)和操作組成。圖 4 簡(jiǎn)單展示了一個(gè) VFS inode,該 inode 包含許多列表,其中一個(gè)列表指向引用該 inode 的 dentry。這里還包含對(duì)象級(jí)別的元數(shù)據(jù),包括熟悉的操作時(shí)間(創(chuàng)建時(shí)間、訪問(wèn)時(shí)間和修改時(shí)間)和所有者和權(quán)限數(shù)據(jù)(組 ID、用戶 ID 和權(quán)限)。inode 引用它所允許的文件操作,大部分這些操作直接映射到系統(tǒng)調(diào)用接口(例如,open、read、write 和 flush)。inode 還引用特定于 inode 的操作(create、lookup、link 和 mkdir 等等)。最后,對(duì)于由地址空間對(duì)象表示的對(duì)象的數(shù)據(jù),有一個(gè)管理結(jié)構(gòu)。地址空間對(duì)象 是為 inode 管理頁(yè)緩存中的各種頁(yè)的對(duì)象。地址空間對(duì)象用于為文件管理頁(yè),也用于將文件部分映射到獨(dú)立的進(jìn)程地址空間。地址空間對(duì)象有自己的操作集(writepage、readpage 和 releasepage 等等)。 圖 4. VFS inode 的簡(jiǎn)化圖示
![]() 注意,可以在 ./linux/include/linux/fs.h 中找到所有這些信息。 目錄條目(dentry) 文件系統(tǒng)的層次結(jié)構(gòu)由 VFS 中的另一個(gè)稱為 dentry 的對(duì)象管理。文件系統(tǒng)有一個(gè)根 dentry(在超塊中引用),這是唯一沒(méi)有父對(duì)象的 dentry。所有其他 dentry 都有父對(duì)象,并且一部分 dentry 有子對(duì)象。例如,如果打開(kāi)一個(gè)由 /home/user/name 組成的文件,那么將創(chuàng)建 4 個(gè) dentry 對(duì)象:一個(gè)針對(duì)根 /、一個(gè)針對(duì)根目錄 home 的條目、一個(gè)針對(duì) user 目錄的 name 條目,以及一個(gè)針對(duì) user 目錄的 name 條目。通過(guò)這種方式,dentry 簡(jiǎn)潔地映射到現(xiàn)在使用的文件系統(tǒng)。 dentry 對(duì)象由 dentry 結(jié)構(gòu)定義(在 ./linux/include/fs/dcache.h 中)。它由許多元素組成,這些元素在文件系統(tǒng)和物理數(shù)據(jù)中跟蹤條目之間的關(guān)系(比如文件名)。圖 5 展示了 dentry 對(duì)象的簡(jiǎn)化圖示。dentry 引用 super_block,super_block 定義包含該對(duì)象的特定文件系統(tǒng)實(shí)例。接下來(lái)是該對(duì)象的父 dentry(父目錄),其后是包含在一個(gè)列表中的子 dentry(如果該對(duì)象剛好是一個(gè)目錄的話)。然后,為 dentry 定義操作(比如 hash、compare、delete 和 release 等等)。接著定義對(duì)象的名稱,在這里名稱保存在 dentry 中而不是 inode 中。最后,提供一個(gè)到 VFS inode 的引用。 圖 5. dentry 對(duì)象的簡(jiǎn)化表示
![]() 注意,dentry 對(duì)象僅存在文件系統(tǒng)內(nèi)存中,而不能儲(chǔ)存在磁盤(pán)上。僅永久儲(chǔ)存文件系統(tǒng) inode,dentry 對(duì)象的目的是改善性能。您可以在 ./linux/include/dcache.h 中看到 dentry 的完整描述。 文件對(duì)象 在 Linux 系統(tǒng)中打開(kāi)的每個(gè)文件都都存在一個(gè) file 對(duì)象。這個(gè)對(duì)象為特定用戶提供打開(kāi)的實(shí)例的信息。圖 6 提供了文件對(duì)象的簡(jiǎn)化視圖。在圖中可以看到,path 結(jié)構(gòu)提供到 dentry 和 vfsmount 的引用。為每個(gè)文件定義了一組文件操作,常見(jiàn)的文件操作包括 open、close、read、write 和 flush 等。接著定義一組標(biāo)志和權(quán)限(包括組和所有者)。最后,為特定文件實(shí)例定義狀態(tài)數(shù)據(jù),比如文件的當(dāng)前偏移量。 圖 6. 文件對(duì)象的簡(jiǎn)化表示
![]() 對(duì)象關(guān)系 我們已經(jīng)查看了 VFS 層中的各種重要對(duì)象,現(xiàn)在我們通過(guò)一個(gè)圖表展示它們之間的關(guān)系。到目前為止,我都是以一種自下而上的方式探索對(duì)象,現(xiàn)在我們采用自上而下方式,從用戶透視圖中考察對(duì)象(見(jiàn) 圖 7)。 在頂層是打開(kāi)的 file 對(duì)象,它由進(jìn)程的文件描述符列表引用。file 對(duì)象引用 dentry 對(duì)象,后者引用 inode。inode 和 dentry 對(duì)象都引用底層的 super_block 對(duì)象??赡苡卸鄠€(gè)文件對(duì)象引用同一個(gè) dentry(當(dāng)兩個(gè)用戶共享同一個(gè)文件時(shí))。注意,在圖 7 中一個(gè) dentry 對(duì)象還引用另一個(gè) dentry 對(duì)象。在這里,目錄引用文件,而文件反過(guò)來(lái)引用特定文件的 inode。 圖 7. VFS 中的主要對(duì)象之間的關(guān)系
![]() VFS架構(gòu) VFS 的內(nèi)部架構(gòu)由一個(gè)調(diào)度層(提供文件系統(tǒng)抽象)和許多緩存(用于改善文件系統(tǒng)操作的性能)組成。這個(gè)小節(jié)探索內(nèi)部架構(gòu)和主要對(duì)象之間的交互(見(jiàn)圖 8)。 圖 8. VFS 層的高級(jí)視圖
![]() 在 VFS 中動(dòng)態(tài)管理的兩個(gè)主要對(duì)象是 dentry 和 inode 對(duì)象。緩存這兩個(gè)對(duì)象,以改善訪問(wèn)底層文件系統(tǒng)的性能。當(dāng)打開(kāi)一個(gè)文件時(shí),dentry 緩存將被表示目錄級(jí)別(目錄級(jí)別表示路徑)的條目填充。此外,還為該對(duì)象創(chuàng)建一個(gè)表示文件的 inode。使用散列表創(chuàng)建 dentry 緩存,并且根據(jù)對(duì)象名分配緩存。dentry 緩存的條目從 dentry_cache slab 分配器分配,并且在緩存存在壓力時(shí)使用最近不使用(least-recently-used,LRU)算法刪除條目。您可以在 ./linux/fs/dcache.c 和 ./linux/include/linux/dcache.h 中找到與 dentry 緩存相關(guān)的函數(shù)。 為了實(shí)現(xiàn)更快的查找速度,inode 緩存被實(shí)現(xiàn)為兩個(gè)列表和一個(gè)散列表。第一個(gè)列表定義當(dāng)前使用的 inode;第二個(gè)列表定義未使用的 inode。正在使用的 inode 還儲(chǔ)存在散列表中。從 inode_cache slab 分配器分配單個(gè) inode 緩存對(duì)象。您可以在 ./linux/fs/inode.c 和 ./linux/include/fs.h 中找到與 inode 緩存相關(guān)的函數(shù)。在現(xiàn)在的實(shí)現(xiàn)中,dentry 緩存支配著 inode 緩存。如果存在一個(gè) dentry 對(duì)象,那么 inode 緩存中也將存在一個(gè) inode 對(duì)象。查找是在 dentry 緩存中執(zhí)行的,這將導(dǎo)致 inode 緩存中出現(xiàn)一個(gè)對(duì)象。 結(jié)束語(yǔ) 本文探索了 VFS 的基礎(chǔ)概念,以及為訪問(wèn)不同文件系統(tǒng)提供統(tǒng)一接口的對(duì)象。Linux 具有很大的可伸縮性和靈活性,并且可以從子系統(tǒng)進(jìn)行擴(kuò)展。您可以從 參考資料 部分提供的鏈接更多地了解 VFS。 |
聯(lián)系客服