RFC-0136:Fxfs | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 全新 Fuchsia 檔案系統的概要總覽。 |
變更 | |
作者 | |
審查人員 | |
提交日期 (年/月) | 2021-09-30 |
審查日期 (年/月) | 2021-10-13 |
摘要
Fxfs 是新的 Fuchsia 檔案系統,已在儲存團隊內部開發。本提案概述 Fxfs 的動機和更高等級的設計決策。
提振精神
Fuchsia 現有的可變動檔案系統 Minfs 有一些限制,意味著我們很難新增日後要新增的功能,進而達到我們的效能目標。Fxfs 正在開發為取代 Minfs 的候選標,以便達成這些目標。
以下列舉一些幾乎一定會需要的功能,例如:
- 完整讀取/寫入 mmap 支援
- 支援擴充屬性
- 嚴格強制執行配額
- 檔案系統通知 (具體為
inotify
支援) - 檔案鎖定 (尤其是
flock
支援)
最終可能會需求還有其他功能:
- 內建加密功能 - 依檔案加密功能
- 快照支援
- 檔案副本
- 支援多個磁碟區
- 壓縮支援
我們也的目標是獲得與其他作業系統相當的檔案系統效能。最重要的是,這可能是最困難的工作,並會花最多心力。
所有檔案系統都必須考量基本的檔案系統目標:
- 建議您盡量減少閃光燈,以盡量減少閃光燈佩戴效果。
- 有效率地使用空間,例如盡量減少小型檔案的浪費。
- 易於遷移。
達成這些目標所需的大部分工作將在儲存堆疊與核心中的工作之外涵蓋,但本文不涵蓋在此處;此 RFC 僅著重於檔案系統的實作,Fxfs。
雖然 Fxfs 很適合在刷新儲存裝置上運作,但是在設計中,沒有任何項目可以限定在旋轉儲存裝置中,我們預期 Fxfs 也能在飛輪儲存裝置中運作。
相關人員
講師:
審查人員:abarth@google.com、brettw@google.com、Palerer@google.com
顧問:
Fuchsia 的安全團隊在詢問加密相關問題後獲得諮詢。
社群媒體化:
「本機儲存空間」團隊針對 Fxfs 進行的詳細設計審查。
設計
記錄結構化合併樹狀結構
您可以前往 Wikipedia 瞭解記錄結構化合併 (LSM) 樹狀結構。Fxfs 會使用 LSM 樹狀結構提供在 Fxf 中使用的永久鍵/值資料結構。
LSM 樹木提供一些吸引人的房源:
- 寫入裝置的層無法變更,這表示:
- 存取這些圖層時不需要鎖定。
- 限制特定錯誤類別 — 如果未修改圖層,損毀的機率就會下降。
- 偵錯問題可能更加簡單:如果圖層不變更,移動部分就會減少。
- 支援壓縮會比較容易,且可在背景套用更積極的壓縮功能以節省空間。
- 異動會依序分批寫入,而不是小部分,這是對快閃儲存而言更適合使用的寫入模式,可減少寫入放大,並避免不必要的清除循環。這種寫入模式也適用於旋轉儲存裝置。
- 快照支援比其他方式更容易上手。
- 允許寫入至閒置時間的延遲工作 (許多裝置都會有大量的閒置時間)。實際上,可在裝置未使用時,在最方便的時刻完成壓縮。
- 壓縮可在背景執行,以便將時間回傳給更重要的工作。
- 重新編寫中繼資料是相當適合執行的基本檔案系統作業,有助於簡化格式遷移作業。可以在壓縮期間寫出完全不同的圖層格式。
不過,這有一些缺點:
- 更難以管理空間:所有作業都需要中繼資料空間,甚至是刪除作業,因此請謹慎預留空間。請注意,由於其他支援快照的檔案系統也會發生這個問題,因此不會是 LSM 樹狀結構的唯一識別碼。
- 在有大量圖層的情況下,讀取速度較慢。我們可以為此採取一些緩解措施 (例如繁花濾鏡),壓縮層則可減少這類成本。
值得注意的是,即使選擇 LSM 樹狀結構,如果我們發現混合型方法有必要,也可以選用可變動的永久層格式。
Fxfs 的 LSM 樹狀結構實作需要合併函式,用於指定記錄的合併方式。
Fxfs 的記憶體內層是以高效率且易於並行的資料結構表示 (目前為略過清單)。
物件儲存庫
Fxfs 是由物件儲存庫的階層組成,物件儲存區提供類似檔案的 API,且以物件 ID 做為金鑰金鑰,物件 ID 為 64 位元無正負號整數。系統支援簡單的命名空間功能 (例如目錄支援或類似功能),但並非必要條件。您可以使用物件存放區,僅使用物件 ID 來參照物件。物件會將其中繼資料儲存在永久的鍵/值資料結構 (LSM 樹狀結構)。中繼資料包含一般檔案資訊,例如對應至裝置偏移值的物件大小和範圍。
Fxfs 的 LSM 樹狀結構會使用物件儲存庫來儲存代表循環相依性的永久層:物件存放區會使用 LSM 樹狀結構儲存中繼資料,LSM 樹則使用物件儲存來儲存持續層。為解決這個問題,物件儲存庫是按階層排列:
根層級存放區
根父項物件存放區只由記憶體內 LSM 樹狀結構提供支援,因此對物件存放區沒有依附元件。
根存放區僅包含根存放區的圖層檔案和日誌檔案 (稍後討論)。請注意,LSM 樹狀結構僅包含中繼資料 (例如範圍資訊),而且只會將資訊永久留在記憶體中。
根儲存庫
根存放區會使用根父項存放區,儲存其永久層檔案。
根存放區包含所有支援檔案系統的物件,例如配置器和超區塊使用的物件。
兒童商店
子項儲存會使用根存放區來儲存永久層檔案。可用來儲存使用者資料。子項商店可以有很多,但他們只能把根存放區當做父項使用,因此系統會將階層限制為三個層級。請注意,我們可以視需要支援更深層的物件儲存庫階層。
物品
物件是以 64 位元的無正負號整數來識別,且該整數是儲存在儲存的儲存庫中,因此您需要指定儲存庫,才能正確識別檔案系統中的物件。
零為保留值,用於表示無效的物件 ID。
物件支援多個屬性,這些屬性是以物件內的 64 位元屬性 ID 編入索引。屬性具有類似檔案的 API,因此可在屬性內的任意偏移量讀取和寫入任意金額。一開始,Fxfs 只會公開對物件 (即檔案內容) 單一屬性的存取權。其他屬性可用於支援擴充屬性。屬性可以是稀疏。
將資料寫入物件有兩種模式:寫入時複製模式 (與 Minfs 相同) 及覆寫模式。使用「寫入時複製」模式時,任何已配置的區塊寫入作業都會寫入新分配的區塊,將中繼資料更新為指向新區塊,然後釋出舊區塊。覆寫模式會覆寫現有區塊,因此不需要更新相同的中繼資料。大多數的物件都會使用寫入時複製模式來編寫,且這是一開始向外部使用者公開的唯一模式。
日誌
Fxfs 的日誌有兩個用途:
- 支援交易功能,也就是能夠以不可分割的形式將異動套用到多個檔案系統物件。
- 為了在斷電時快速保留變化。如果沒有這樣做,所有變更必須等到記憶體層清除後才會保留,但基於效能和寫入增強的原因,最好盡可能延遲這項作業 (視記憶體限製而定)。
記憶體內資料結構的所有異動都必須通過日誌。與 Minfs 的日誌不同,日誌是邏輯日誌,而不是實體日誌。這樣可大幅減少日誌佔用的空間:插入記錄可以用幾個位元組表示,而變更 Minfs 中的資料結構時,可能會涉及多個區塊。
請注意,Fxfs 的日誌 (例如 Minfs) 不包含資料。不過,Fxfs 日誌確實會針對以 COW 模式寫入的資料執行總和檢查碼,而 Fxfs 會在日誌重播期間,針對自上次已知裝置清除後寫入的資料驗證總和檢查碼,這表示 Fxfs 可以偵測目前已寫入的 COW 寫入,並將檔案內容還原為上次的完整寫入版本。Minfs 沒有這項功能的資料檢查碼處理功能。
日誌就像持續成長的單一檔案。異動會串流至檔案中。因為樹狀結構較精簡,日誌檔案開頭可以釋出範圍,這表示日誌會有一個稀疏前置字串。所有物件都有 64 位元大小,而我們需要支援的寫入率,因此生命週期中不會發生包裝問題。為因應裝置可自行重新訂購寫入作業,系統會在每 4 KiB 區塊的結尾加上檢查碼。重播時,重播作業會在日誌中的第一個區塊有檢查碼不符的情形時結束。一個區塊的檢查碼會用來當做下一個區塊的種子,此區塊應避免意外接受針對不同偏移量的區塊,或是前一個 Fxf 執行個體的殘餘區塊。
重播日誌時,要瞭解到多層次的日誌檔案,必須要超封鎖。為解決這個問題,日誌會使用覆寫作業模式,並預先分配擴充項目。在重播期間,系統會用來讀取日誌串流中的任何範圍,用來讀取日誌檔案中的稍後偏移值。
超級模塊
Fxfs 的超級區塊不僅僅是區塊,用途與傳統的超級區塊類似,因此使用相同的名稱。超級區塊是以物件的形式存在,並位於根物件存放區中。與其他物件不同,物件的第一個範圍會放在裝置的固定位置 (所有其他物件都沒有位置限制)。超區塊的第一部分包含序列化結構,其中包含在其他檔案系統中找到的資訊 (例如區塊大小、重要物件的物件編號等) 的類似資訊。之後,超級區塊會包含根父項物件儲存庫中的「所有」記錄 (在寫入超級區塊時)。超級區塊的編寫方式和撰寫日誌相同:每個 4 KiB 區塊的結尾都有檢查碼。
這類廣告有兩種掛接期間,系統會選擇含有最新序列編號的超區塊。
掛接檔案系統須符合以下條件:
- 使用最新的序號讀取超區塊。
- 將日誌中的所有異動內容套用至記憶體內的層。
- 讀取圖層資訊,並初始化 LSM 樹狀結構永久層。
配置器
配置器使用 LSM 樹狀結構儲存參考計數範圍 (可以有效視為永久儲存 <device-range> => <reference-count>
。Fxf 一開始僅支援一個參考計數,但日後 Fxf 可能會支援檔案副本或範圍共享,這會導致系統參照多個項目。
目錄
物件會以下列格式儲存記錄,藉此儲存支援目錄:<object-id><child-name> => <child-object-id><child-type>
。這項資訊記錄在用於其他物件中繼資料的樹狀結構中。
壓縮
最初的壓縮是因為需要釋出日誌的空間。合理的政策會先做為一個合理的選擇,並且會視需要不斷調整;任何與格式無關的政策,所以可輕易變更。
檔案名稱編碼
目前 Fxfs 為檔案名稱採用的特定編碼方式尚未指定,但請注意,編碼選擇幾乎與 UTF-8 相容,後者是用於 FIDL 字串和 Rust 字串的編碼。Fxf 會區分大小寫,且不會進行正規化。若有相容性問題,就可能必須變更。
檔案系統限制
- 檔案大小不得超過
2^63
個位元組 (64 位元帶正負號整數的最大值)。Fxfs 在內部可以表示檔案大小上限為2^64
個位元組,但現有的檔案系統 API 對此設有限制 (例如已簽署的off_t
類型)。 - 目錄大小沒有特定限制,但實際上會受限於磁碟大小和節點數量。
- 每個音量大約可以有 2^64 噸的雜物。在實作上,這可能會受限於磁碟大小。
- Fxfs 可支援約 2^64 磁碟區。實際上,這可能會受到磁碟大小和其他資源 (例如載入磁碟區時的記憶體) 的限制。
- Fxfs 支援以奈秒為單位的時間戳記,包含
2^64
位元秒和2^32
位元奈秒,這可以代表遙遠的 UNIX Epoch 紀元時間戳記。
擊球
Fxfs 提供 fsck 的基本實作,可驗證配置和物件參照計數。不久之後,我們會進行更多工作,以擴大視野。
Minfs
我們根據 Minfs 所做的設計選擇
- 支援多執行緒。Minfs 為單執行緒。相較於一開始就實作多執行緒支援,要溯及既往。Fxfs 是多執行緒的。
- Minfs 使用的實體日誌很簡單,但會導致寫入大幅擴增。Fxfs 使用邏輯日誌。
- Minfs 對目錄大小和 i 節點數量設有嚴格限制。Fxfs 的限制主要是根據磁碟大小而定。
- 改良 Minfs 的格式並不容易,因為所有變更都必須回溯相容,且必須審慎考慮遷移。Fxf 仍需遷移,但由於壓縮會觸發完整重寫中繼資料,因此部分格式變更會比較簡單。
實作
Fxfs 原型設計已經發展一段時間,因為已有一段時間,存在樹狀結構內 (//src/storage/fxfs),並提供使用該工具而非 Minfs 的選項。目前 Minfs 仍然是預設的可變動檔案系統。變更預設值的決定不在這個 RFC 的範圍內。
語言
Fxfs 使用 Rust。我們相信 Rust 具有幾項吸引力:
- 記憶體安全 - 當機次數較少和安全性問題較少,特別適用於有多個執行緒。
- 順暢的非同步支援 - 檔案系統受惠於高平行處理技術,以及 Rust 的非同步支援,可大幅簡化這項作業。
效能
使用 Fxfs 的理由之一是改善可變動檔案系統的效能。我們用來評估效能的基準是獨立開發而成,這些基準的確切性質不在這個 RFC 的範圍內。
回溯相容性
Fxfs 起初將做為 Minfs 的替代方案,且對於從 Minfs 遷移的功能有限 (不適用於實際工作環境)。
我們日後可能會考慮支援更強大的遷移作業。
安全性考量
初始 Fxfs 可與 Zxcrypt 搭配使用,進行磁碟區層級的加密作業 (如同 Minifs),因此這個區域應該不會有太多變化。Fxfs 是在 Rust 中開發而成,理論上應可降低一些安全性風險。
Fxfs 內建加密功能需要徹底考量安全層面,這並不在 RFC 的涵蓋範圍內。
隱私權注意事項
無
測試
Fxfs 使用與 Minfs 相同的全方位檔案系統測試套件。在適用情況下,也會有 Fxfs 專屬的其他單元和整合測試。
說明文件
Fxfs 應與 Minfs 互通,因此不需要額外的外部說明文件,我們的 API 將不會變更。此 RFC 本身是記錄高階 Fxfs 的主要構件。
缺點、替代方案和未知
開發新的檔案系統是一項重要的事。雖然我們成功在功能和效能方面實作接近 Minfs 的原型,還有一個方法可以採用 Fxfs 正式上線。
在啟用這項專案之前,我們會考慮其他策略,例如移植現有的開放原始碼檔案系統,或是使用現有檔案系統的設計。請考量以下事項:
- 相較於其他作業系統,Fchsia 的檔案系統介面與其他作業系統大不相同,因此移植作業是相當可觀的。
- 部分現有的開放原始碼檔案系統具有授權障礙。
- 程式碼集既是,也與 Fuchsia 的大多數程式碼集不一致 (C++ 為不常見,測試做法也不同)。
- 選擇現有設計會對格式演進造成一些限制;為支援新的功能需求而變更格式可能會涉及建立格式,以及/或造成推送變更上游的負擔。
- 我們需要執行的大部分效能工作實際上並非在檔案系統的實作中,因此開發新的檔案系統絕對不是達成效能目標的重要途徑。
- 既有的檔案系統具有演進史。重新實作現有的設計通常需要挑選一組要支援的功能,這會導致相容性有限。
- 針對 Minfs 進行漸進式變更以達到需要的時間,因為我們可能需要支援遷移。
因此,我們選擇支援對 F2fs 移植作業的外部貢獻,目標是達到 Fuchsia 搭配多個不同檔案系統運作順暢的位置。
先前的圖片和參考資料
LSM 樹狀圖並非全新項目,且在各種應用程式中廣泛使用,雖然在較小的檔案系統中使用的範例有限。
其他檔案系統也提供了 Fxfs 設計的其他面向,例如邏輯日誌格式和多重磁碟區支援。