Linux檔案系統淺析

來源:互聯網
上載者:User

Linux檔案系統淺析

 

作者:TP    撰寫日期:2011-09-20~ 2011-09-25

 

       自從上次面試中被問及設計一個檔案系統的問題後,我就一直糾結中。檔案到底有著什麼樣的資料結構去表現它們? 我們的作業系統是怎麼去管理他們? 前輩大俠們設計檔案系統的過程中有些什麼樣的思考,它又是怎麼一步步的演變成今天這樣一個穩定而伸縮性強的體繫結構的。

 

       在查看一段時間的資料後,對於檔案系統終於有了自己的一小點瞭解。在這裡寫出分享一下,還請大家不吝賜教。

 

       Linux 支援許多種檔案系統,從ext2,ext3到ntfs等等。但本文討論 Linux 核心中的虛擬檔案系統(VFS,有時候稱為虛擬檔案系統交換器),並介紹將檔案系統串連在一起的主要結構。

 

1.什麼是檔案系統

 

檔案系統是作業系統在電腦硬碟上儲存和檢索資料的邏輯方法,從本質上講是特殊的資料階層式存放區結構,它包含檔案、目錄和相關的控制資訊。

  

                                      圖 1.

       圖 1 所示的體繫結構顯示了使用者空間和核心中與檔案系統相關的主要組件之間的關係。VFS 是底層檔案系統的主要介面。這個組件匯出一組介面,然後將它們抽象到各個檔案系統,各個檔案系統的行為可能差異很大。有兩個針對檔案系統對象的緩衝(inode 和 dentry)。它們緩衝最近使用過的檔案系統對象。在這裡緩衝區快取和裝置驅動的互動、以及VFS提供的系統介面暫不討論,主要看看實現這個VFS子系統的主要結構。

 

2.檔案系統的主要結構

       VFS中主要有四個主要的物件類型,這些對象是超級塊(superblock)、索引節點inode、目錄項dentry 和檔案。超級塊代表這一個已經安裝的檔案系統,索引節點代表著檔案系統中的一個檔案。另一組結構稱為 dentry,它們用來實現名稱和 inode 之間的映射,有一個目錄緩衝用來儲存最近使用的 dentry。dentry 還維護目錄和檔案之間的關係,從而支援在檔案系統中移動。最後,VFS 檔案表示一個開啟的檔案(儲存開啟的檔案的狀態,比如寫位移量等等)。他們四者的關係可見圖2:

                   

 

圖2.

       從圖2我們可以看到,超級塊在每個檔案系統的根上,超級塊描述和維護檔案系統的狀態。檔案系統中管理的每個對象(檔案或目錄)在 Linux 中表示為一個 inode。而dentry是路徑的是指向inode的,它表現的是檔案名稱和inode的映射,同時,不同的檔案名稱可以映射到形同的inode。下面分別對這幾個對象做一下簡單的解釋:

 

a.目錄項對象 dentry: dentry的中文名稱是目錄項,是Linux檔案系統中某個索引節點(inode)的連結。這個索引節點可以是檔案,也可以是目錄。為了方便尋找操作,虛擬檔案系統引入的目錄項的概念。每個dentry代表路徑中的一個特定部分。對路徑/bin/vi來說,bin和vi都屬於目錄對象。前兩個是目錄,最後一個是普通檔案。又由於解析一個路徑並走查其分量是一個字串比較的過程,也是一個耗時的過程,檔案系統會引入目錄緩衝技術用於事先載入部分目錄到記憶體中。以下是dentry的結構體:

struct dentry {
atomic_t d_count; //目錄項對象使用計數器
unsigned int d_flags; //目錄項標誌
struct inode * d_inode; //與檔案名稱關聯的索引節點
struct dentry * d_parent; //父目錄的目錄項對象
struct list_head d_hash; //散列表表項的指標
struct list_head d_lru; //未使用鏈表的指標
struct list_head d_child; //父目錄中目錄項對象的鏈表的指標
struct list_head d_subdirs; //對目錄而言,表示子目錄目錄項對象的鏈表
struct list_head d_alias; //相關索引節點(別名)的鏈表
int d_mounted; //對於安裝點而言,表示被安裝檔案系統根項
struct qstr d_name; //檔案名稱
unsigned long d_time; /* used by d_revalidate */
struct dentry_operations *d_op; //目錄項方法
struct super_block * d_sb; //檔案的超級塊對象
vunsigned long d_vfs_flags;
void * d_fsdata; //與檔案系統相關的資料
unsigned char d_iname [DNAME_INLINE_LEN]; //存放短檔案名稱
};

在該結構體中,對以下幾個成員做一下說明,因為他們構成了目錄項的架構。

d_inode:它直接記錄了這個名稱有關的索引節點的指標。

d_parent:指向父親dentry

d_hash:散列表,同過他可以快速的將給定路徑解析為相關的目錄項對象

d_child:父目錄中目錄項對象的鏈表

d_ subdirs:子目錄

 

b.索引節點對象inode一個索引節點代表系統中的一個檔案,它包含了核心在操作檔案安或目錄需要的所有資訊。由於索引節點的資料結構比較龐大,這裡暫時對幾個主要的成員做解釋:

struct inode {
struct list_head i_hash; // 散列表
struct list_head i_list; // 索引節點鏈表
struct list_head i_dentry; // 目錄項鏈表
… …
struct inode_operations *i_op; // 索引節點動作表
… …
};

 

i_hash: Linux保留了活動索引節點以及最近使用索引節點的緩衝。可以通過兩種突擊訪問這些節點。第一種途徑是通過dcache。第二種途徑是通過索引節點散列表。每個索引節點都根據檔案系統超級塊的地址和索引節點號碼建立一個8位元字的散列。然後,具有相同散列值的資訊節點在一個雙重連結的列表中連結起來。這裡的ihash就是指這個散列表。

 

i_list: i_lish連結清單以不同的狀態連結資訊節點。包括:inode_in_use列表, inode_unused等。

 

i_dentry: identry列表是引用這個資訊節點的所有dentry結構的列表。即不同的檔案名稱或則路徑映射到了同一個檔案。

 

c.超級塊對象super_bolck超級塊結構表示一個檔案系統。它包含管理檔案系統所需的資訊,包括檔案系統名稱(比如 ext2)、檔案系統的大小和狀態、塊裝置的引用和中繼資料資訊(比如空閑列表等等)。超級塊通常儲存在儲存媒體上,但是如果超級塊不存在,也可以即時建立它。超級塊的資料結構在linux/fs.h中。建立、管理和銷毀超級塊對象的代碼在檔案fs/super.c中。超級塊對象通過alloc_super()函數建立並初始化。在檔案系統安裝時,核心會調用該函數以便從磁碟讀取檔案系統超級塊,並且講其資訊填充到記憶體中的超級塊對象中。

 

       不管怎樣,雖然對linux檔案系統的瞭解對現有工作沒有直接的關係。但我覺得它是一個可伸縮和可擴充的體繫結構的絕對經典執行個體。如果把Linux核心比作是程式員的經典原始碼名著,檔案系統結構絕對是不容錯過的章節。

 

參考文獻:《linux核心設計與實現》、《linux檔案系統》

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.