歡迎您光臨本站 註冊首頁

Linux 虛擬系統文件交換器剖析

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

Linux ? 的最顯著特徵是靈活性和擴展性,例如它的虛擬文件系統交換器(VFS).您可以在各種設備上創建文件系統,包括傳統的磁碟、USB flash 驅動、內存以及其他儲存設備.您還可以在另一個文件系統環境中嵌入文件系統.探索導致 VFS 如此強大的因素,並了解 VFS 的主要介面和進程.

Linux 文件系統的靈活性和擴展性支持直接源於一組抽象介面.這組介面的核心就是虛擬文件系統交換器(VFS).

VFS 為上層應用程序提供一組標準介面,用於對不同的文件系統執行文件 I/O.這組介面在一個或多個底層設備上支持多個併發文件系統.另外,這些文件系統可以不是靜態的,可以根據儲存設備而變化.

VF與VFS

您還可以看到 VFS 還被定義為虛擬文件系統(virtual file system),但定義為虛擬文件系統轉換器(virtual file system switch)更能說明其作用,因為虛擬層跨多個文件系統轉換(即多路復用)請求./proc 文件系統在這裡帶來很多的混淆,因為它通常也被稱為虛擬文件系統.

例如,一個典型的 Linux 桌面在可用硬碟上支持 ext3 文件系統,並且在可用的 CD-ROM(或者稱為 CD-ROM 文件系統 或 CDFS)上支持 ISO 9660 文件系統.因為 CD-ROM 是可以插入和移除的, Linux 內核必須適應這些包含不同內容和結構的新文件系統.可以通過網路文件系統(Network File System,NFS)訪問遠程文件系統.在此時,Linux 還可以掛載來自本地硬碟的 Windows?/Linux 雙引導系統的 NT File System (NTFS) 分區,並且能夠向其讀寫數據.

,可移除的 USB flash 啟動(UFD)是可以熱插拔的,它構成另一個文件系統.概而言之,可以在這些設備中使用同一組文件 I/O 介面,從而允許底層的文件系統和物理設備能夠從用戶中抽象出來(見圖 1).

圖 1. 在不同文件系統和儲存設備之間提供統一介面的抽象層

分層抽象

現在,我們向 Linux VFS 提供的抽象特性添加一些具體的架構.圖 2 從 VFS 的角度顯示 Linux 結構的高級視圖.在 VFS 之上的是標準的內核系統調用介面(SCI).這個介面允許用戶空間發出要求轉換到內核的調用(在不同地址空間中).在這個域中,調用 POSIX open 調用的用戶空間應用程序經過 GNU C 庫(glibc)進入內核和系統調用去多元化(de-multiplexing).,使用 sys_open 調用 VFS.

圖 2. VFS 的分層架構

早期的VFS實現

Linux 並不是第一個包含虛擬層以支持通用文件模型的操作系統.早期的 VFS 實現包括 Sun 的 VFS(SunOS version 2.0,大約出現在 1985 年),以及 IBM 和 Microsoft? 的 「Installable File System」 for IBM OS/2.這些虛擬化文件系統層的方法為 Linux VFS 鋪平了道路.

VFS 提供抽象層,從而將 POSIX API 與特定文件系統如何實現該行為的細節分離開來.這裡的關鍵之處是,不管底層文件系統是 ext3 還是 Btrfs,Open、Read、Write 或 Close API 系統調用都能正常工作.VFS 提供一個由底層文件系統(它們必須為各種 POSIX API 函數實現行為)繼承的通用文件模型.另一個在 VFS 範圍之外的深層抽象隱藏了底層物理設備(可能是磁碟、磁碟分區、網路儲存實體、內存或其他能夠儲存信息的媒介 —— 即使是暫時性的).

除了從底層文件系統抽象文件操作的細節之外,VFS 還將底層塊設備綁定到可用的文件系統.讓我們看看 VFS 的內部結構及其工作原理.

VFS的內部結構

在查看 VFS 子系統的總體架構之前,我們先看看所使用的主要對象.這個小節探索了超塊(superblock)、索引節點(或 inode)、目錄條目(或 dentry)和文件對象.在這裡,其他一些組成部分也很重要,比如緩存.不過我將在後面的總體架構中討論它們.

超塊

超塊(superblock)是關於文件系統的高級元數據的容器.超塊是存在於磁碟上(實際上位於磁碟的多個位置上,以提供冗餘)的結構.它是處理磁碟上的文件系統的基礎,因為它定義文件系統的管理參數(例如,塊的總數、空閑塊和根索引節點).

在磁碟上,超塊向內核提供關於磁碟上的文件系統的結構的信息.在內存中,超塊為管理活動的(已掛載)文件系統提供必要的信息和狀態.因為 Linux 支持同時掛載多個併發文件系統,在一個列表中維護每個 super_block 結構(super_blocks 在 ./linux/fs/super.c 中定義,結構在 /linux/include/fs/fs.h 中定義).

圖 3 提供了超塊及其元素的簡化視圖.super_block 結構是指封裝了其他信息的許多其他結構.例如,file_system_type 結構維護文件系統的名稱(比如 ext3)以及各種鎖和函數,以獲取和刪除 super_block.file_system_type 對象由常見的 register_file system 和 unregister_file system 函數管理(見 ./linux/fs/file systems.c).super_operations 結構為讀寫節點和高級操作(比如重新掛載)定義大量函數.根目錄條目(dentry)對象也緩存在這裡,因為它是文件系統所在的塊設備.,提供許多用於管理節點的列表,包括 s_inodes(列出所有節點的列表)、s_dirty(列出所有臟節點的列表)、s_io 和 s_more_io 以及 s_files(列出特定文件系統的所有打開文件的列表).

圖 3. super_block 結構及其元素的簡化視圖

注意,在內核內部,另一個稱為 vfsmount 的管理對象提供關於已掛載的文件系統的信息.這些對象的列表引用超塊,並定義掛載點、文件系統所在的 /dev 設備的名稱以及其他高級附加信息.

索引節點(inode)

Linux 通過一個稱為 inode(index node 的縮寫)的對象管理文件系統中的所有對象.一個 inode 可以引用一個文件、目錄或另一個對象的符號鏈接.注意,因為文件用於表示其他類型的對象(比如設備或內存),也使用 inode 來表示它們.

我在這裡所指的 inode 是 VFS 層 inode(常駐 inode).每個文件系統也包含一個位於磁碟上的 inode,並且提供關於特定文件系統的特定對象的細節.

VFS inode 使用 slab 分配器進行分配(來自 inode_cache;參考資料 部分提供一個介紹 slab 分配器的鏈接).inode 由描述 inode、inode 內容和可能在 inode 上發生的各種操作的數據和操作組成.圖 4 簡單展示了一個 VFS inode,該 inode 包含許多列表,其中一個列表指向引用該 inode 的 dentry.這裡還包含對象級別的元數據,包括熟悉的操作時間(創建時間、訪問時間和修改時間)和所有者和許可權數據(組 ID、用戶 ID 和許可權).inode 引用它所允許的文件操作,大部分這些操作直接映射到系統調用介面(例如,open、read、write 和 flush).inode 還引用特定於 inode 的操作(create、lookup、link 和 mkdir 等等).,對於由地址空間對象表示的對象的數據,有一個管理結構.地址空間對象 是為 inode 管理頁緩存中的各種頁的對象.地址空間對象用於為文件管理頁,也用於將文件部分映射到獨立的進程地址空間.地址空間對象有自己的操作集(writepage、readpage 和 releasepage 等等).

圖 4. VFS inode 的簡化圖示

注意,可以在 ./linux/include/linux/fs.h 中找到所有這些信息.

目錄條目(dentry)

文件系統的層次結構由 VFS 中的另一個稱為 dentry 的對象管理.文件系統有一個根 dentry(在超塊中引用),這是唯一沒有父對象的 dentry.所有其他 dentry 都有父對象,並且一部分 dentry 有子對象.例如,如果打開一個由 /home/user/name 組成的文件,那麼將創建 4 個 dentry 對象:一個針對根 /、一個針對根目錄 home 的條目、一個針對 user 目錄的 name 條目,以及一個針對 user 目錄的 name 條目.通過這種方式,dentry 簡潔地映射到現在使用的文件系統.

dentry 對象由 dentry 結構定義(在 ./linux/include/fs/dcache.h 中).它由許多元素組成,這些元素在文件系統和物理數據中跟蹤條目之間的關係(比如文件名).圖 5 展示了 dentry 對象的簡化圖示.dentry 引用 super_block,super_block 定義包含該對象的特定文件系統實例.接下來是該對象的父 dentry(父目錄),其後是包含在一個列表中的子 dentry(如果該對象剛好是一個目錄的話).然後,為 dentry 定義操作(比如 hash、compare、delete 和 release 等等).接著定義對象的名稱,在這裡名稱保存在 dentry 中而不是 inode 中.,提供一個到 VFS inode 的引用.

圖 5. dentry 對象的簡化表示

注意,dentry 對象僅存在文件系統內存中,而不能儲存在磁碟上.僅永久儲存文件系統 inode,dentry 對象的目的是改善性能.您可以在 ./linux/include/dcache.h 中看到 dentry 的完整描述.

文件對象

在 Linux 系統中打開的每個文件都都存在一個 file 對象.這個對象為特定用戶提供打開的實例的信息.圖 6 提供了文件對象的簡化視圖.在圖中可以看到,path 結構提供到 dentry 和 vfsmount 的引用.為每個文件定義了一組文件操作,常見的文件操作包括 open、close、read、write 和 flush 等.接著定義一組標誌和許可權(包括組和所有者).,為特定文件實例定義狀態數據,比如文件的當前偏移量.

圖 6. 文件對象的簡化表示

對象關係

我們已經查看了 VFS 層中的各種重要對象,現在我們通過一個圖表展示它們之間的關係.到目前為止,我都是以一種自下而上的方式探索對象,現在我們採用自上而下方式,從用戶透視圖中考察對象(見 圖 7).

在頂層是打開的 file 對象,它由進程的文件描述符列表引用.file 對象引用 dentry 對象,後者引用 inode.inode 和 dentry 對象都引用底層的 super_block 對象.可能有多個文件對象引用同一個 dentry(當兩個用戶共享同一個文件時).注意,在圖 7 中一個 dentry 對象還引用另一個 dentry 對象.在這裡,目錄引用文件,而文件反過來引用特定文件的 inode.

圖 7. VFS 中的主要對象之間的關係

VFS架構

VFS 的內部架構由一個調度層(提供文件系統抽象)和許多緩存(用於改善文件系統操作的性能)組成.這個小節探索內部架構和主要對象之間的交互(見圖 8).

圖 8. VFS 層的高級視圖

在 VFS 中動態管理的兩個主要對象是 dentry 和 inode 對象.緩存這兩個對象,以改善訪問底層文件系統的性能.當打開一個文件時,dentry 緩存將被表示目錄級別(目錄級別表示路徑)的條目填充.此外,還為該對象創建一個表示文件的 inode.使用散列表創建 dentry 緩存,並且根據對象名分配緩存.dentry 緩存的條目從 dentry_cache slab 分配器分配,並且在緩存存在壓力時使用最近不使用(least-recently-used,LRU)演算法刪除條目.您可以在 ./linux/fs/dcache.c 和 ./linux/include/linux/dcache.h 中找到與 dentry 緩存相關的函數.

為了實現更快的查找速度,inode 緩存被實現為兩個列表和一個散列表.第一個列表定義當前使用的 inode;第二個列表定義未使用的 inode.正在使用的 inode 還儲存在散列表中.從 inode_cache slab 分配器分配單個 inode 緩存對象.您可以在 ./linux/fs/inode.c 和 ./linux/include/fs.h 中找到與 inode 緩存相關的函數.在現在的實現中,dentry 緩存支配著 inode 緩存.如果存在一個 dentry 對象,那麼 inode 緩存中也將存在一個 inode 對象.查找是在 dentry 緩存中執行的,這將導致 inode 緩存中出現一個對象.

結束語

本文探索了 VFS 的基礎概念,以及為訪問不同文件系統提供統一介面的對象.Linux 具有很大的可伸縮性和靈活性,並且可以從子系統進行擴展.您可以從 參考資料 部分提供的鏈接更多地了解 VFS.


[火星人 ] Linux 虛擬系統文件交換器剖析已經有872次圍觀

http://coctec.com/docs/linux/show-post-53086.html