BlobFS

BlobFS 是一個可定址內容的檔案系統,已針對一次寫入、經常讀取的檔案 (例如二進位檔和程式庫) 進行最佳化。在 Fuchsia 上,BlobFS 是所有軟體套件使用的儲存系統。

掛接時,BlobFS 會顯示包含所有檔案 (又稱為 blob) 的單一邏輯目錄:

blob/
 ├── 00aeb9b5652a4adbf630d04a6ca22668f9c8469746f3f175687b3c0ff6699a49
 ├── 01289d3e1d2cdbc7d1b4977210877c5bbdffdbad463d992badc149152962a205
 ├── 018951bcf92091fd5d294cbd1f3a48d6ca59be7759587f28077b2eb754b437c0
 └── 01bad8536a7aee498ffd323f53e06232b8a81edd507ac2a95bd0e819c4983138

BlobFS 中的檔案如下:

  • 不可變動:blob 建立後,即無法修改 (移除除外)。
  • Content-Addressable:系統會從內容中擷取 Blob 名稱。
  • 已驗證:系統會使用加密編譯檢查碼確保 blob 資料的完整性。

這些 Blob 屬性讓 BlobfS 成為 Fuchsia 安全性的關鍵元件,以確保軟體套件的內容在執行前可以通過驗證。

BlobFS 的設計和實作

磁碟機格式

BlobFS 會將每個 blob 儲存在非相鄰範圍 (連續的資料區塊範圍) 中連結的清單。每個 blob 都有相關聯的 I 節點,用於說明區塊資料在磁碟上的起始位置,以及 blob 相關中繼資料。

BlobFS 將磁碟 (或其分區) 分成五個區塊:

  • Superblock 儲存整個檔案系統的中繼資料,
  • Block Map:用來追蹤自由和分配的資料區塊的點陣圖。
  • 節點對應:Inodes 的平面陣列 (blob 資料開始在磁碟上的參照位置) 或 ExtentContainers (參照包含部分 blob 資料的數個範圍的參照)。
  • Journal,這是確保檔案系統運作的記錄檔,即使裝置在作業期間重新啟動或斷電也一樣;以及
  • 「資料區塊」,其中 blob 內容及其驗證中繼資料會以一系列程度儲存。

BlobFS 磁碟配置

圖 1:BlobFS 磁碟版面配置

超級封鎖

超級區塊是 BlobFS 格式分區中的第一個區塊。說明檔案系統中其他區塊的位置和大小,以及其他檔案系統層級中繼資料。

掛接 BlobFS 格式的檔案系統時,這個區塊會對應至記憶體並進行剖析,以判斷檔案系統的其餘部分的位置。每當建立新的 blob 時,都會修改區塊,且每當 BlobFS 檔案系統的大小變小或變大時 (適用於 FVM 代管的 BlobFS 執行個體),就會修改區塊。

BlobFS 超級區塊

圖 2:BlobFS 超級區塊

當 BlobFS 由 FVM 管理時,超級區塊會包含一些額外中繼資料,說明包含 BlobFS 檔案系統的 FVM 配量。非 FVM 且大小固定的 BlobFS 圖片會忽略這些欄位 (上圖中的黃色欄位)。

封鎖地圖

區塊地圖是簡易的點陣圖,會將每個資料區塊標示為已分配或未。進行區塊配置時,這張地圖可用來尋找連續範圍 (稱為「擴充」) 的區塊,以將 blob 內容儲存在其中。

區塊地圖範例

圖 3:提供幾種不同大小的區塊地圖範例。

掛接 BlobFS 映像檔時,區塊地圖會對應到記憶體,以供區塊配置器讀取。每當分配區塊 (建立 blob 期間) 或取消配置 (在刪除 blob 期間) 時,區塊對應就會寫回磁碟。

節點對應

節點對應是檔案系統中所有節點的陣列,可能有兩種變化:

  • Inodes:描述檔案系統中的單一 blob
  • ExtentContainers:指向包含部分 blob 資料的範圍。

這兩種類型的節點都儲存在單一平面陣列中。每個節點都有通用標頭,說明節點的類型以及是否分配節點。這兩種節點類型的大小相同,因此沒有陣列的內部片段化。

節點

檔案系統中的每個 blob 都有對應的 I 節點,用於說明 blob 資料的起始位置,以及一些與 blob 相關的中繼資料。

BlobFS Inode 的版面配置

圖 4:BlobFS Inode 的版面配置。

如為小型 blob,Inode 可能是唯一必要的節點,用來說明 blob 在磁碟中的位置。在本例中,extent_count 為 1,不得使用 next_node,而 inline_extent 則說明 blob 的單一範圍。

較大的 blob 可能會佔用多個範圍,尤其是在分割的 BlobFS 圖片上。在這個範例中,blob 的第一個範圍會儲存在 inline_extent 中,且所有後續規模都會從 next_node. 開始,儲存在 ExtentContainer 的連結清單中。

Extent 格式

圖 5:極端格式 (佔用 64 位元)。Inode 和 ExtentContainer 都使用這種格式。

請注意,此範圍表示法意指一個範圍最多只能有 2**16 個區塊 (超出大小的最大值)。

ExtentContainers

ExtentContainer 會保留數個 (最多 6) 個範圍的參照,用來儲存 blob 的部分內容。

ExtentContainer 中的範圍在邏輯上是連續的 (也就是儲存在 extents[0] 中的 blob 的邏輯可定區塊區塊,然後是 extents[1] 之前),並會依序填入。如果設定了 next_node,則 ExtentContainer 必須已滿。

BlobFS ExtentContainer 的版面配置

圖 6:BlobFS ExtentContainer 的版面配置。

已連結節點清單的屬性

blob 的範圍會儲存在單一 I 節點 (保存第一個範圍) 的連結清單中,以及零或多個 ExtentContainer (每個節點最多可保留 6 個擴充項目)。

這份已連結的清單包含下列資源。違反上述任何屬性會導致 blobf 將 blob 視為毀損。

  • 填充在邏輯上皆屬連續:
    • 如果節點 A 在清單中節點 B 之前,則節點 A 中所有範圍的邏輯偏移值都低於 blob 內容的邏輯偏移。
    • 在指定的 ExtentContainer 中,如果範圍為 x 和 y,假如 x < y,外部 x 對 blob 內容的邏輯偏移就比範圍 y 低。
  • 連結新節點之前,系統會封裝節點。換句話說,如果節點有非空值的 next_node,就必須具有完整的範圍 (*針對 I 節點,以及 ExtentContainers 的 6 範圍)。
  • 連結清單中的範圍總數必須與 I 節點的 extent_count 相同。
  • 已連結清單中所有範圍的大小總和必須與 Ionic 的 block_count 相同。
  • 清單的結尾取決於系統節點中的 extent_count。不應使用最終節點中的 next_node
Node 版面配置範例

本節包含一些範例,說明 blob 節點的格式。

範例:單一擴充 blob

範例:單一擴充 blob

圖 7:以單一程度儲存 blob 的節點版面配置

範例:多餘 blob

範例:多餘 blob

圖 8:以不同程度儲存的 blob 節點版面配置。請注意,blob 的延伸項目可能會分散到整個磁碟。

Blob 分割

新建立的 BlobFS 映像檔可以產生所有資料區塊。任意大小可以輕易找到,而 blob 通常都是以單一較大的範圍 (或少數很多範圍) 儲存。

隨著時間經過,分配及取消分配 blob 時,區塊地圖會「分割」到許多較小的範圍。新建的 blob 將必須儲存在多個較小的範圍中。

片段化區塊地圖

圖 9:片段化區塊地圖。雖然免費區塊可以提供許多,但如果是很廣泛仍可使用。

片段不理想的狀況,原因如下:

  • 較慢讀取:讀取片段的 blob 必須在 Node Map 中追蹤指標。這會影響依序讀取和隨機存取讀取
  • 較慢的建立與刪除:建立 blob 需要找到免費的擴充功能;如果必須找到許多較小的範圍,則需要較長時間。同樣地,刪除片段化 blob 時,會一併處理並釋放許多擴充功能。
  • 中繼資料負擔:如要儲存分段的 blob,就需要更多節點。節點地圖中的節點數量有限,因此可能會耗盡,導致系統無法建立 blob。

目前 BlobFS 並未執行重組作業。

日誌

待辦事項

資料區塊

最後,blob 的實際內容必須儲存在某處。系統會針對此目的指定 BlobFS 映像檔中剩餘的儲存區塊。

每個 blob 的配置程度都足以容納其所有資料,以及一些為 blob 儲存驗證中繼資料而保留的資料區塊。此中繼資料一律儲存在 blob 的第一個區塊。系統會新增中繼資料,讓實際資料一律從區塊對齊的地址開始。

這類驗證中繼資料稱為「Merkle Tree」,這是使用加密編譯雜湊值確保 blob 內容完整性的資料結構。

梅克爾樹

blob 的 Merkle Tree 結構如下 (詳情請參閱 Fuchsia Merkle Roots):

  • 每個分葉節點都是單一區塊中資料的 sha256 雜湊。
  • 每個非分葉節點都是合併其子項雜湊的 sha256 雜湊。
  • 樹狀結構會在有單一 sha256 雜湊的層級終止。

最頂層節點的雜湊值稱為 blob 的「Merkle Root」。 這個值會做為 blob 的名稱。

簡化版 Merkle Tree 範例

圖 10:簡化的範例 Merkle Tree。請注意,實際上,每個雜湊值都包含更多資訊 (例如區塊偏移和長度),且每個非分葉節點都會大幅擴大 (特別是每個非分葉節點最多可包含 8192 / 32 == 256 個子項)。

BlobFS 實作

如同其他 Fuchsia 檔案系統,BlobFS 可做為使用者空間程序實作,可透過 FIDL 介面為用戶端提供服務。