侯旗,陳慈發(fā),艾偉
(三峽大學(xué),宜昌443002)
隨著嵌入式技術(shù)的發(fā)展,越來越多的嵌入式設(shè)備采用Linux作為其操作系統(tǒng)。Linux支持各種物理文件系統(tǒng),而不同物理文件系統(tǒng)具有不同的組織結(jié)構(gòu)和不同的處理方式。為了兼容支持不同的文件系統(tǒng),Linux設(shè)計了在系統(tǒng)啟動時由系統(tǒng)在內(nèi)存創(chuàng)建的文件系統(tǒng),即虛擬文件系統(tǒng)(Virtual File System,VFS)。該文件系統(tǒng)對不同的物理文件系統(tǒng)的所有特性進(jìn)行抽象,屏蔽各種文件系統(tǒng)的差別,向Linux內(nèi)核和進(jìn)程提供了一個處理各種物理文件系統(tǒng)的公共接口,從而實現(xiàn)了對不同文件系統(tǒng)的支持。而且,Linux系統(tǒng)把一切的設(shè)備也當(dāng)作文件來處理。理解Linux虛擬文件系統(tǒng)機(jī)制對于學(xué)習(xí)Linux運(yùn)行原理起著重要的作用。本文對Linux虛擬文件系統(tǒng)原理進(jìn)行了較為詳盡的分析。
Linux以EXT2作為基本的文件系統(tǒng),組成虛擬文件系統(tǒng)的超級塊、索引節(jié)點(diǎn)、目錄項等數(shù)據(jù)結(jié)構(gòu),兼容于各種文件系統(tǒng)的相應(yīng)數(shù)據(jù)結(jié)構(gòu),從而實現(xiàn)了對多種文件系統(tǒng)的透明調(diào)用。
Linux繼承了Uinx,把文件名和文件控制信息分開管理。一個Linux所支持的物理文件系統(tǒng)使用的塊設(shè)備上的一個獨(dú)立邏輯分區(qū)可大致分為:引導(dǎo)塊、超級塊、inode塊、data塊4部分[1]。超級塊是描述文件系統(tǒng)整體信息的數(shù)據(jù)結(jié)構(gòu),在系統(tǒng)運(yùn)行期間被讀入內(nèi)存,在內(nèi)存中建立一個超級塊的映像。Linux所支持的文件系統(tǒng)的一般結(jié)構(gòu)如圖1所示。
圖1 Linux所支持的文件系統(tǒng)的一般結(jié)構(gòu)
Linux VFS采用超級塊(super_block)和索引節(jié)點(diǎn)(inode)來描述文件系統(tǒng)。這里的super_block和inode不同于物理文件系統(tǒng)中的super_block和inode數(shù)據(jù)結(jié)構(gòu),VFS super_block是VFS把不同文件系統(tǒng)中的整體組織和結(jié)構(gòu)信息進(jìn)行抽象后形成的,兼顧不同文件系統(tǒng)的統(tǒng)一的超級塊結(jié)構(gòu)。在安裝文件系統(tǒng)時,由系統(tǒng)在內(nèi)存中建立,其內(nèi)容主要由文件系統(tǒng)的超級塊數(shù)據(jù)來填充。inode則是在系統(tǒng)打開文件時,由系統(tǒng)在內(nèi)存動態(tài)建立,其內(nèi)容主要由文件系統(tǒng)的inode節(jié)點(diǎn)的數(shù)據(jù)來填充。
Linux VFS除了沒有存儲文件內(nèi)容的data塊外,文件系統(tǒng)的結(jié)構(gòu)與物理文件系統(tǒng)基本相似,如圖2所示。
圖2 Linux VFS文件系統(tǒng)結(jié)構(gòu)
Linux進(jìn)程通過VFS中相應(yīng)的超級塊和索引節(jié)點(diǎn)中的信息,準(zhǔn)確地訪問操作目的磁盤文件系統(tǒng)中的相應(yīng)文件。
為了區(qū)分文件系統(tǒng)中的inode,這里把VFS中的inode稱為vnode。
Linux系統(tǒng)支持文件系統(tǒng)目錄樹機(jī)制,根據(jù)路徑名,如/home/xyz/work/test.c,就 可 以 在 磁 盤 上 找 到 文 件test.c的目錄項和索引節(jié)點(diǎn)。在路徑/home/xyz/work/test.c中,目錄/、home、xyz、work以及普通文件test.c都對應(yīng)一個目錄項對象。目錄項在磁盤文件系統(tǒng)中的數(shù)據(jù)結(jié)構(gòu)是dir_entry,VFS在遍歷路徑名的過程中將其解析成內(nèi)存目錄項對象(dentry對象)和vnode對象。
vnode與某個文件的對應(yīng)關(guān)系是通過設(shè)備號i_dev與inode號i_ino建立的,它們唯一地指定了某個設(shè)備上的一個文件或目錄。vnode是設(shè)備上的文件或目錄的inode在內(nèi)存中的統(tǒng)一對應(yīng)結(jié)構(gòu),并且給出了不同文件系統(tǒng)特有的信息,即各種文件系統(tǒng)的inode在內(nèi)存中的映像。
如前所述,Linux繼承了Uinx,把文件名和文件控制信息分開管理,由目錄項(dir_entry)管理文件名,索引節(jié)點(diǎn)(inode)管理文件控制信息,并且通過dir_entry結(jié)構(gòu)中的d_inode域指向文件的inode節(jié)點(diǎn),建立與文件索引節(jié)點(diǎn)的聯(lián)系。文件的索引節(jié)點(diǎn)(inode)結(jié)構(gòu)體包含了關(guān)于文件的組織信息和管理信息,根據(jù)其中的i_info查找存儲文件內(nèi)容的數(shù)據(jù)塊,根據(jù)i_op指向的inode_operations結(jié)構(gòu),通過其中的指針函數(shù)調(diào)用各自的inode操作函數(shù)。
系統(tǒng)進(jìn)程使用文件由表示進(jìn)程當(dāng)前打開的所有文件的數(shù)據(jù)結(jié)構(gòu)files_struct建立進(jìn)程與文件系統(tǒng)的關(guān)系。指針fd和fd_array都指向代表打開文件對象數(shù)組。進(jìn)程調(diào)用文件操作函數(shù),依據(jù)文件路徑打開文件,文件操作函數(shù)返回一整數(shù),即文件描述符,例如int open(const char*pathname,int flages)[2]。之后,進(jìn)程便用文件描述符來表示一個打開的文件,該整數(shù)文件描述符就是files_struct中file數(shù)組fd的下標(biāo)。
圖3描述了進(jìn)程使用文件時用到的VFS中主要數(shù)據(jù)結(jié)構(gòu)的關(guān)系。
圖3 VFS中主要數(shù)據(jù)結(jié)構(gòu)關(guān)系圖
dentry結(jié)構(gòu)描述的是邏輯意義上的文件,記錄的是其邏輯上的屬性。只要是有效的dentry結(jié)構(gòu),則其指針d_inode必定指向一個inode結(jié)構(gòu)。而inode結(jié)構(gòu)所代表的是物理意義上的文件,記錄的是其物理上的屬性。一個inode結(jié)構(gòu)可能對應(yīng)著不只一個dentry結(jié)構(gòu),因為一個物理意義上的文件可以被鏈接(link)其他路徑名。
所以,在inode結(jié)構(gòu)中有個隊列i_dentry,凡是代表著這個文件的所有目錄項(普通文件也是目錄文件的一種)都是通過dentry結(jié)構(gòu)中的d_alias掛入相應(yīng)的inode結(jié)構(gòu)中的i_dentry隊列。
本文主要從數(shù)據(jù)結(jié)構(gòu)的角度出發(fā),對Linux虛擬文件系統(tǒng)的實現(xiàn)技術(shù)作了簡要的分析。Linux系統(tǒng)把一切設(shè)備都作為文件看待,深入探究Linux虛擬文件系統(tǒng)的文件組織方式,可以為系統(tǒng)軟件設(shè)計和嵌入式Linux驅(qū)動開發(fā)提供一定參考價值。
[1]毛德操.Linux內(nèi)核源代碼情景分析(上)[M].杭州:浙江大學(xué)出版社,2009:428-430.
[2]韓超,魏治宇,寥文江.嵌入式linux上的C語言編程實踐[M].北京:電子工業(yè)出版社,2009:163-164.