概述

Ext2文件系統將磁碟劃分為大小相等的邏輯塊進行管理,其默認大小是4KB(不做特殊說明,本文後續內容都採用該默認值)。文件系統邏輯塊的大小在格式化的時候可以指定的。文件系統將磁碟劃分為邏輯塊就好像一個大廈劃分為若干個房間,或者超市規劃為若干貨架一樣。同時為了便於管理和避免訪問衝突,其將若干個邏輯塊組成一個大的邏輯塊,稱為塊組(Block Group)。塊組是Ext2文件系統的管理單元,塊組中又包含若干管理數據(元數據)實現對塊組中的邏輯塊的管理,比如那些邏輯塊是什麼功能,那些邏輯塊已經被使用等等。

圖1 磁碟的塊組劃分

通過一個大廈對一個磁碟進行類比在形象不過了。大廈框架好比磁碟;而房間是對大廈規劃後的結果,好比對磁碟的格式化;大廈每層的佈局圖好比元數據。我們可以通過樓層和每層的佈局圖很容易的找到房間。文件系統與此類似,它通過元數據查找和管理邏輯塊。

如圖2是某貨架示意圖。每層都被劃分為不同的貨架,每個貨架都有編號,且防止固定類型的商品。比如有些放酸奶,有些放調料還有放奶粉等,並規劃。我們通過示意圖和房間號可以很容易找到具體位置。

圖2 超市貨架圖

如圖3是Ext2文件系統的磁碟佈局圖。如中間藍色為磁碟的邏輯空間,它被劃分為若干個塊組。每個塊組的大小相等。如果我們在格式化的時候採用的是默認參數,此時塊組的大小是128MB(後面介紹為什麼是128MB),每個邏輯塊的大小是4KB。

整體佈局

每個塊組內部都有相關的元數據對該塊組進行管理。如圖3所示,第一個塊組中的元數據包括引導塊、超級塊、塊組描述符、預留GDT塊、數據塊點陣圖、inode點陣圖、inode表和其它數據塊。後續塊組中有些是對超級塊的備份,有些則沒有第一個塊組這麼完整的元數據信息,而只有數據塊點陣圖、inode點陣圖和inode表等元數據信息。也就是說塊組其實分為兩種,一種是有超級塊的,比較複雜的塊組(如圖3下面淡棕色所示),另外一種是沒有超級塊的,比較簡單的塊組(如圖3上面淡綠色所示)。

圖3 塊組及內部細節

引導塊是作為引導操作系統用的,在文件系統作為根文件系統時使用。在系統加電啟動是,其內容有BIOS自動裝載並執行。它包含一個啟動裝載程序,用於從計算機安裝的操作系統中選擇一個啟動,還負責繼續啟動過程。因此Ext2文件系統把這個區域預留出來,不作為文件系統管理的磁碟區域。

超級塊是文件系統起始位置,用於整個文件系統,它作為文件系統的入口,記錄了整個文件系統的關鍵信息。而上面提到的其它元數據則只針對本塊組。下面本文介紹一下每個元數據的具體作用。

超級塊(SuperBlock)

超級塊記錄了整個文件系統的各種信息,包括邏輯塊的數量、inode數量、支持的特性和維護信息等內容。為了保證整個文件系統的完整性,例如突然斷電或者系統崩潰等場景,文件系統出現元數據損壞的情況,Ext2文件系統對超級塊進行了備份。這樣可以保證即使在第一個超級塊出現損壞的情況下,仍然可以通過其它塊組中的超級塊進行恢復,不至於整個文件系統都不可訪問。

超級塊位於第1個邏輯塊內,由於第一個塊組預留了1KB的內容作為系統引導,因此在該塊組超級塊的位置在1KB偏移處,而其它備份塊組中的超級塊都在該塊組偏移為0的地方。超級塊會佔用1個邏輯塊的空間(實際佔用空間要小於該值),也就是說塊組描述符(ext2_group_desc)是在4KB偏移的地方。如下代碼是超級塊在磁碟存放的結構體,磁碟數據被讀出來後按照該結構體的格式進行解析,其中變數__lexx表示變數是小端對齊,使用是需要轉換為CPU的對齊方式。在文件系統中還有另外一個結構體super_block,這個結構體用於代碼邏輯中使用。

struct ext2_super_block {
__le32 s_inodes_count; /* 整個文件系統inode的數量 */
__le32 s_blocks_count; /* 整個文件系統邏輯塊的數量 */
__le32 s_r_blocks_count; /* Reserved blocks count */
__le32 s_free_blocks_count; /* 文件系統剩餘邏輯塊的數量 */
__le32 s_free_inodes_count; /* 文件系統剩餘inode的數量 */
__le32 s_first_data_block; /* First Data Block */
__le32 s_log_block_size; /* Block size */
__le32 s_log_frag_size; /* Fragment size */
__le32 s_blocks_per_group; /* 每一個塊組中邏輯塊的數量 */
__le32 s_frags_per_group; /* # Fragments per group */
__le32 s_inodes_per_group; /* 每一個塊組中inode的數量 */
__le32 s_mtime; /* 掛載時間 */
__le32 s_wtime; /* 寫時間 */
__le16 s_mnt_count; /* 掛載數量 */
__le16 s_max_mnt_count; /* Maximal mount count */
__le16 s_magic; /* Magic signature */
__le16 s_state; /* File system state */
__le16 s_errors; /* Behaviour when detecting errors */
__le16 s_minor_rev_level; /* minor revision level */
__le32 s_lastcheck; /* time of last check */
__le32 s_checkinterval; /* max. time between checks */
__le32 s_creator_os; /* OS */
__le32 s_rev_level; /* Revision level */
__le16 s_def_resuid; /* Default uid for reserved blocks */
__le16 s_def_resgid; /* Default gid for reserved blocks */
__le32 s_first_ino; /* 第一個非保留inode的id,ext2有一些保留的inode,比如2用於根目錄 */
__le16 s_inode_size; /* inode結構體的大小 */
__le16 s_block_group_nr; /* 本超級塊所位於的塊組的編號 */
__le32 s_feature_compat; /* compatible feature set */
__le32 s_feature_incompat; /* incompatible feature set */
__le32 s_feature_ro_compat; /* readonly-compatible feature set */
__u8 s_uuid[16]; /* 128-bit uuid for volume */
char s_volume_name[16]; /* volume name */
char s_last_mounted[64]; /* directory where last mounted */
__le32 s_algorithm_usage_bitmap; /* For compression */
/*
* Performance hints. Directory preallocation should only
* happen if the EXT2_COMPAT_PREALLOC flag is on.
*/
__u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
__u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
__u16 s_padding1;
... ...
};

塊組描述符

塊組描述符,顧名思義是對該塊組的描述,其中包括該塊組中數據塊點陣圖的位置、inode點陣圖位置和inode表位置等信息。另外,還包括數據塊和inode的剩餘情況等信息。塊組描述符位於第2個邏輯塊,佔用一個邏輯塊的空間。

struct ext2_group_desc
{
__le32 bg_block_bitmap; /* Blocks bitmap block */
__le32 bg_inode_bitmap; /* Inodes bitmap block */
__le32 bg_inode_table; /* Inodes table block */
__le16 bg_free_blocks_count; /* Free blocks count */
__le16 bg_free_inodes_count; /* Free inodes count */
__le16 bg_used_dirs_count; /* Directories count */
__le16 bg_pad;
__le32 bg_reserved[3];
};

數據塊點陣圖

數據塊點陣圖標識了塊組中那個數據塊被使用了,那個沒有被使用。磁碟中每個被管理的邏輯塊在該點陣圖中用1bit進行表示,0為未使用,1為已經使用。數據塊點陣圖佔用1個邏輯塊,對於默認塊大小(4KB)情況,可以管理40968個邏輯塊,也即40968*4096=128MB的空間。當然如果格式化的時候塊大小為8KB,則管理的空間會更大一些。

inode點陣圖

inode點陣圖與邏輯塊點陣圖類似,描述inode的使用情況。inode用於唯一標識一個文件,其為一個編號。文件系統根據這個編號查找具體的問題。在inode點陣圖中每一位標識inode表中的個inode是否被使用。關於什麼是inode表,請參考下面的描述。

默認情況inode點陣圖佔用的空間也為4KB。

inode表

inode表一列表的形式保存了文件的元數據信息,包括文件大小、擴展屬性和時間等內容。由於inode結構的大小根據格式化文件系統的屬性而有差異,因此該表佔用的磁碟空間不定,大概若干個邏輯塊的大小。關於文件名稱與inode數據結構的關係是通過inode的id確定的,在文件夾中的文件存儲包含文件名和inode的id信息,而通過該id可以計算出inode數據結構位於的塊組位置和inode表位置。

本文簡要介紹一下Ext4文件系統的磁碟佈局情況,後續會更加詳細的介紹每一部分的細節。

關注作者微信公眾號, 及時獲取更新, itworld123


推薦閱讀:
相關文章