Starnix VFS 架構

頁面深入探討 Starnix 虛擬檔案系統 (VFS) 的重要概念和基礎結構:

激發 Starnix 虛擬檔案系統的動力

Starnix 有自己專屬的虛擬檔案系統 (與 Fuchsia 的 VFS 不同),原因如下:

  • 效能 – Starnix VFS 可允許許多檔案系統作業,避免發出 FIDL 呼叫。Starnix VFS 的做法是快取先前 FIDL 呼叫的結果,並在程序中實作整個檔案系統 (與 tmpfsprocfs 類似)。

  • 相容性 - Starnix 的檔案系統必須支援 Fuchsia VFS 程式庫不支援的數項 Linux 檔案系統作業,而許多 Linux 作業系統仰賴的作業系統。請特別留意,下列兩項運算難以改造為 Fuchsia 現有的 VFS 設計:

    • 掛接目錄 - Linux 檔案系統可將某個檔案系統的目錄掛接到另一個檔案系統的目錄。

    • 追蹤 open() 後方的檔案路徑:Linux 檔案系統可以使用檔案描述元判斷由 open() 呼叫開啟的檔案路徑。如果檔案或其中一個上層目錄遭到移動或重新命名,檔案路徑就必須考量這項變更。

Starnix VFS 的構成元素

本節使用 Starnix VFS 的基本建構區塊來建構簡易檔案系統:

檔案與目錄

Starnix VFS 的核心是 FsNode 執行個體集合。每個 FsNode 都含有檔案或目錄的相關資訊 (見圖 1)。系統會在 FsNode 執行個體上執行檔案系統作業,例如讀取、寫入及擷取檔案資訊。

簡易檔案系統

圖 1. 包含目錄和檔案的簡易檔案系統。

DirEntry 會為 FsNode 指派名稱。這種 DirEntryFsNode 的對應稱為硬式編碼。多個 DirEntry 執行個體可對應至單一檔案類型的 FsNode (請參閱圖 2)。這樣就能將檔案系統中的多個路徑解析為同一個 FsNode。因此,多個路徑可以解析為檔案系統中的相同檔案內容和屬性。但是,雖然一個檔案可以有多個硬連結,但目錄 (也就是目錄類型的 FsNode) 只能有一個硬連結。

具有兩個 DirEntry 執行個體的檔案系統

圖 2:多個 DirEntry 執行個體可對應至同一個 FsNode

檔案系統

檔案系統會追蹤一組相關檔案和目錄的資訊。在 Starnix VFS 中,檔案系統 (也就是 FileSystem 的單一執行個體) 代表一組 DirEntry 例項,而每個 FileSystem 執行個體都包含下列項目:

  • 指向根目錄的 DirEntry
  • FsNode 執行個體的快取 (代表根目錄下的檔案和目錄)

檔案系統

圖 3 FileSystem 會追蹤 DirEntryFsNode 執行個體。

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 的根目錄。

已掛接的檔案系統

圖 5Mount 會追蹤掛接 FileSystem 的根目錄。

為啟用從父項 FileSystem 順暢移至子項 FileSystem 的功能,反之亦然,Mount 會追蹤指向掛接 FileSystem 根目錄的 DirEntry (請參閱圖 5)。此外,Mount 也會使用 mountpoint 指標 (請參閱 NamespaceNode) 追蹤其父項 Mount,並使用 submounts 指標追蹤其子項 Mount 例項。(參閱圖 6)。

掛接執行個體

圖 6Mountmountpointsubmounts 指標可用於在已掛接的檔案系統之間移動。

請注意,FileSystem 可一次掛接到多個不同的 FileSystem 執行個體。這樣做可讓從多個父項 FileSystem 執行個體存取相同的 FileSystem,進而使用各種路徑 (或符號連結) 連線到掛接 FileSystem 中的相同檔案。

命名空間節點

Starnix 中的每個工作都包含 FsContext 的例項。FsContext 會保留工作與 Starnix VFS 的關聯資訊,但檔案描述元資料表除外。

重要的是,FsContext 包含 Namespace,可讓工作識別掛接在這個命名空間下的所有 FileSystem 執行個體。之所以會發生這種情況,是因為每個 Namespace 都包含 Mount,用於追蹤命名空間中的「根掛接」(請參閱圖 7)。使用根掛接的 submounts 指標 (指向所有 DirEntry 執行個體及其在命名空間中各自的 Mount 例項),工作可以觸及此命名空間下其他所有掛接的 FileSystem 執行個體。

FsContext 和命名空間

圖 7. FsContext 具有 Namespace,其中包含用於追蹤根掛接的 Mount

NamespaceNode 適用於 Namespace 中的周遊路徑。每個 NamespaceNode 都會追蹤 Mount 及其各自的 DirEntry

不過,由於同一個 FileSystem 可以多次掛接在 Namespace 中 (例如,位於相同父項 FileSystem 中的不同掛接點目錄),因此可能需要多個 NamespaceNode 執行個體來追蹤這些指向同一個基礎 FileSystem 的不同 Mount 執行個體。

命名空間 Nodes 執行個體

圖 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 NamespaceNodeentry 指標至 example 目錄。

Cwd 命名空間 Node

圖 10. 目前的工作目錄已變更為命名空間中的 example 目錄。

圖 11 中的圖表顯示範例 FS 掛接至父項 FS 的命名空間。在這個情境下,當 cd example 執行時,cwd NamespaceNodemount 指標會更新為追蹤 Example FS 根目錄的新 Mount (名為「範例掛接」)。有了這個新的 MountFsContext 中的工作就能在周遊路徑時,順利從父項 FS 移至範例 FS。

包含已掛接檔案系統的命名空間

圖 11. 將範例 FS 掛接至父項 FS example 目錄的命名空間。

系統會在行走 NamespaceNode 執行個體時處理符號連結 (或符號連結)。如果工作命中符號連結並要求提供路徑,則這個符號連結的路徑會從 NamespaceNode 遞迴解析。