EXT2 文件系統
對文件系統而言,文件僅是一系列可讀寫的數據塊。文件系統並不需要了解數據塊應該放到物理介質上什麽位置。這些都是設備驅動的任務。無論何時,只要文件系統需要從包含它的塊設備中讀取信息或數據,它就將請求底層的設備驅動讀取一個基本塊大小整數倍的數據塊。EXT2文件系統將它所使用的邏輯分區劃分成數據塊組。每個數據塊組都將那些對文件系統完整性最重要的信息復制出來,同時將實際文件盒目錄看做信息與數據塊。
羅即文件系統管理的是一個邏輯空間,這個邏輯空間就像一個大的數組,數組的每個元素就是文件系統操作的基本單位——邏輯塊。邏輯塊是從0開始編號的,而且,邏輯塊是連續的,邏輯塊相對的是物理塊。通常,EXT2的物理塊占一個或幾個連續的扇區。
一般而言,只有塊組0的超級塊才讀入內存,其他塊組的超級塊僅僅作為備份。在系統運行期間,要將超級塊復制到內存系統緩沖區。
塊位圖和節點位圖
在EXT2文件系統中,采用位圖描述數據塊和索引節點的使用情況,每個塊組中占用兩個塊,即一個用來描述該數據塊的使用情況,另一個描述該組索引節點的使用情況。這兩個塊分別稱為數據位圖塊和索引節點位圖塊。數據位圖塊中的每一位表示該塊組中的每一個塊的使用情況,如果為0,則表示相應數據塊空閑,如果是1,則表示已分配。
索引節點表
每個塊組中的索引節點都存儲在各自的索引節點表中,並且按索引節點號依次存儲。索引節點表通常占好幾個數據塊,索引節點表所占的塊使用時也想普通的數據塊一樣被調入塊高速緩存。
EXT2整個磁盤的邏輯結構如圖所示:
EXT2文件系統的幾個數據結構
1 EXT2超級塊
超級塊中包含了描述文件系統基本尺寸和形態的信息。文件系統管理器利用他們來使用和維護文件系統。EXT2超級塊是用來描述EXT2文件系統整體信息的數據結構,是EXT2的核心所在。超級塊經函數ext2_fill_supter讀入後,又在內存中建立一個映像super_block.u.ext2_sb_info結構。
結構ext2_super_block列出如下:
邏輯塊是從0開始編號的,對塊大小為1KB的文件系統,s_first_data_block為1,對其他文件系統,則為0.
2 EXT2超級塊信息結構
EXT2超級塊被讀入內存後,主要用於填寫VFS的超級塊。此外,它還要填寫另外一個結構ext2_super_info。結構ext2_super_info描述了EXT2文件系統特定的信息。之所以要用到這個結構,是因為VFS的超級塊必須兼容各種文件系統的不同的超級塊結構,因此每個文件系統超級塊特定的特性必須用另一個結構保存於內存中,以加快對文件的操作。EXT2超級塊與VFS超級塊的關系如圖所示:
結構ext2_super_info列出如下:
3 超級塊的操作函數結構
超級塊的操作函數結構如下所示:
4 EXT2的索引節點inode
在EXT2文件系統中每個文件與目錄由惟一的inode來描述。每個數據塊組的EXT2 inode被保存在inode表中,同時還有一個位圖被系統用來跟蹤已分配和未分配的inode。
EXT2文件系統使用索引節點來記錄文件信息。每個普通文件盒目錄都有惟一的索引節點與之對應,索引節點中含有文件或目錄的重要信息。當你要訪問一個文件或目錄時,通過文件或目錄名首先找到與之對應的索引節點,然後通過索引節點得到文件或目錄的信息及磁盤上的具體的存儲位置。
EXT2在硬盤上的索引節點的數據結構如下:
EXT2通過索引節點中的數據塊指針數組進行邏輯塊到物理塊的映射。在EXT2索引節點中,數據塊中數組共有15項,前12個為直接指針,後三個分別為“一次間接指針”、“二次間接指針”、“三次間接指針”,EXT2默認的物理塊大小為1KB,塊地址占4個字節,所以每個物理塊可以存儲256個地址。這樣,文件大小最大可達12KB+256KB+64MB+16GB。但實際上,Linux是32位系統,故文件大小最大只能為4GB,及整個文件系統都被一個文件所占用。索引節點的物理塊指針數組如圖所示:
系統是以邏輯塊號為索引查找物理塊的。例如,要找到第100個邏輯塊對應的物理塊,因為256+12>100>12,所以要用到一次間接塊,在一次間接塊中查找第88項,此項內容就是對應的物理塊的地址。
節點在磁盤上是經過編號的。其中,有一些節點有特殊用途,用戶不能使用。這些特殊節點定義為:
5 EXT2文件系統的節點信息結構
與EXT2超級塊類似,當磁盤上的索引節點調入內存後,除了要填寫VFS的索引節點外,系統還要根據它填寫另一個數據結構ext2_inode_info,其作用也是為了存儲特定文件系統自己的特性。
結構ext2_inode_info分析如下:
VFS索引節點中沒有物理塊指針數組的域,這個EXT2特有的信息在調入內存後,就必須保持在ext2_inode_info這個結構中。
6 節點操作函數結構
7 文件操作函數結構
8 EXT2文件系統的組描述符
在塊組中緊跟著超級塊後面的塊是組描述符,在start_sect+block_size*2位置上。乘以2的原因是block_size是KByte為單位,我們用扇區訪問。組描述符表每一項為組描述符,是一個叫ext2_group_desc的數據結構,供32字節。它用來描述某個塊組的整體信息。
找到了組描述符,可得到很多信息,如該組塊組位圖的位置,該組塊inode位圖位置,該組塊inode表的位置等。
組描述符的定義如下:
EXT2 文件系統建立過程
在 函數init_ext2_fs註冊了EXT2文件系統,函數分析如下:
文件系統實例ext2_fs_type列出如下:
函數ext2_get_sb打開塊設備,得到超級塊,將這個超級塊加到全局super_blocks鏈表中,並掛接文件系統。函數ext2_get_sb列出如下:
函數ext2_fill_super從硬盤中讀出超級塊數據並填充超級塊結構。
超級塊操作函數集實例ext2_sops列出如下:
文件的讀寫
文件的讀寫操作都調用到具體文件系統的讀寫操作函數結構,這裏即調用到EXT2文件系統的ext2_file_operations結構,得到具體的操作函數。
下圖為read系統調用的操作函數層次圖,可見EXT2文件系統的讀操作最終調用ext2_readpage函數完成,對於文件讀操作過程中的文件對內存的映射過程。
結構ext2_file_operations是EXT2文件系統對於文件的操作函數集,列出如下:
ext2_aops結構是EXT2 文件系統中具體操作實現函數集,它被ext2_file_operations結構的函數所調用。列出如下:
ext2_aops結構中的這些函數列出如下:
這些函數除了調用的ext2_get_block函數是EXT2文件系統特有的外,其他都是fs/buffer.c中的函數。
ext2_get_block()將對文件系統的邏輯塊號轉換為塊設備的邏輯塊號。這種轉化關系是由ext2_inode結構中i_block[]數組描述的i_block[]的前12項為直接索引表,第13項為間接索引塊指針,第14項為二重索引塊指針,第15項為三重索引塊指針。當文件長度不超過12個塊時,可通過直接塊索引表直接定位目標塊;當文件長度超過12塊,並且剩余的部分不超過間接塊索引數量時,就在間接塊索引塊中定位目標塊,依次類推。
函數ext2_get_block功能是從邏輯塊序號得到對應物理塊。若對應物理塊被刪除,則重新分配,並得到它間接塊路徑。
函數ext2_get_block具體分析如下:
系統是以邏輯塊號為索引查找物理塊的。例如,要找到第100個邏輯塊對應的物理塊,因為256+12>100>12,所以要用到一次間接塊,在一次間接塊中查找第88項,此項內容就是對應的物理塊的地址。
函數ext2_get_branch從物理塊中讀取數據到chain的buffer中,函數的參數說明如下:
- inode 操作的節點
- depth 間接塊的深度
- offset 間接物理塊的指針數組
- chain 存儲讀取物理塊的數據
- 存儲錯誤標誌
函數ext2_get_branch的功能是填充Indirect結構的數組,如果運行正常,則返回NULL。函數分析如下:
函數ext2_alloc_branch分配並建立一個塊鏈表,其中參數inode表示需分配塊的節點,參數num表示間接塊的深度,參數offsets是一個數組,即offsets[num],參數branch是存儲鏈表的地方。函數分析如下:
文件擴展時的數據塊分配策略
文件系統普遍存在的一個問題是碎片化,即一個文件所包含的數據塊遍布整個文件系統,這使得對文件數據塊的順序訪問越來越慢。EXT2文件系統試圖通過分配一個和當前文件數據塊在物理位置上鄰接,或者至少位於同一個數據塊組中的新塊來解決這個問題。
EXT2的目錄項及文件的定位
在EXT2中,目錄是一種特殊的文件,它是由ext2_dir_entry結構組成的列表。為了減少磁盤空間的浪費,這個結構是可變長的。但是,它還有一定的長度方面的限制:一是文件名最長只能為255個字符;二是盡管文件名長度可以不限,但系統自動將之變成4的整數倍,不足的地方用0填充。
鏈接文件
EXT2把文件名和文件信息分開存儲,其中文件信息用索引節點來描述,目錄項是用來聯系文件名和索引節點的。目錄項中,每一對文件名和索引節點號的一個一一對應稱為一個鏈接,這就是說,同一個索引節點表可以對應多個不同的文件名。這種鏈接稱為硬鏈接。可以用ln命令為一個已存在的文件建立一個新的硬鏈接:
ln /home/cyf/file1 /home/cyf/file2
建立了一個文件file2,鏈接到file1上。file2和file1有相同的索引節點號,也就是和file1共享同一個索引節點。在建立了一個新的硬鏈接後,這個索引節點中的i_links_count值將加1,i_links_count的值反映了鏈接到這個索引節點上的文件數。
使用硬鏈接的好處在於:
1)由於刪除文件時,實際上先對i_links_count做減1,如果i_links_count不為0,則結束,即僅僅刪除了一個硬鏈接,實際文件的數據並沒有刪除。只有在i_links_count為0時,真正將文件從磁盤上刪除。這樣,你可以對重要的文件作多個鏈接,防止文件被刪除。
2)允許用戶在不進入某個目錄的情況下對該目錄下面的文件進行處理。
符號鏈接與硬鏈接最大的不同就在於它並不與索引節點建立鏈接,也就是說,當為一個文件建立一個符號鏈接時,索引節點的鏈接計數並不變化。當你刪除一個文件時,它的符號鏈接文件也就失去了作用,而當你刪除一個文件的符號鏈接文件,對該文件本身並無影響。
EXT2 文件系統