天天看點

Ext4檔案系統架構分析(三) ——目錄哈希、擴充屬性與日志

struct dx_root

Htree的内部節點: struct dx_node

Htree 樹根和節點中都存在的 Hash map: struct dx_entry

擴充屬性(xattrs)通常存儲在磁盤上的一個單獨的資料塊中,通過inode.i_file_acl*引用。擴充屬性的第一應用是存儲檔案的ACL以及其他安全資料(selinux)。使用user_xattr挂載選項就可為使用者存儲以“user”開頭的所有擴充屬性。這樣的限制在3.0核心中已經消失。

可以在兩個地方找到擴充屬性:一是在一個inode項結尾到下一個inode項開頭的地方;二是inode.i_file_acl指向 的資料塊之中,到3.0為止,這個資料塊中不包含指向第二個擴充屬性資料塊的指針。理論上可以将每個屬性值存儲到一個單獨的資料塊中,但是3.0核心為止仍然沒有這樣做。

當擴充屬性不存儲在一個inode之後的時候,就會有一個頭部ext4_xattr_ibody_header

擴充屬性資料塊的開頭是ext4_xattr _header

緊跟在ext4_xattr_ibody_header或者ext4_xattr _header後面的是結構數組 struct ext4_xattr_entry

擴充屬性值可以緊跟在ext4_xattr_entry項表後面。考慮4 bytes對齊。擴充屬性值從擴充屬性資料塊的末尾開始向ext4_xattr _header / ext4_xattr_entry表的方向增長。當發生溢出時,溢出的部分放到一個單獨的磁盤資料塊上。

檔案系統在磁盤上保留一段小的連續區域(預設128MB),作為盡可能需要快速寫入磁盤的“重要”資料的存放地。一旦該重要資料事務完全寫到磁盤,将其從磁盤寫緩存中刷出。被送出的資料一份記錄也被寫到日志。一段時間後,日志在擦除送出記錄前将事務寫到它們在磁盤上的最終位置(可能包含大量的尋道或者大量的讀-寫-擦除)。

從性能方面考慮,Ext4預設直接将檔案系統中繼資料寫到日志。因而不能保證檔案資料塊的一緻性。

       日志的inode為8。日志inode的前68 bytes複制了ext4 超級塊。日志檔案在檔案系統中是普通檔案,但是隐藏不可見。日志檔案通常消耗一個完整的塊組,可以通過mke2fs将日志檔案放在磁盤的中間。

Ext4和Ocfs2都使用JBD2。

日志布局

一個事務以描述符和一些資料或者block revocation連結清單開始。一個結束的事務總是以一個送出塊結束。如果沒有送出記錄(或者校驗和不比對),事務在日志重演的時候将被丢棄。

日志中的每個資料塊的開頭都是一個12 bytes的資料結構 struct journal_header_s

日志的超級塊比Ext4的超級塊簡單。儲存在日志的超級塊中是日志的關鍵資料。日志超級塊使用資料結構struct journal_superblock_s表示,大小為1024 bytes。

Descriptor Block包含一個日志資料塊tags的數組,這些tags描述了日志中接下來的資料塊的最終位置。

日志資料塊tags具有如下格式:由資料結構struct journal_block_tag_s表示,可以是8,12,24或38bytes。

存放的是通過日志寫到磁盤的資料塊。但是如果資料塊的前4 bytes與jbd2的魔數比對,那麼這些4 bytes用0代替,并且在Descriptor Block中設定escaped。

繼續閱讀