1. 程式人生 > 其它 >檔案系統2:EXT

檔案系統2:EXT

EXT主要有EXT2,EXT3,EXT4,主要介紹EXT2與EXT4。由於時間倉促,很多自己也不理解,可能有很多錯誤。

基本概念

首先介紹EXT中的基本概念:

  • 塊:EXT用塊管理分割槽空間,每一個塊所佔大小,常見的有1KB,2KB,4KB,8KB
  • 塊組:幾個塊又被組成一個塊組進行管理,一個塊組含有的塊的數量是塊大小的8倍,因為塊點陣圖(之後介紹)佔一個塊,其中每一個位元對應一個塊,所以如果一個塊大小為1KB,那麼一個塊組有1K*8=8192個塊

檔案儲存分配方式

在之前FAT檔案系統中介紹檔案的儲存位置是通過FAT表和連結的方式來實現的,如下所示

而EXT採用的是節點表和索引式的方式來實現,即通過節點表將檔案所佔據的塊記錄下來,如下所示(當然實際不如下面這麼簡單,而且也不準確,只是說明這種思想,實際的更多細節可以看之後的內容)

其中節點表中一個檔案的塊的地址分為直接地址,一級索引,二級索引,三級索引,如下所示:

  • 直接地址即所指向的塊儲存的就是檔案資料
  • 一級索引即所指向的塊儲存的是塊的地址,如圖中一級索引指向22號塊,22號塊中儲存的是塊的地址,其中指向的塊有24,25等,而24指向的塊才儲存著檔案的資料
  • 其它型別的索引類似

並不完全準確大致思想如下:

硬連結與軟連線

在下面節點表會提到硬連結數,所以介紹一下。如下圖所示,檔案a,b,c都是圖中最右上角的檔案,但是b是採用硬連結的方式,直接指向了檔案對應的節點4的地址,所以節點4的硬連線數為2。
而c採用軟連線的方式,指向了一個儲存最右上角的檔案地址的檔案,這類似於windows中的快捷方式。

EXT2

以每塊佔1KB為例,EXT2的結構如下所示:

  • 超塊:包含重要的資訊,包括檔案系統中節點和塊的總數和空閒的數量,每個塊組中節點和塊的數量等
  • 塊組描述表GDT:定義所有塊組的引數,包括塊點陣圖,節點點陣圖,節點表的位置,空閒塊,節點數量等
  • 超塊備份和塊組描述表備份:因為超塊比較重要,所以起初,每個塊組都儲存一個超塊和塊組描述表的備份,但是會佔用太多空間,所以改為只在組為0,1,3,5,7的冪的組才新增備份。
  • 塊點陣圖與節點點陣圖之後介紹

注意:

  • 0號塊不屬於任何一個塊組
  • 引導扇區始終佔1024個位元組,超塊始終佔1024個位元組,又因為圖中以每塊佔1KB為例,所以圖中引導扇區佔block0,超塊佔block1,但是如果每塊佔2KB,那麼引導扇區和超塊就會一起佔block0。
  • 塊組描述表在超塊後的第一個塊,可能不止佔圖中所示的一個塊,可能佔多個塊

超塊

偏移 意義
0-3 檔案系統的節點總數,小於等於每組節點數*組數
4-7 檔案系統的塊總數,小於等於每組塊數*組數
8-B 專門為超級使用者保留的塊的總數
C-F 所有空閒塊的總數
10-13 所有空閒節點的總數
14-17 第一個塊,也就是包含超塊的ID,值為0或1
18-1B 塊的大小,2^(10+值)
1C-1F 簇大小,2^(10+值)
20-23 每組的塊數,最後一個組可能不夠
24-27 每組簇數
28-2B 每組節點數,小於等於塊大小除以節點大小。節點表佔一個塊,所以應該使節點表能夠記錄所有的節點,同時節點對應組中的塊的數量,應該使節點數與塊數達到一個平衡
2C-2F 檔案系統被裝入的最後時間
30-33 檔案系統被訪問的最後時間
34-35 檔案系統被裝入的次數
36-37 在驗證檔案系統前,可裝入檔案系統的最大次數
38-39 檔案系統標識,EXT2為EF53
3A-3B 檔案系統狀態,如果為1,表示檔案系統未被裝入,為2,表示檔案系統被裝入
3C-3D 檢測到錯誤時檔案系統應該進行的操作
3E-3F 標識其版本的二級版本
40-43 最後一次檔案系統檢查時間
44-47 最多多長時間進行一次檔案系統檢查
48-4B 建立檔案系統的作業系統的標識,0:linux,1:gnu hurd,2:masix,3:freebsd,4:lites
4C-4F 版本值,版本1具有可變的節點大小等特徵
50-51 使用保留快的使用者ID
52-53 使用保留塊的使用者組ID
54-57 用作標準檔案(即不是目錄等的普通檔案)的第一個節點號,版本0的預設值為11,其它版本可以修改
58-59 節點的大小,在版本0中,值為128B,在其它版本中,值必須為2的冪次,且小於等於塊的大小
5A-5B 超塊所在組號
5C-5F 版本EXT2,3,4相容的功能的掩碼,檔案系統支不支援都不影響,具體見文件
60-63 版本EXT2,3,4不相容的功能的掩碼,檔案系統不支援就無法裝入檔案系統,具體見文件
64-67 只讀功能掩碼,如果掩碼所示功能檔案系統不支援,就以只讀方式裝入檔案系統,具體見文件
68-77 卷ID,值唯一
78-87 卷名
88-C7 上次裝入檔案系統的目錄路徑
C8-CB 壓縮演算法
CC 建立檔案時應預先分配的塊數
CD 建立目錄時應預先分配的塊數
CE-CF 保留的描述表塊數
D0-DF 包含日誌超塊的ID,EXT3中的日誌功能
E0-E3 日誌檔案的索引節點號,EXT3中的日誌功能
E4-E7 日誌檔案的索引號,EXT3中的日誌功能
E8-EB 要刪除的節點列表中的第一個節點,EXT3中的日誌功能
EC-FB 4個32位的用於目錄索引的雜湊演算法的種子
FC 預設用於目錄索引的雜湊演算法版本
FD-FF 填充
100-103 預設檔案系統裝載選項
104-107 第一個元塊組的塊組ID
108-3FF 保留

本次以下面磁碟為例,其中主分割槽為EXT2

首先,找到磁碟MBR中分割槽表,得到主分割槽在磁碟2048扇區處,然後前1024B為引導扇區,這裡引導扇區內容為空,之後2050扇區即為超塊,如下所示

對應意義如下

偏移 意義
0-3 檔案系統的節點總數為00 01 E6 50即124496
4-7 檔案系統的塊總數00 03 CC 00即248832
8-B 專門為超級使用者保留的塊的總數00 00 30 99即12441
C-F 所有空閒塊的總數00 03 40 F5即213237
10-13 所有空閒節點的總數7E E5 01 00即124286
14-17 值為1,包含超塊的塊在塊1中
20-23 每組的塊數00 00 20 00即8192
24-27 每組簇數00 00 20 00即8192
28-2B 每組節點數B0 0F 00 00即4016
38-39 檔案系統標識EF 53為EXT2
4C-4F 修訂版本值00 00 00 01即版本為1
54-57 用作標準檔案(即不是目錄等的普通檔案)的第一個節點號00 00 00 0B即為11
58-59 節點的大小00 80即128B
5A-5B 超塊所在組號00 00即塊組0

塊組描述表

塊組描述表表示檔案系統中所有塊組的資訊,其中每32個位元組表示一個塊組的資訊,這32個位元組的結構資訊如下

偏移 意義
0-3 該組塊中的塊點陣圖的第一個塊號
4-7 該組塊中的節點點陣圖的第一個塊號
8-B 該組塊中的節點表的第一個塊號
C-D 該組塊中空閒塊總數
E-F 該組塊的空閒節點總數
10-11 該組分配給目錄的節點數
12-1F 保留填充

超塊的下一個塊為塊組描述表,這裡一個塊是1024B,就是兩個扇區,而超塊在2050扇區,所以塊組描述表在2052扇區,以下為塊組描述表的部分資料

只看第一個塊組也就是塊組0的資訊,即前32位

偏移 意義
0-3 該組塊中的塊點陣圖的第一個塊號00 00 00 03即3,也就是該組塊中的塊點陣圖在塊3
4-7 該組塊中的節點點陣圖的第一個塊號00 00 00 04即4,也就是該組塊中的節點點陣圖在塊4
8-B 該組塊中的節點表的第一個塊號00 00 00 05即5,也就是該組塊中的節點表是從塊5開始的
C-D 該組塊中空閒塊總數0A B1,即2737
E-F 該組塊的空閒節點總數0F 9D即3997
10-11 該組分配給目錄的節點數00 02即2

塊點陣圖

每一位表示一個塊是否被使用,1表示已用,0表示未用,第一個塊(編號為0)由0位元組的0位表示,第九個塊由1位元組的0位表示。塊3中的塊點陣圖如下

節點點陣圖

每一位表示一個節點是否被使用,編號從1開始,所以第一個節點(編號為1)由0位元組的0位表示。保留的節點在初始化時都會被標記為已使用(前幾個節點是被保留的,版本0為11節點,其它版本要看設定為多少,在超塊的偏移54-57處已經確定)。塊4中的節點點陣圖如下

節點表

節點表儲存了各種各樣檔案的位置,大小,型別和訪問許可權,但不儲存檔名,檔名只儲存在目錄中。節點表中每128B表示一個節點項,節點表中前幾個項是被保留的(版本0為11個項,其它版本要看設定為多少,在超塊的偏移54-57已經確定,這11箇中第1個是用作壞塊的節點,第2個:根目錄節點,第3,4個:根訪問控制相關,第5:引導載入程式節點,第6:未刪除目錄節點)。每一個節點項結構如下:

偏移 意義
0-1 該檔案的格式和訪問許可權,各值的含義見下圖,該偏移處的值可以是下圖中任意值的組合
偏移 意義
2-3 與檔案關聯的使用者ID
4-7 版本0中這32位(有符號的)表示檔案的大小(單位為位元組),在其它版本表示檔案大小的低32位
8-B 上次訪問該節點的時間(從1970.1.1以來的秒數)
C-F 建立節點的時間(從1970.1.1以來的秒數)
10-13 上次修改節點的時間(從1970.1.1以來的秒數)
14-17 刪除節點的時間(從1970.1.1以來的秒數)
18-19 有權訪問此檔案的使用者組
1A-1B 該節點的硬連結數
1C-1F 保留的用於包含此節點資料的512B的塊的總數
20-23 訪問此節點時EXT2的行為,如下圖,其中如果值為EXT2_INDEX_FL,表示這個節點指向目錄,且目錄時索引格式


偏移 意義
24-27 與作業系統相關的值
28-63 每32位為一個塊號,共15個塊。前12個是直接地址,第13個是一級索引,14,15類推
64-67 檔案版本
68-6B 包含擴充套件屬性的塊編號,版本0的塊是沒有擴充套件屬性的,所以值為0
6C-6F 版本0的此值始終為0,其它版本表示檔案大小的高32位
70-73 檔案段的位置
74-7F 作業系統的相關結構,具體見文件

塊5中的節點表如下:
前11個為保留的節點,所以以下是節點表中保留的項的部分資料。

其中第二個節點,也就是根目錄節點分析如下:

偏移 意義
0-1 該檔案的格式和訪問許可權ED 41,即對照上圖中的值可以確定其為drwxr-xr-x,分析ED 41小端儲存,實際為41 ED,對照表中4000為目錄,所以為d,表中100為使用者可讀,所以為r,表中使用者可寫,使用者可執行,組可讀為80,40,20,加起來為E0,所以為wxr,表中使用者可執行,其他人可讀,其他人可執行為8,4,1,加起來為D,綜合起來確定了該檔案的屬性
2-3 與檔案關聯的使用者ID00 00
4-7 因為在前面知道是版本1,所以表示檔案大小的低32位00 00 00 04
18-19 有權訪問此檔案的使用者組00 00
1A-1B 該節點的硬連結數00 04即4
1C-1F 保留的用於包含此節點資料的512B的塊的總數00 00 00 02即2
28-63 只有一個包含節點資料的塊的塊號00 00 FB 01即507
6C-6F 檔案大小的高32位00 00 00 00,綜合低位的00 00 00 04知檔案4B大小

目錄

目錄有其特定的格式。目錄分為鏈目錄格式與索引目錄格式,在檔案多的時候索引目錄格式查詢檔案更快,在節點表的偏移20-23處表明了格式。

連結串列目錄格式

偏移 意義
0-3 檔案的節點號,如果值為零,表示這一項沒有被使用
4-5 從當前目錄項的開頭到下一個目錄項的16位無符號移位,即目錄項的長度。此欄位的值必須至少等於當前項的長度。目錄項必須在4位元組邊界上對齊,並且不能有任何跨越多個數據塊的目錄項。如果一個項不能完全放入一個數據塊,則必須將其推送到下一個資料塊,並正確調整前一條項的記錄。
6 檔名多少位元組的長度
7 檔案型別,0:不明型別,1:常規檔案,2:目錄,3:字元裝置,4:塊裝置,5:快取檔案,6:套接字檔案,7:連結檔案
8-(取決於檔名長度和邊界對其的要求) 檔名

結合例子介紹,在上面的節點表中我們知道一個目錄在507塊,也就是在扇區2048+507*2=3062,其中2048是分割槽的起始扇區(其實2048-2049為塊0,而507塊是塊本身,所以扇區為2050+2*(507-1)),其資料如下

開始為當前目錄項

偏移 意義
0-3 檔案節點號為2,由上可知,該目錄確實存在2節點
4-5 目錄項的長度為12
6 檔案包1B長
7 值為2表示為目錄
8-B 檔名為.

下一項為其父目錄項,由上知前一項錄項長度為12,所以下一項從偏移C處開始

偏移 意義
0-3 檔案節點號為2
4-5 目錄項的長度為12
6 檔名2B長
7 值為2表示目錄
8-B 檔名為..

其餘項就是該目錄下的檔案的項了

索引目錄格式

使用雜湊樹來組織和查詢目錄項。為了與連結串列目錄格式相容,在前面一塊放置一個連結串列目錄格式的資料塊,下一個資料塊才為索引目錄格式塊。當索引目錄項超過一個數據塊可容納的數時,將建立間接索引,即分配給該目錄另一個數據塊。關於此格式的更多原理見文件

首先是索引根目錄項結構

偏移 意義
0-3 當前目錄節點
4-5 當前項長度
6 名字長度,單位B
7 檔案型別,為2,也就是目錄型別
8 檔名.
9-B 填充
C-F 當前目錄節點
10-11 當前項長度
12 名字長度,單位B
13 檔案型別,為2,也就是目錄型別
14-15 檔名..
16-17 填充
18-1B 保留
1C 雜湊版本
1D 索引目錄資訊長度,這裡索引目錄資訊就是偏移18-1F的值
1E 索引目錄間接索引數
1F 保留

之後是索引目錄項,第一個索引目錄項如下:

偏移 意義
0-1 塊中所能容納索引目錄項的最大數量
2-3 現在已容納的索引目錄項的數量

之後的索引目錄項結構如下

偏移 意義
0-3 目錄名的雜湊值
4-7 目錄節點的塊號

EXT4

相比於EXT2,在EXT4中可以將幾個塊組作為一個邏輯塊組繫結在一起,稱為元塊組,其它塊組的節點點陣圖,塊點陣圖都可以統一放在一起。以下主要介紹EXT4中格式與EXT2不一樣的地方

超塊

與EXT2相比在以下偏移處不同

偏移 意義
FD 不明白
FE-FF 塊組描述符的大小
100-103 預設檔案系統裝載選項,詳細見文件
104-107 第一個元塊組的塊組ID
108-10B 檔案系統建立時間(從1970.1.1以來的秒數)
10C-14F 日誌節點的備份
150-153 塊總數的高32位
154-157 保留的塊數的高32位
158-15B 空閒的塊數的高32位
15C-15D 節點(因為對節點進行了擴充套件)額外至少有多少位元組
15E-15F 節點額外應該保留多少位元組
160-163 標誌,是這些的組合,0001:使用簽名雜湊目錄,0002:使用未簽名雜湊目錄,0004:測試程式碼
164-165 移動到讀取下一個磁碟之前從磁碟讀取或寫入磁碟的邏輯塊數
166-167 防止檔案系統多次掛載
168-169 多掛載保護資料的塊編號
170-173 返回到當前磁碟之前從磁碟讀取或寫入磁碟的邏輯塊數
174 元陣列的大小,值為2^該值
175 元資料校驗和演算法型別,值為1指crc32c演算法
176-177 保留
178-179 檔案系統執行期間,寫入的KB數
180-183 活動快照的節點號
184-187 活動快照的序列ID
188-189 為活動快照將來使用而保留的塊數
190-193 磁碟快照列表的頭的塊號
194-197 錯誤數
198-19B 第一次發生錯誤的時間(從1970.1.1以來的秒數)
19C-19F 第一次錯誤涉及的節點
1A0-1A7 第一次錯誤涉及的塊數
1A8-1C7 發生錯誤的函式名字
1C8-1CB 發生錯誤的行號
1CC-1CF 最近錯誤的時間(從1970.1.1以來的秒數)
1D0-1D3 最近錯誤涉及的節點
1D4-1D7 最近錯誤的行號
1D8-1DF 最近錯誤涉及的塊數
1E0-1EF 最近錯誤的函式名字
200-23F ASCIIZ掛載選項字串
240-243 使用者配額檔案的節點數
244-247 組配額檔案的節點數
248-24B 檔案系統中開銷塊或簇
24C-253 包含超塊備份的塊組,每32位為一組
254-257 使用的加密演算法,0:不使用,1:XTS的256b的AES,2:GCM的256b的AES,3:CBC的256b的AES
258-267 用於加密的string2key演算法的鹽值
268-26B lost+found檔案的節點數
26C-26F Inode that tracks project quotas
270-273 用於元資料校驗和計算的種子,值為crc32c
274-3FB 保留
3FC-3FF 超塊校驗和

本次以下面磁碟為例,其中root為EXT4

首先在偏移1024B處找到超塊,如下所示,這裡就不一一分析了,直接使用軟體自動分析。
在偏移18處可以看到塊的大小,為2^(10+2),即4K

塊組描述表

塊組描述表中每一項與EXT2相比,有32B版本和64B版本,32B是EXT2中的擴充套件

偏移 意義
0-3 塊點陣圖的低32位
4-7 節點點陣圖的低32位
8-B 節點表的低32位
C-D 空閒塊數的低32位
E-F 空閒節點的低32位
10-11 目錄數量的低32位
12-13 塊組標誌,這些值的任意組合,1:節點表和點陣圖未初始化,2:塊點陣圖未初始化,4:節點表被清零
14-17 快照點陣圖的低32位
18-19 塊點陣圖校驗和的低32位
1A-1B 節點點陣圖校驗和的低32位
1C-1D 未使用的節點數的低32位
1E-1F 組描述符校驗和

以上為32B版本,64B版本加上下面的內容

偏移 意義
20-23 塊點陣圖的高32位
24-27 節點點陣圖的高32位
28-2B 節點表的高32位
2C-2D 空閒塊數的高32位
2E-2F 空閒節點的高32位
30-31 目錄數量的高32位
32-33 未使用的節點數的高32位
34-37 快照點陣圖的高32位
38-39 塊點陣圖校驗和的高32位
3A-3B 節點點陣圖校驗和的高32位
3C-3F 保留

由超塊知一個塊佔4K,所以塊組描述符在扇區8,即超塊的下一塊中。這裡只看第一個塊組項,可知該塊組的塊點陣圖在1025*8(因為一個塊4K,佔8個扇區)處,節點點陣圖在1041*8處,節點表在1057*8處。

節點表

相比於EXT2,增加了如下欄位

偏移 意義
80-81 節點大小(超出原始128B的部分),在ext2和ext3中節點大小為128B,超出的部分記錄在這個欄位
82-83 節點校驗和的高16位
84-87 額外的更改時間
88-8B 額外的修改時間
8C-8F 額外的訪問時間
90-93 檔案建立時間
94-97 額外的檔案建立時間
98-9B 版本號的高32位
9C-9F 專案ID

extent tree

並且在偏移28-63處不再使用直接地址,一級索引這樣的方式找塊號(在EXT2和EXT3中使用),而改用擴充套件樹extent tree結構,其結構如下,偏移為偏移28-63處內部的相對偏移,開始12個位元組為樹結構的頭

偏移 意義
0-1 標記,為F3 0A
2-3 樹頭後的有效項數
4-5 樹頭後面可以有的最大項數
6-7 樹的深度,最大為5,為0則表明,每一項直接指向資料塊
8-B 樹的生成

樹頭之後,跟著每一項,每一項的結構如下

偏移 意義
0-3 該樹覆蓋的範圍中第一個檔案的塊號
4-5 樹覆蓋的範圍所佔總塊數
6-7 此項指向的塊號的高16位
8-B 此項指向的塊號的低32位

日誌

為了防止系統崩潰導致資料前後不一致,從EXT3引入日誌系統,都按大端儲存

在超塊中可以知道日誌節點在8號節點(11個保留節點中從0開始編號,但是第0個不存在,所以8號實際上還是第8個節點)。
通過塊組描述表知道節點表在1057*8處。
在節點表,找到第8個節點,如下圖所示紅框處。
在第8個節點,通過extent tree的結構中第一項8-B偏移處的塊號的低32位(紅線處),知道日誌在2129920塊處,即2129920*8扇區處

日誌資料如下

其結構為:

日誌中每一個塊都有一個12位元組的開頭

偏移 意義
0-3 日誌標記,值為C03B3998
4-7 塊內容的描述,1:描述符,表示塊位於事務提交之前,2:塊阻止記錄,表示塊事務提交完成,3:日誌超塊v1,4:日誌超塊v2,5:阻止重寫記錄,使得日誌能夠跳過後面重寫的塊
8-B 塊對應的事務ID

日誌超塊

偏移 意義
0-B 固定的塊頭
C-F 日誌塊的大小
10-13 日誌中塊的總數
14-17 日誌的第一個塊
18-1B 日誌中預期的第一個提交ID
1C-1F 日誌開始的塊編號
20-23 錯誤值
24-27 日誌相容功能,見文件
28-2B 日誌不相容功能,見文件
2C-2F
30-3F 日誌的128位uuid
40-43 共享此日誌的檔案系統數
44-47
48-4B
4C-4F
50 用於日誌的校驗和演算法,1:CRC32,2:MD5,3:SHA1,4:CRC32C
51-53 填充
54-57 日誌中快速提交塊數
58-FB 填充
FC-FF 整個超塊的校驗和,值設為0
100-3FF 共享日誌的所有檔案系統ID

描述符塊

開始依然是固定的12B塊頭,之後是多個日誌塊的標記,如果日誌超塊中偏移28-2B處設定了值為0x10的JBD2_FEATURE_INCOMPAT_CSUM_V3,則格式如下,偏移為這些內容的相對偏移

偏移 意義
0-3 資料塊在磁碟上位置的低32位
4-7 描述符塊對應的標記,見文件
8-B 資料塊在磁碟上位置的高32位
C-F 日誌UUID,序列號和資料塊的校驗和
10-1F 該標記的uuid

如果沒有設定,則格式如下,偏移為這些內容的相對偏移

偏移 意義
0-3 資料塊在磁碟上位置的低32位
4-5 日誌UUID,序列號和資料塊的校驗和的低16位
6-7 描述符塊對應的標記,見文件
8-B 資料塊在磁碟上位置的高32位,當日志超塊表明為64位版本時,欄位才存在
C-1F 該標記的uuid

參考

https://www.nongnu.org/ext2-doc/ext2.pdf
https://www.kernel.org/doc/html/latest/filesystems/ext4/about.html
http://web.mit.edu/tytso/www/linux/ext2intro.html
https://students.mimuw.edu.pl/ZSO/Wyklady/11_extXfs/extXfs.pdf
https://zhuanlan.zhihu.com/p/61749046
https://www.cnblogs.com/ggjucheng/archive/2012/08/22/2651641.html
https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Hash_Tree_Directories