2007 年 12 月 03 日 在 文件系統(tǒng)方面,Linux? 可以算得上操作系統(tǒng)中的 “瑞士軍刀”。Linux 支持許多種文件系統(tǒng),從日志型文件系統(tǒng)到集群文件系統(tǒng)和加密文件系統(tǒng)。對(duì)于使用標(biāo)準(zhǔn)的和比較奇特的文件系統(tǒng)以及開發(fā)文件系統(tǒng)來說,Linux 是極好的平臺(tái)。本文討論 Linux 內(nèi)核中的虛擬文件系統(tǒng)(VFS,有時(shí)候稱為虛擬文件系統(tǒng)交換器),然后介紹將文件系統(tǒng)連接在一起的主要結(jié)構(gòu)。 Linux 文件系統(tǒng)體系結(jié)構(gòu)是一個(gè)對(duì)復(fù)雜系統(tǒng)進(jìn)行抽象化的有趣例子。通過使用一組通用的 API 函數(shù),Linux 可以在許多種存儲(chǔ)設(shè)備上支持許多種文件系統(tǒng)。例如, 首 先回答最常見的問題,“什么是文件系統(tǒng)”。文件系統(tǒng)是對(duì)一個(gè)存儲(chǔ)設(shè)備上的數(shù)據(jù)和元數(shù)據(jù)進(jìn)行組織的機(jī)制。由于定義如此寬泛,支持它的代碼會(huì)很有意思。正如前 面提到的,有許多種文件系統(tǒng)和媒體。由于存在這么多類型,可以預(yù)料到 Linux 文件系統(tǒng)接口實(shí)現(xiàn)為分層的體系結(jié)構(gòu),從而將用戶接口層、文件系統(tǒng)實(shí)現(xiàn)和操作存儲(chǔ)設(shè)備的驅(qū)動(dòng)程序分隔開。
在 Linux 中將一個(gè)文件系統(tǒng)與一個(gè)存儲(chǔ)設(shè)備關(guān)聯(lián)起來的過程稱為掛裝(mount)。使用 為了說明 Linux 文件系統(tǒng)層的功能(以及掛裝的方法),我們?cè)诋?dāng)前文件系統(tǒng)的一個(gè)文件中創(chuàng)建一個(gè)文件系統(tǒng)。實(shí)現(xiàn)的方法是,首先用 清單 1. 創(chuàng)建一個(gè)經(jīng)過初始化的文件
現(xiàn)在有了一個(gè) 10MB 的 file.img 文件。使用
這個(gè)文件現(xiàn)在作為一個(gè)塊設(shè)備出現(xiàn)(由 /dev/loop0 表示)。然后用 清單 2. 用循環(huán)設(shè)備創(chuàng)建 ext2 文件系統(tǒng)
使用 清單 3. 創(chuàng)建掛裝點(diǎn)并通過循環(huán)設(shè)備掛裝文件系統(tǒng)
如清單 4 所示,還可以繼續(xù)這個(gè)過程:在剛才掛裝的文件系統(tǒng)中創(chuàng)建一個(gè)新文件,將它與一個(gè)循環(huán)設(shè)備關(guān)聯(lián)起來,再在上面創(chuàng)建另一個(gè)文件系統(tǒng)。 清單 4. 在循環(huán)文件系統(tǒng)中創(chuàng)建一個(gè)新的循環(huán)文件系統(tǒng)
通過這個(gè)簡單的演示很容易體會(huì)到 Linux 文件系統(tǒng)(和循環(huán)設(shè)備)是多么強(qiáng)大??梢园凑障嗤姆椒ㄔ谖募嫌醚h(huán)設(shè)備創(chuàng)建加密的文件系統(tǒng)??梢栽谛枰獣r(shí)使用循環(huán)設(shè)備臨時(shí)掛裝文件,這有助于保護(hù)數(shù)據(jù)。 既然已經(jīng)看到了文件系統(tǒng)的構(gòu)造方法,現(xiàn)在就看看 Linux 文件系統(tǒng)層的體系結(jié)構(gòu)。本文從兩個(gè)角度考察 Linux 文件系統(tǒng)。首先采用高層體系結(jié)構(gòu)的角度。然后進(jìn)行深層次討論,介紹實(shí)現(xiàn)文件系統(tǒng)層的主要結(jié)構(gòu)。 盡管大多數(shù)文件系統(tǒng)代碼在內(nèi)核中(后面討論的用戶空間文件系統(tǒng)除外),但是圖 1 所示的體系結(jié)構(gòu)顯示了用戶空間和內(nèi)核中與文件系統(tǒng)相關(guān)的主要組件之間的關(guān)系。 圖 1. Linux 文件系統(tǒng)組件的體系結(jié)構(gòu) ![]() 用戶空間包含一些應(yīng)用程序(例如,文件系統(tǒng)的使用者)和 GNU C 庫(glibc),它們?yōu)槲募到y(tǒng)調(diào)用(打開、讀取、寫和關(guān)閉)提供用戶接口。系統(tǒng)調(diào)用接口的作用就像是交換器,它將系統(tǒng)調(diào)用從用戶空間發(fā)送到內(nèi)核空間中的適當(dāng)端點(diǎn)。 VFS 是底層文件系統(tǒng)的主要接口。這個(gè)組件導(dǎo)出一組接口,然后將它們抽象到各個(gè)文件系統(tǒng),各個(gè)文件系統(tǒng)的行為可能差異很大。有兩個(gè)針對(duì)文件系統(tǒng)對(duì)象的緩存(inode 和 dentry)。它們緩存最近使用過的文件系統(tǒng)對(duì)象。 每 個(gè)文件系統(tǒng)實(shí)現(xiàn)(比如 ext2、JFS 等等)導(dǎo)出一組通用接口,供 VFS 使用。緩沖區(qū)緩存會(huì)緩存文件系統(tǒng)和相關(guān)塊設(shè)備之間的請(qǐng)求。例如,對(duì)底層設(shè)備驅(qū)動(dòng)程序的讀寫請(qǐng)求會(huì)通過緩沖區(qū)緩存來傳遞。這就允許在其中緩存請(qǐng)求,減少訪問 物理設(shè)備的次數(shù),加快訪問速度。以最近使用(LRU)列表的形式管理緩沖區(qū)緩存。注意,可以使用
這就是 VFS 和文件系統(tǒng)組件的高層情況?,F(xiàn)在,討論實(shí)現(xiàn)這個(gè)子系統(tǒng)的主要結(jié)構(gòu)。 Linux 以一組通用對(duì)象的角度看待所有文件系統(tǒng)。這些對(duì)象是超級(jí)塊(superblock)、inode、dentry 和文件。超級(jí)塊在每個(gè)文件系統(tǒng)的根上,超級(jí)塊描述和維護(hù)文件系統(tǒng)的狀態(tài)。文件系統(tǒng)中管理的每個(gè)對(duì)象(文件或目錄)在 Linux 中表示為一個(gè) inode。inode 包含管理文件系統(tǒng)中的對(duì)象所需的所有元數(shù)據(jù)(包括可以在對(duì)象上執(zhí)行的操作)。另一組結(jié)構(gòu)稱為 dentry,它們用來實(shí)現(xiàn)名稱和 inode 之間的映射,有一個(gè)目錄緩存用來保存最近使用的 dentry。dentry 還維護(hù)目錄和文件之間的關(guān)系,從而支持在文件系統(tǒng)中移動(dòng)。最后,VFS 文件表示一個(gè)打開的文件(保存打開的文件的狀態(tài),比如寫偏移量等等)。 VFS 作為文件系統(tǒng)接口的根層。VFS 記錄當(dāng)前支持的文件系統(tǒng)以及當(dāng)前掛裝的文件系統(tǒng)。 可以使用一組注冊(cè)函數(shù)在 Linux 中動(dòng)態(tài)地添加或刪除文件系統(tǒng)。內(nèi)核保存當(dāng)前支持的文件系統(tǒng)的列表,可以通過 /proc 文件系統(tǒng)在用戶空間中查看這個(gè)列表。這個(gè)虛擬文件還顯示當(dāng)前與這些文件系統(tǒng)相關(guān)聯(lián)的設(shè)備。在 Linux 中添加新文件系統(tǒng)的方法是調(diào)用 在注冊(cè)新的文件系統(tǒng)時(shí),會(huì)把這個(gè)文件系統(tǒng)和它的相關(guān)信息添加到 file_systems 列表中(見圖 2 和 linux/include/linux/mount.h)。這個(gè)列表定義可以支持的文件系統(tǒng)。在命令行上輸入 圖 2. 向內(nèi)核注冊(cè)的文件系統(tǒng) ![]() VFS 中維護(hù)的另一個(gè)結(jié)構(gòu)是掛裝的文件系統(tǒng)(見圖 3)。這個(gè)結(jié)構(gòu)提供當(dāng)前掛裝的文件系統(tǒng)(見 linux/include/linux/fs.h)。它鏈接下面討論的超級(jí)塊結(jié)構(gòu)。 圖 3. 掛裝的文件系統(tǒng)列表 ![]() 超 級(jí)塊結(jié)構(gòu)表示一個(gè)文件系統(tǒng)。它包含管理文件系統(tǒng)所需的信息,包括文件系統(tǒng)名稱(比如 ext2)、文件系統(tǒng)的大小和狀態(tài)、塊設(shè)備的引用和元數(shù)據(jù)信息(比如空閑列表等等)。超級(jí)塊通常存儲(chǔ)在存儲(chǔ)媒體上,但是如果超級(jí)塊不存在,也可以實(shí)時(shí)創(chuàng)建 它??梢栽?./linux/include/linux/fs.h 中找到超級(jí)塊結(jié)構(gòu)(見圖 4)。 圖 4. 超級(jí)塊結(jié)構(gòu)和 inode 操作 ![]() 超級(jí)塊中的一個(gè)重要元素是超級(jí)塊操作的定義。這個(gè)結(jié)構(gòu)定義一組用來管理這個(gè)文件系統(tǒng)中的 inode 的函數(shù)。例如,可以用 inode 表示文件系統(tǒng)中的一個(gè)對(duì)象,它具有惟一標(biāo)識(shí)符。各個(gè)文件系統(tǒng)提供將文件名映射為惟一 inode 標(biāo)識(shí)符和 inode 引用的方法。圖 5 顯示 inode 結(jié)構(gòu)的一部分以及兩個(gè)相關(guān)結(jié)構(gòu)。請(qǐng)?zhí)貏e注意 圖 5. inode 結(jié)構(gòu)和相關(guān)聯(lián)的操作 ![]() inode 和目錄緩存分別保存最近使用的 inode 和 dentry。注意,對(duì)于 inode 緩存中的每個(gè) inode,在目錄緩存中都有一個(gè)對(duì)應(yīng)的 dentry??梢栽?./linux/include/linux/fs.h 中找到 除 了各個(gè)文件系統(tǒng)實(shí)現(xiàn)(可以在 ./linux/fs 中找到)之外,文件系統(tǒng)層的底部是緩沖區(qū)緩存。這個(gè)組件跟蹤來自文件系統(tǒng)實(shí)現(xiàn)和物理設(shè)備(通過設(shè)備驅(qū)動(dòng)程序)的讀寫請(qǐng)求。為了提高效率,Linux 對(duì)請(qǐng)求進(jìn)行緩存,避免將所有請(qǐng)求發(fā)送到物理設(shè)備。緩存中緩存最近使用的緩沖區(qū)(頁面),這些緩沖區(qū)可以快速提供給各個(gè)文件系統(tǒng)。 本 文沒有討論 Linux 中可用的具體文件系統(tǒng),但是值得在這里稍微提一下。Linux 支持許多種文件系統(tǒng),包括 MINIX、MS-DOS 和 ext2 等老式文件系統(tǒng)。Linux 還支持 ext3、JFS 和 ReiserFS 等新的日志型文件系統(tǒng)。另外,Linux 支持加密文件系統(tǒng)(比如 CFS)和虛擬文件系統(tǒng)(比如 /proc)。 最后一種值得注意的文件系統(tǒng)是 Filesystem in Userspace(FUSE)。這種文件系統(tǒng)可以將文件系統(tǒng)請(qǐng)求通過 VFS 發(fā)送回用戶空間。所以,如果您有興趣創(chuàng)建自己的文件系統(tǒng),那么通過使用 FUSE 進(jìn)行開發(fā)是一種不錯(cuò)的方法。
盡管文件系統(tǒng)的實(shí)現(xiàn)并不復(fù)雜,但它是可伸縮和可擴(kuò)展的體系結(jié)構(gòu)的好例子。文件系統(tǒng)體系結(jié)構(gòu)已經(jīng)發(fā)展了許多年,并成功地支持了許多不同類型的文件系統(tǒng)和許多目標(biāo)存儲(chǔ)設(shè)備類型。由于使用了基于插件的體系結(jié)構(gòu)和多層的函數(shù)間接性,Linux 文件系統(tǒng)在近期的發(fā)展很值得關(guān)注。 學(xué)習(xí)
獲得產(chǎn)品和技術(shù)
討論
|
聯(lián)系客服