虛擬檔案系統VFS 上

2021-10-25 22:09:59 字數 3744 閱讀 9421

虛擬檔案系統(vfs)作為核心子系統,為使用者空間程式提供了檔案和檔案系統相關的介面。系統中所有檔案系統依賴vfs共存、協同工作,程式利用標準的unix系統呼叫對不同的檔案系統,甚至不同介質的檔案系統進行讀寫操作。

vfs使得使用者可以直接使用open()、read()、write()這樣的系統呼叫而無須考慮具體檔案系統和實際物理介質。

vfs將各種不同的檔案系統抽象後採用統一的方式進行操作。同時與塊i/o結合,提供抽象、介面以及交融,使得使用者空間的程式呼叫統一的系統呼叫訪問各種檔案。

之所以可以使用通用介面對所有型別的檔案系統進行操作,是因為核心在底層檔案系統介面上建立了乙個抽象層,使得linux能夠支援各種檔案系統。

為了支援多檔案系統,vfs提供了乙個通用檔案系統模型,該模型概括了任何檔案系統的常用功能集和行為。

vfs抽象層之所以能夠銜接各種各樣的檔案系統,是因為它定義了所有檔案系統都支援基本的、概念上的介面和資料結構。同時檔案系統也將諸多行為在形式上與vfs的定義保持一致。實際檔案系統的**在統一的介面和資料結構下隱藏了具體的實現細節,所以在vfs層和核心的其餘部分看來,所有檔案系統都是相同的。

核心通過抽象層能夠方便的支援各種各樣的檔案系統,實際的檔案系統通過程式設計提供給vfs所希望的抽象介面和資料結構。

ret =

write

(fd, buf, len)

;

該系統呼叫將buf指標指向的長度為len的資料寫入檔案描述符fd對應的檔案的當前位置,該系統呼叫首先被乙個通用系統呼叫sys_write()處理,sys_write()找到fd所在的檔案系統實際給出的操作,然後執行該操作,資料最後通過該操作寫入儲存介質。

unix使用了四種與檔案系統相關的抽象概念:檔案、目錄、索引節點、安裝點。

從本質上將檔案系統是特殊的資料分層儲存結構,包含檔案、目錄和相關的控制資訊,檔案系統的通用操作包括建立、刪除和安裝等。unix中,檔案系統被安裝在乙個特定的安裝點上,該安裝點在全域性層次結構上被稱作命名空間,所有的已安裝檔案系統都作為根檔案系統樹的枝葉吹安在系統中。

檔案通過目錄進行組織,檔案目錄相當於資料夾,用來容納相關檔案,所以目錄也包含其他目錄,即子目錄。所以目錄層層巢狀,形成檔案路徑。檔案路徑中的每一部分都被稱作目錄條目,也稱為目錄項。在unix中,目錄屬於普通檔案,列出包含在目錄中的所有檔案。在vfs中同樣把目錄當做檔案對待,對目錄執行與檔案相同的操作。目錄項可以理解為檔案路徑,在讀取到每個檔案過後會為該檔案建立目錄項。

unix檔案系統將檔案與檔案資訊加以區分,例如訪問許可權、檔案大小、建立時間等屬於檔案資訊。檔案的相關資訊被稱為檔案的元資料,儲存在乙個被稱為索引節點(index node, inode)中的單獨的資料結構中。

所有這些資訊與檔案系統控制資訊相關,檔案系統的控制資訊儲存在超級塊中,超級塊是一種包含檔案系統資訊的資料結構。

unix檔案系統在磁碟上的布局也是如此實現的,比如說在磁碟,檔案資訊安裝inode格式儲存在單獨的塊中,控制資訊集中儲存在磁碟的超級塊中。unix中檔案的概念從物理上對映到儲存介質上。linux的vfs的設計目標就是要保證能與支援和實現了這些概念的檔案系統協同工作。假如檔案系統不支援這種風格,同樣可以在linux上工作,但必須經過封裝提供符合概念的介面。這種轉換需要在使用現場(on the fly)引入特殊處理,但是帶來極大的開銷。

vfs採用的是物件導向的設計思路,採用資料結構代表通用檔案物件。vfs主要包括四個物件型別:

每個物件都包含乙個操作物件,描述了核心針對主要物件可以使用的方法:

作業系統作為乙個結構體指標實現,包含操作其父物件的函式指標。對於很多方法,如果vfs的通用函式無法滿足,就必須使用檔案系統的獨有方法進行填充。

檔案系統都必須實現超級塊物件,用於儲存特定檔案系統的資訊,通常對應於存放在磁碟特定扇區的檔案系統超級塊或者檔案系統控制塊。對於並非基於磁碟的檔案系統,會在使用現場建立超級塊並儲存到記憶體。超級塊物件由super_block表示,定義在中,以下為具體描述:

struct

super_block

;

建立、管理和撤銷超級塊物件的**位於檔案fs/super.c中,超級塊物件通過alloc_super()函式建立並初始化。在檔案系統安裝時,檔案系統會呼叫該函式以便從磁碟讀取檔案系統超級塊,並將其資訊填充到記憶體中的超級塊物件中。

超級塊結構體中最重要的域是s_op,指向超級塊的操作函式表,超級塊操作函式由super_operations結構體表示,定義在檔案中,其形式如下:

struct

super_operations

;

該結構體中的每一項都是乙個指向超級塊操作函式的指標,超級塊操作函式執行檔案系統和索引節點的底層操作。

當檔案系統需要對其超級塊執行操作時,首先要在超級塊物件中尋找需要的操作方法,當乙個檔案系統要寫自己的超級塊,需要呼叫:

sb->s_op->

write_super

(sb)

;

在這個呼叫中,sb是指向檔案系統超級塊的指標,沿著該指標進入超級塊操作函式表s_op,並從表中取得希望得到的write_super()函式,該函式執行寫入超級塊的實際操作。需要注意的是,儘管write_siper()方法來自超級塊,但在呼叫時,超級塊毅然要作為引數進行傳遞,這是因為c語言缺少物件導向的支援、如果是在c++中,只需要如下呼叫:

sb.

write_super

()

由於在c語言中無法直接得到操作函式的父物件,所以必須將父物件以引數形式傳遞給操作函式。

s_op中的所有函式由vfs在程序上下文中呼叫,除了dirty_inode(),其他函式在必要時都可以阻塞。這其中的一些函式是可選的,在超級塊操作表中,檔案系統可以將不需要的函式指標設定為null。如果vfs發現操作函式指標是null,那麼會呼叫通用函式執行相應操作,要麼什麼也不做,如何選擇取決於具體操作。

索引節點物件包含了核心在操作檔案或目錄時需要的全部資訊,對於unix風格的檔案系統來說,這些資訊可以從磁碟索引節點直接讀入,如果乙個檔案系統沒有索引節點,那麼不管這些資訊在磁碟上是如何存放的,檔案系統都必須從其中提取這些資訊,沒有索引節點的檔案系統通常將檔案的描述資訊作為檔案的一部分進行存放。這些檔案系統與unix風格的檔案系統不同,沒有將資料與控制資訊分開存放。有些現代檔案系統使用資料庫儲存檔案的資料。但是無論採用哪種方式,索引節點必須在記憶體中建立以便檔案系統使用。

索引節點物件由inode結構體表示,定義在檔案中:

struct

inode

;

乙個索引節點代表檔案系統中(索引節點僅當檔案系統被訪問時才會在記憶體中建立)的乙個檔案,也可以是裝置或管道這樣特殊的檔案,因此索引節點結構體中有一些和特殊檔案相關的項。

有時,某些檔案系統並不能完整地包含索引節點結構體要求的所有資訊,檔案系統可以在實現中選擇任意合適的辦法來解決這個問題。

索引節點的inode_operations項描述了vfs用以操作索引節點物件的所有方法,這些方法由檔案系統實現。與超級塊類似,對索引節點的操作呼叫方式如下:

i->i_op->

truncate

(i);

i 指向給定的索引節點,truncate()函式是由索引節點 i 所在的檔案系統定義的。inode_operations結構體定義在檔案中。這些函式可能由vfs執行這些函式,也可能由具體的檔案系統執行:

struct

inode_operations

;

虛擬檔案系統VFS

現代作業系統必須同時支援多個檔案系統,作業系統如何將多個檔案系統整合成乙個目錄結構?使用者如何在訪問檔案系統空間時可以無縫地在檔案系統型別之間移動呢?絕大多數作業系統包括unix都使用物件導向技術來簡化 組織和模組化實現過程,使用這些方法允許不同檔案系統型別可通過同樣結構來實現,這也包括了網路檔案系...

VFS虛擬檔案系統

虛擬檔案系統是具體檔案系統之上的乙個抽象層,它可以使得客戶程式以統一的方式接入不同型別的具體檔案型別。vfs是核心和具體檔案系統之間的乙個介面,只要通過實現這個介面,核心就可以新增對某乙個檔案系統型別的支援。有時vfs指的是通過使用軟體來作為乙個管理容器,提供和具體的檔案系統一樣的功能,通常是乙個或...

linux虛擬檔案系統vfs

linux可以掛載不同的檔案系統 ext2,fat,ntfs 用同一的樣式呈現給使用者,讀寫操作用起來都一樣,這是怎樣做到的呢?linux核心在各種不同的檔案系統格式上做了乙個抽象層,使得檔案 目錄 讀寫訪問等概念成為抽象層的概念,因此各種檔案系統看起來用起來都一樣,這個抽象層稱為虛擬檔案系統 vf...