頁面深入探討 Starnix 虛擬檔案系統 (VFS) 的重要概念和基礎結構:
激發 Starnix 虛擬檔案系統的動力
Starnix 有自己專屬的虛擬檔案系統 (與 Fuchsia 的 VFS 不同),原因如下:
效能 – Starnix VFS 可允許許多檔案系統作業,避免發出 FIDL 呼叫。Starnix VFS 的做法是快取先前 FIDL 呼叫的結果,並在程序中實作整個檔案系統 (與
tmpfs
和procfs
類似)。相容性 - Starnix 的檔案系統必須支援 Fuchsia VFS 程式庫不支援的數項 Linux 檔案系統作業,而許多 Linux 作業系統仰賴的作業系統。請特別留意,下列兩項運算難以改造為 Fuchsia 現有的 VFS 設計:
掛接目錄 - Linux 檔案系統可將某個檔案系統的目錄掛接到另一個檔案系統的目錄。
追蹤
open()
後方的檔案路徑:Linux 檔案系統可以使用檔案描述元判斷由open()
呼叫開啟的檔案路徑。如果檔案或其中一個上層目錄遭到移動或重新命名,檔案路徑就必須考量這項變更。
Starnix VFS 的構成元素
本節使用 Starnix VFS 的基本建構區塊來建構簡易檔案系統:
檔案與目錄
Starnix VFS 的核心是 FsNode
執行個體集合。每個 FsNode
都含有檔案或目錄的相關資訊 (見圖 1)。系統會在 FsNode
執行個體上執行檔案系統作業,例如讀取、寫入及擷取檔案資訊。
圖 1. 包含目錄和檔案的簡易檔案系統。
DirEntry
會為 FsNode
指派名稱。這種 DirEntry
與 FsNode
的對應稱為硬式編碼。多個 DirEntry
執行個體可對應至單一檔案類型的 FsNode
(請參閱圖 2)。這樣就能將檔案系統中的多個路徑解析為同一個 FsNode
。因此,多個路徑可以解析為檔案系統中的相同檔案內容和屬性。但是,雖然一個檔案可以有多個硬連結,但目錄 (也就是目錄類型的 FsNode
) 只能有一個硬連結。
圖 2:多個 DirEntry
執行個體可對應至同一個 FsNode
。
檔案系統
檔案系統會追蹤一組相關檔案和目錄的資訊。在 Starnix VFS 中,檔案系統 (也就是 FileSystem
的單一執行個體) 代表一組 DirEntry
例項,而每個 FileSystem
執行個體都包含下列項目:
- 指向根目錄的
DirEntry
FsNode
執行個體的快取 (代表根目錄下的檔案和目錄)
圖 3 FileSystem
會追蹤 DirEntry
和 FsNode
執行個體。
Starnix VFS 中的掛接檔案系統
掛接功能可讓使用者順暢地從某個檔案系統移至另一個檔案系統。檔案系統掛接至特定目錄後,使用者 (或工作) 將可使用該系統及其內容。這個「掛接點」目錄通常是使用者已有存取權的其他檔案系統目錄。舉例來說,在圖 4 中,使用者可以使用父項 FS 中的路徑 /example/file1.txt
,取得範例 FS (檔案系統) 中的 file1.txt
檔案。
圖 4 Example FS 的根目錄會掛接至父項 FS 的 example
目錄。
在 Starnix VFS 中掛接檔案系統和追蹤掛接點時涉及下列執行個體:
掛載
Mount
會在另一個 FileSystem
的掛接點目錄存取 FileSystem
。為了以不同的方式放置,Mount
是用來連結下列兩個目錄:
- 父項
FileSystem
中的掛接點目錄 - 子項
FileSystem
的根目錄
在圖 4 中,父項 FS 擁有做為子目錄的 example
目錄,而範例 FS 會掛接到這個 example
目錄 (亦即掛接點目錄)。在這種設定中,當您將工作目錄變更為父項 FS 中的 example
目錄 (例如 cd example
正在執行) 時,您會「輸入掛接」,也就是說,您現在位於範例 FS 的根目錄。
圖 5:Mount
會追蹤掛接 FileSystem
的根目錄。
為啟用從父項 FileSystem
順暢移至子項 FileSystem
的功能,反之亦然,Mount
會追蹤指向掛接 FileSystem
根目錄的 DirEntry
(請參閱圖 5)。此外,Mount
也會使用 mountpoint
指標 (請參閱 NamespaceNode
) 追蹤其父項 Mount
,並使用 submounts
指標追蹤其子項 Mount
例項。(參閱圖 6)。
圖 6:Mount
的 mountpoint
和 submounts
指標可用於在已掛接的檔案系統之間移動。
請注意,FileSystem
可一次掛接到多個不同的 FileSystem
執行個體。這樣做可讓從多個父項 FileSystem
執行個體存取相同的 FileSystem
,進而使用各種路徑 (或符號連結) 連線到掛接 FileSystem
中的相同檔案。
命名空間節點
Starnix 中的每個工作都包含 FsContext
的例項。FsContext
會保留工作與 Starnix VFS 的關聯資訊,但檔案描述元資料表除外。
重要的是,FsContext
包含 Namespace
,可讓工作識別掛接在這個命名空間下的所有 FileSystem
執行個體。之所以會發生這種情況,是因為每個 Namespace
都包含 Mount
,用於追蹤命名空間中的「根掛接」(請參閱圖 7)。使用根掛接的 submounts
指標 (指向所有 DirEntry
執行個體及其在命名空間中各自的 Mount
例項),工作可以觸及此命名空間下其他所有掛接的 FileSystem
執行個體。
圖 7. FsContext
具有 Namespace
,其中包含用於追蹤根掛接的 Mount
。
NamespaceNode
適用於 Namespace
中的周遊路徑。每個 NamespaceNode
都會追蹤 Mount
及其各自的 DirEntry
。
不過,由於同一個 FileSystem
可以多次掛接在 Namespace
中 (例如,位於相同父項 FileSystem
中的不同掛接點目錄),因此可能需要多個 NamespaceNode
執行個體來追蹤這些指向同一個基礎 FileSystem
的不同 Mount
執行個體。
圖 8. FsContext
有兩個 NamespaceNode
執行個體,用於追蹤特定目錄:Root 和 cwd。
舉例來說,每個 FsContext
至少都包含兩個用於追蹤下列目錄的 NamespaceNode
執行個體 (見圖 8):
- 根目錄
- 目前的工作目錄 (cwd)
這兩個 NamespaceNode
執行個體都會用來查詢這個 Namespace
中的路徑。開頭為 /
的路徑 (例如 /example/file1.txt
) 會分別與根 NamespaceNode
查詢,而沒有起始 /
的路徑 (例如 file1.txt
) 則使用 cwd NamespaceNode
查詢。
圖 9. 具有一個 (根層級) Mount
的簡易命名空間。
圖 9 中的圖表呈現了一個具有單一 Mount
的命名空間,其中目前工作目錄 (cwd) 也是根目錄。圖 10 中的圖表顯示目前的工作目錄已變更為 example
目錄 (例如,執行 cd example
),該目錄會更新 cwd NamespaceNode
的 entry
指標至 example
目錄。
圖 10. 目前的工作目錄已變更為命名空間中的 example
目錄。
圖 11 中的圖表顯示範例 FS 掛接至父項 FS 的命名空間。在這個情境下,當 cd example
執行時,cwd NamespaceNode
的 mount
指標會更新為追蹤 Example FS 根目錄的新 Mount
(名為「範例掛接」)。有了這個新的 Mount
,FsContext
中的工作就能在周遊路徑時,順利從父項 FS 移至範例 FS。
圖 11. 將範例 FS 掛接至父項 FS example
目錄的命名空間。
符號連結
系統會在行走 NamespaceNode
執行個體時處理符號連結 (或符號連結)。如果工作命中符號連結並要求提供路徑,則這個符號連結的路徑會從 NamespaceNode
遞迴解析。