Coda Kernel-Venus 介面¶
注意
這是描述 Coda 元件的技術文件之一 - 本文件描述了客戶端核心-Venus 介面。
更多資訊
執行 Coda 所需的使用者級軟體
要執行 Coda,您需要獲取客戶端的使用者級快取管理器 Venus,以及操作 ACL、登入等的工具。客戶端需要在核心配置中選擇 Coda 檔案系統。
伺服器需要使用者級伺服器,目前不依賴於核心支援。
Venus 核心介面
Peter J. Braam
v1.0, 1997 年 11 月 9 日
本文件描述了 Venus 和 Coda 檔案系統操作所需的核心級檔案系統程式碼之間的通訊。 本文件旨在描述當前介面(版本 1.0)以及我們設想的改進。
1. 簡介¶
Coda 分散式檔案系統中的一個關鍵元件是快取管理器 Venus。
當啟用了 Coda 的系統上的程序訪問 Coda 檔案系統中的檔案時,請求將定向到作業系統中的檔案系統層。作業系統將與 Venus 通訊以服務於程序的請求。 Venus 管理永續性客戶端快取,並向 Coda 檔案伺服器和相關伺服器(例如身份驗證伺服器)發出遠端過程呼叫,以服務於從作業系統收到的這些請求。當 Venus 服務完請求後,它會將適當的返回程式碼以及與請求相關的其他資料回覆給作業系統。 可選地,Coda 的核心支援可以維護最近處理的請求的微型快取,以限制與 Venus 的互動次數。 當微型快取中的元素不再有效時,Venus 具有通知核心的功能。
本文件精確地描述了核心和 Venus 之間的這種通訊。 將給出所謂的向上呼叫和向下呼叫的定義,並帶有它們處理的資料格式。 我們還將描述由呼叫產生的語義不變式。
歷史上,Coda 是在 Mach 2.6 中的 BSD 檔案系統中實現的。核心和 Venus 之間的介面與 BSD VFS 介面非常相似。 提供了類似的功能,並且引數和返回資料的格式與 BSD VFS 非常相似。 這為在 BSD 系統中實現 Coda 的核心級檔案系統驅動程式提供了一個幾乎自然的環境。 但是,其他作業系統(如 Linux 和 Windows 95 和 NT)具有具有不同介面的虛擬檔案系統。
要在這些系統上實現 Coda,需要對 Venus/Kernel 協議進行一些逆向工程。 此外,人們發現其他系統可以從該協議的某些小型最佳化和修改中獲益匪淺。 為了促進這項工作並使未來的移植更加容易,應該非常詳細地記錄 Venus 和核心之間的通訊。 這是本文件的目標。
2. 服務 Coda 檔案系統呼叫¶
對 Coda 檔案系統服務的請求服務源於訪問 Coda 檔案的程序 P。 它發出一個系統呼叫,該呼叫會陷入到 OS 核心。 陷入核心的此類呼叫的示例是 Unix 上下文中的
read、write、open、close、create、mkdir、rmdir、chmod。 Win32 環境中存在類似的呼叫,並命名為CreateFile。通常,作業系統在虛擬檔案系統 (VFS) 層中處理請求,在 NT 中命名為 I/O 管理器,在 Windows 95 中命名為 IFS 管理器。 VFS 負責對請求進行部分處理,並負責定位將服務於請求部分的特定檔案系統。 通常,路徑中的資訊有助於定位正確的 FS 驅動程式。 有時,在經過廣泛的預處理後,VFS 開始呼叫 FS 驅動程式中匯出的例程。 這是 FS 特定請求處理開始的點,並且 Coda 特定核心程式碼在此處發揮作用。
Coda 的 FS 層必須公開和實現多個介面。 首先,VFS 必須能夠對 Coda FS 層進行所有必要的呼叫,因此 Coda FS 驅動程式必須公開 VFS 介面,如適用於作業系統。 這些作業系統之間的差異非常大,但共享諸如讀取/寫入、建立和刪除物件等功能。 Coda FS 層透過呼叫快取管理器 Venus 提供的一個或多個明確定義的服務來服務此類 VFS 請求。 當來自 Venus 的回覆返回到 FS 驅動程式時,VFS 呼叫的服務將繼續,並以回覆核心的 VFS 結束。 最後,VFS 層返回到程序。
因此,FS 驅動程式公開的基本介面必須允許 Venus 管理訊息流量。 特別是,Venus 必須能夠檢索和放置訊息,並被通知新訊息的到達。 通知必須透過一種不會阻塞 Venus 的機制,因為即使沒有訊息正在等待或處理,Venus 也必須處理其他任務。
Coda FS 驅動程式的介面
此外,FS 層還提供使用者程序和 Venus 之間的一種特殊通訊路徑,稱為 pioctl 介面。 pioctl 介面用於 Coda 特定服務,例如請求有關 Venus 管理的持久快取的詳細資訊。 在這裡,核心的參與度很小。 它識別呼叫程序並將資訊傳遞給 Venus。 當 Venus 回覆時,響應將以未修改的形式傳遞迴呼叫方。
最後,Venus 允許核心 FS 驅動程式快取來自某些服務的結果。 這樣做是為了避免過多的上下文切換併產生一個高效的系統。 但是,Venus 可能會獲取資訊,例如來自網路的資訊,這意味著必須重新整理或替換快取的資訊。 然後,Venus 向 Coda FS 層發出向下呼叫,以請求重新整理或更新快取。 核心 FS 驅動程式同步處理此類請求。
在這些介面中,VFS 介面以及放置、接收和通知訊息的功能是特定於平臺的。 我們不會深入研究匯出到 VFS 層的呼叫,但我們會說明訊息交換機制的要求。
3. 訊息層¶
在最低級別,Venus 和 FS 驅動程式之間的通訊透過訊息進行。 請求 Coda 檔案服務的程序和 Venus 之間的同步依賴於阻塞和喚醒程序。 Coda FS 驅動程式代表程序 P 處理 VFS 和 pioctl 請求,為 Venus 建立訊息,等待回覆,最後返回到呼叫方。 訊息交換的實現是特定於平臺的,但是語義(到目前為止)似乎普遍適用。 資料緩衝區由 FS 驅動程式代表 P 在核心記憶體中建立,並複製到 Venus 中的使用者記憶體。
FS 驅動程式在服務 P 時向上呼叫 Venus。 透過建立訊息結構將此類向上呼叫分派到 Venus。 該結構包含 P 的標識、訊息序列號、請求的大小以及指向核心記憶體中請求資料的指標。 由於資料緩衝區被重用來儲存來自 Venus 的回覆,因此有一個用於回覆大小的欄位。 訊息中的標誌欄位用於精確記錄訊息的狀態。 其他平臺相關的結構包括指向確定訊息在佇列上的位置的指標和指向同步物件的指標。 在向上呼叫例程中,填寫訊息結構,將標誌設定為 0,並將其放置在 _pending_ 佇列中。 呼叫向上呼叫例程負責分配資料緩衝區; 其結構將在下一節中描述。
必須存在一種通知 Venus 訊息已被建立的工具,並使用 OS 中可用的同步物件來實現。 此通知在程序 P 的向上呼叫上下文中完成。 當訊息位於掛起佇列中時,程序 P 無法在向上呼叫中繼續。 必須暫停檔案系統請求例程中 P 的(核心模式)處理,直到 Venus 回覆。 因此,P 中的呼叫執行緒在向上呼叫中被阻塞。 訊息結構中的指標將定位 P 正在休眠的同步物件。
Venus 檢測到訊息已到達的通知,FS 驅動程式允許 Venus 使用 getmsg_from_kernel 呼叫來檢索訊息。 此操作在核心中透過將訊息放置在正在處理的訊息佇列上並將標誌設定為 READ 來完成。 Venus 傳遞資料緩衝區的內容。 現在 getmsg_from_kernel 呼叫返回,Venus 處理該請求。
在稍後的某個時刻,FS 驅動程式收到來自 Venus 的訊息,即當 Venus 呼叫 sendmsg_to_kernel 時。 此時,Coda FS 驅動程式會檢視訊息的內容並確定
該訊息是否是針對暫停執行緒 P 的回覆。 如果是這樣,它將從處理佇列中刪除該訊息,並將該訊息標記為 WRITTEN。 最後,FS 驅動程式取消阻塞 P(仍在 Venus 的核心模式上下文中),並且 sendmsg_to_kernel 呼叫返回到 Venus。 程序 P 將在某個時候被排程,並繼續處理其向上呼叫,並將資料緩衝區替換為來自 Venus 的回覆。
該訊息是一個
downcall。 向下呼叫是從 Venus 到 FS 驅動程式的請求。 FS 驅動程式立即處理該請求(通常是快取驅逐或替換),並且當它完成時,sendmsg_to_kernel 返回。現在 P 醒來並繼續處理向上呼叫。 有一些微妙之處需要考慮。 首先,P 將確定它是否由於來自其他來源的訊號(例如嘗試終止 P)而在向上呼叫中被喚醒,或者像通常那樣被 Venus 在其 sendmsg_to_kernel 呼叫中被喚醒。 在正常情況下,向上呼叫例程將釋放訊息結構並返回。 FS 例程可以繼續進行其處理。
睡眠和 IPC 安排
如果 P 因訊號而不是 Venus 喚醒,它將首先檢視標誌欄位。 如果訊息尚未 READ,則程序 P 可以處理其訊號而無需通知 Venus。 如果 Venus 已 READ,並且不應處理該請求,則 P 可以向 Venus 傳送訊號訊息,以指示它應忽略先前的訊息。 此類訊號放置在佇列的頭部,並由 Venus 首先讀取。 如果訊息已被標記為 WRITTEN,則停止處理為時已晚。 VFS 例程現在將繼續。 (-- 如果 VFS 請求涉及多個向上呼叫,則這可能會導致複雜的狀態,可以在訊息結構中新增一個額外的欄位“handle_signals”,以指示已透過的不可返回點。--)
3.1. 實現細節¶
此機制的 Unix 實現已透過與 Coda 關聯的字元裝置的實現。 Venus 透過對裝置執行讀取來檢索訊息,回覆透過寫入傳送,通知透過裝置的檔案描述符上的 select 系統呼叫。 程序 P 在可中斷的等待佇列物件上保持等待狀態。
在 Windows NT 和 DPMI Windows 95 實現中,使用了 DeviceIoControl 呼叫。 DeviceIoControl 呼叫旨在透過 OPCODES 將緩衝區從使用者記憶體複製到核心記憶體。 sendmsg_to_kernel 作為同步呼叫發出,而 getmsg_from_kernel 呼叫是非同步的。 Windows EventObjects 用於通知訊息的到達。 程序 P 在 NT 中的 KernelEvent 物件和 Windows 95 中的訊號量上保持等待狀態。
4. 呼叫級別的介面¶
本節描述了 Coda FS 驅動程式可以對 Venus 進行的向上呼叫。 每個向上呼叫都使用兩個結構:inputArgs 和 outputArgs。 以偽 BNF 形式,這些結構採用以下形式
struct inputArgs { u_long opcode; u_long unique; /* Keep multiple outstanding msgs distinct */ u_short pid; /* Common to all */ u_short pgid; /* Common to all */ struct CodaCred cred; /* Common to all */ <union "in" of call dependent parts of inputArgs> }; struct outputArgs { u_long opcode; u_long unique; /* Keep multiple outstanding msgs distinct */ u_long result; <union "out" of call dependent parts of inputArgs> };在繼續之前,讓我們闡明各個欄位的作用。 inputArgs 以 opcode 開頭,該 opcode 定義了從 Venus 請求的服務型別。 目前大約有 30 個向上呼叫,我們將討論它們。 unique 欄位使用唯一編號標記 inputArg,該編號將唯一地標識該訊息。 傳遞程序 ID 和程序組 ID。 最後,包括呼叫者的憑據。
在深入研究特定呼叫之前,我們需要討論核心和 Venus 共享的各種資料結構。
4.2. pioctl 介面¶
可以透過應用程式透過 pioctl 介面發出 Coda 特定請求。 pioctl 實現為虛構檔案 /coda/.CONTROL 上的普通 ioctl。 pioctl 呼叫開啟此檔案,獲取檔案控制代碼併發出 ioctl 呼叫。 最後,它關閉該檔案。
核心對此的參與僅限於提供開啟和關閉的功能,並傳遞 ioctl 訊息,並驗證 pioctl 資料緩衝區中的路徑是否為 Coda 檔案系統中的檔案。
核心被傳遞了一個數據包,其形式為
struct { const char *path; struct ViceIoctl vidata; int follow; } data;其中
struct ViceIoctl { caddr_t in, out; /* Data to be transferred in, or out */ short in_size; /* Size of input buffer <= 2K */ short out_size; /* Maximum size of output buffer, <= 2K */ };該路徑必須是 Coda 檔案,否則將不會發出 ioctl 向上呼叫。
注意
資料結構和程式碼一團糟。 我們需要清理一下。
我們現在繼續記錄各個呼叫:
4.3. root¶
- 引數
輸入
空
輸出
struct cfs_root_out { ViceFid VFid; } cfs_root;- 描述
在 Coda 檔案系統初始化期間,會對 Venus 進行此呼叫。 如果結果為零,則 cfs_root 結構包含 Coda 檔案系統的根的 ViceFid。 如果生成非零結果,則其值是平臺相關的錯誤程式碼,指示 Venus 在定位 Coda 檔案系統的根時遇到的困難。
4.4. lookup¶
- 總結
如果目錄中存在某個物件,則查詢該物件的 ViceFid 和型別。
- 引數
輸入
struct cfs_lookup_in { ViceFid VFid; char *name; /* Place holder for data. */ } cfs_lookup;輸出
struct cfs_lookup_out { ViceFid VFid; int vtype; } cfs_lookup;- 描述
進行此呼叫是為了確定目錄條目的 ViceFid 和檔案型別。 請求的目錄條目帶有名稱“name”,Venus 將搜尋由 cfs_lookup_in.VFid 標識的目錄。 結果可能表明該名稱不存在,或者在查詢該名稱時遇到了困難(例如,由於斷開連線)。 如果結果為零,則欄位 cfs_lookup_out.VFid 包含目標 ViceFid,並且 cfs_lookup_out.vtype 包含 coda_vtype,該 coda_vtype 給出了名稱指定的物件型別。
該物件的名稱是最大長度為 CFS_MAXNAMLEN 的 8 位字串,當前設定為 256(包括 0 終止符。)
重要的是要意識到 Venus 會按位或欄位 cfs_lookup.vtype 與 CFS_NOCACHE,以指示不應將該物件放置在核心名稱快取中。
注意
vtype 的型別當前錯誤。 它應該是 coda_vtype。 Linux 不注意 CFS_NOCACHE。 它應該。
4.5. getattr¶
總結 獲取檔案的屬性。
- 引數
輸入
struct cfs_getattr_in { ViceFid VFid; struct coda_vattr attr; /* XXXXX */ } cfs_getattr;輸出
struct cfs_getattr_out { struct coda_vattr attr; } cfs_getattr;- 描述
此呼叫返回由 fid 標識的檔案的屬性。
- 錯誤
如果 fid 的物件不存在、無法訪問或者呼叫者無權獲取屬性,則會發生錯誤。
注意
許多核心 FS 驅動程式(Linux、NT 和 Windows 95)都需要獲取屬性以及 Fid,以例項化內部“inode”或“FileHandle”。 透過在 Venus/核心互動級別和 RPC 級別上都組合查詢和 getattr 呼叫,可以在此類系統上實現效能的顯著提高。
輸入引數中包含的 vattr 結構是多餘的,應將其刪除。
4.6. setattr¶
- 總結
設定檔案的屬性。
- 引數
輸入
struct cfs_setattr_in { ViceFid VFid; struct coda_vattr attr; } cfs_setattr;輸出
空
- 描述
結構 attr 填充了要以 BSD 樣式更改的屬性。 未更改的屬性設定為 -1,除了 vtype 設定為 VNON。 其他設定為要分配的值。 FS 驅動程式可能請求更改的唯一屬性是模式、所有者、groupid、atime、mtime 和 ctime。 返回值指示成功或失敗。
- 錯誤
可能會發生各種錯誤。 物件可能不存在、可能無法訪問,或者 Venus 可能未授予許可權。
4.7. access¶
- 引數
輸入
struct cfs_access_in { ViceFid VFid; int flags; } cfs_access;輸出
空
- 描述
驗證是否允許 VFid 標識的物件執行由標誌描述的操作。 結果表明是否將授予訪問許可權。 重要的是要記住,Coda 使用 ACL 來強制實施保護,並且最終伺服器而不是客戶端強制實施系統的安全性。 此呼叫的結果將取決於使用者是否持有令牌。
- 錯誤
物件可能不存在,或者描述保護的 ACL 可能無法訪問。
4.8. create¶
- 總結
呼叫以建立檔案
- 引數
輸入
struct cfs_create_in { ViceFid VFid; struct coda_vattr attr; int excl; int mode; char *name; /* Place holder for data. */ } cfs_create;輸出
struct cfs_create_out { ViceFid VFid; struct coda_vattr attr; } cfs_create;- 描述
呼叫此向上呼叫以請求建立檔案。 該檔案將在由 VFid 標識的目錄中建立,其名稱將為 name,模式將為 mode。 如果設定了 excl,則如果該檔案已存在,將返回一個錯誤。 如果 attr 中的 size 欄位設定為零,則該檔案將被截斷。 檔案的 uid 和 gid 透過使用宏 CRTOUID(此宏與平臺相關)將 CodaCred 轉換為 uid 來設定。 成功後,將返回該檔案的 VFid 和屬性。 Coda FS 驅動程式通常會在核心級別為新物件例項化 vnode、inode 或檔案控制代碼。
- 錯誤
可能會發生各種錯誤。 許可權可能不足。 如果該物件存在並且不是檔案,則在 Unix 下返回錯誤 EISDIR。
注意
引數的打包效率非常低,並且似乎表明系統呼叫 creat 和 VFS 操作 create 之間存在混淆。 僅呼叫 VFS 操作 create 來建立新物件。 此建立呼叫與 Unix 中的建立呼叫不同,因為它不會被呼叫來返回檔案描述符。 截斷和獨佔選項以及模式可以簡單地成為模式的一部分,就像在 Unix 下一樣。 不應有標誌引數; 這在 open (2) 中用於返回 READ 或 WRITE 模式的檔案描述符。
目錄的屬性也應該返回,因為大小和 mtime 發生了變化。
4.9. mkdir¶
- 總結
建立一個新目錄。
- 引數
輸入
struct cfs_mkdir_in { ViceFid VFid; struct coda_vattr attr; char *name; /* Place holder for data. */ } cfs_mkdir;輸出
struct cfs_mkdir_out { ViceFid VFid; struct coda_vattr attr; } cfs_mkdir;- 描述
此呼叫類似於 create,但會建立一個目錄。 只有輸入引數中的 mode 欄位用於建立。 成功建立後,返回的 attr 包含新目錄的屬性。
- 錯誤
與 create 相同。
注意
輸入引數應更改為模式,而不是屬性。
應該返回父目錄的屬性,因為大小和 mtime 發生了變化。
4.10. link¶
- 總結
建立一個指向現有檔案的連結。
- 引數
輸入
struct cfs_link_in { ViceFid sourceFid; /* cnode to link *to* */ ViceFid destFid; /* Directory in which to place link */ char *tname; /* Place holder for data. */ } cfs_link;輸出
空
- 描述
此呼叫使用名稱 tname 在由 destFid 標識的目錄中建立指向 sourceFid 的連結。 源必須駐留在目標的父目錄中,即源必須具有父目錄 destFid,即 Coda 不支援跨目錄硬連結。 只有返回值是相關的。 它指示成功或失敗的型別。
- 錯誤
可能會發生常見的錯誤。
4.11. symlink¶
- 總結
建立一個符號連結
- 引數
輸入
struct cfs_symlink_in { ViceFid VFid; /* Directory to put symlink in */ char *srcname; struct coda_vattr attr; char *tname; } cfs_symlink;輸出
無
- 描述
建立一個符號連結。 該連結將放置在由 VFid 標識的目錄中,並命名為 tname。 它應該指向路徑名 srcname。 新建立的物件的屬性將設定為 attr。
注意
應該返回目標目錄的屬性,因為其大小發生了變化。
4.12. remove¶
- 總結
刪除一個檔案
- 引數
輸入
struct cfs_remove_in { ViceFid VFid; char *name; /* Place holder for data. */ } cfs_remove;輸出
無
- 描述
刪除由 VFid 標識的目錄中名為 cfs_remove_in.name 的檔案。
注意
應該返回目錄的屬性,因為其 mtime 和大小可能會發生變化。
4.13. rmdir¶
- 總結
刪除一個目錄
- 引數
輸入
struct cfs_rmdir_in { ViceFid VFid; char *name; /* Place holder for data. */ } cfs_rmdir;輸出
無
- 描述
從 VFid 標識的目錄中刪除名稱為“name”的目錄。
注意
應該返回父目錄的屬性,因為其 mtime 和大小可能會發生變化。
4.14. readlink¶
- 總結
讀取符號連結的值。
- 引數
輸入
struct cfs_readlink_in { ViceFid VFid; } cfs_readlink;輸出
struct cfs_readlink_out { int count; caddr_t data; /* Place holder for data. */ } cfs_readlink;- 描述
此例程將由 VFid 標識的符號連結的內容讀取到緩衝區資料中。 緩衝區資料必須能夠容納任何最大為 CFS_MAXNAMLEN(PATH 或 NAM??)的名稱。
- 錯誤
沒有不尋常的錯誤。
4.15. open¶
- 總結
開啟一個檔案。
- 引數
輸入
struct cfs_open_in { ViceFid VFid; int flags; } cfs_open;輸出
struct cfs_open_out { dev_t dev; ino_t inode; } cfs_open;- 描述
此請求要求 Venus 將由 VFid 標識的檔案放置在其快取中,並注意到呼叫程序希望使用 open(2) 中的標誌將其開啟。 返回到核心的返回值對於 Unix 和 Windows 系統有所不同。 對於 Unix 系統,將通知 Coda FS 驅動程式容器檔案的裝置和 inode 編號,這些編號在欄位 dev 和 inode 中。 對於 Windows,容器檔案的路徑將返回到核心。
注意
當前,cfs_open_out 結構未正確適應處理 Windows 情況。 最好實現兩個向上呼叫,一個向上呼叫旨在針對容器檔名開啟,另一個向上呼叫針對容器檔案 inode 開啟。
4.16. close¶
- 總結
關閉一個檔案,並在伺服器上更新它。
- 引數
輸入
struct cfs_close_in { ViceFid VFid; int flags; } cfs_close;輸出
無
- 描述
關閉由 VFid 標識的檔案。
注意
flags 引數是虛假的,未使用。 但是,Venus 的程式碼有空間來處理 execp 輸入欄位,可能該欄位應用於通知 Venus 檔案已關閉但仍對映到記憶體以進行執行。 有關在 Venus vproc_vfscalls 中獲取與不獲取資料的註釋。 這似乎很傻。 如果要關閉檔案,則容器檔案中的資料將成為新資料。 同樣,execp 標誌可能會起作用以造成混淆:當前,Venus 可能會認為檔案仍然對映到記憶體時可以從快取中重新整理該檔案。 這需要理解。
4.17. ioctl¶
- 總結
在檔案上執行 ioctl。 這包括 pioctl 介面。
- 引數
輸入
struct cfs_ioctl_in { ViceFid VFid; int cmd; int len; int rwflag; char *data; /* Place holder for data. */ } cfs_ioctl;輸出
struct cfs_ioctl_out { int len; caddr_t data; /* Place holder for data. */ } cfs_ioctl;- 描述
在檔案上執行 ioctl 操作。 command、len 和 data 引數按 usual 填充。 Venus 不使用標誌。
注意
另一個虛假引數。 不使用標誌。 Venus 程式碼中的 PREFETCHING 業務是什麼?
4.18. rename¶
- 總結
重新命名一個 fid。
- 引數
輸入
struct cfs_rename_in { ViceFid sourceFid; char *srcname; ViceFid destFid; char *destname; } cfs_rename;輸出
無
- 描述
將目錄 sourceFid 中名稱為 srcname 的物件重新命名為 destFid 中的 destname。 重要的是名稱 srcname 和 destname 是以 0 結尾的字串。 Unix 核心中的字串並不總是以 null 結尾的。
4.19. readdir¶
- 總結
讀取目錄條目。
- 引數
輸入
struct cfs_readdir_in { ViceFid VFid; int count; int offset; } cfs_readdir;輸出
struct cfs_readdir_out { int size; caddr_t data; /* Place holder for data. */ } cfs_readdir;- 描述
從 VFid 讀取目錄條目,從偏移量 offset 開始,最多讀取 count 個位元組。 在資料中返回資料,並在大小中返回大小。
注意
不使用此呼叫。 Readdir 操作利用容器檔案。 在即將進行的目錄改版期間,我們將重新評估此問題。
4.20. vget¶
- 總結
指示 Venus 執行 FSDB->Get。
- 引數
輸入
struct cfs_vget_in { ViceFid VFid; } cfs_vget;輸出
struct cfs_vget_out { ViceFid VFid; int vtype; } cfs_vget;- 描述
此向上呼叫要求 Venus 對 VFid 標記的 fsobj 執行 get 操作。
注意
不使用此操作。 但是,它非常有用,因為它可以用於處理讀/寫記憶體對映檔案。 可以使用 vget 將它們“固定”在 Venus 快取中,並使用 inactive 釋放它們。
4.21. fsync¶
- 總結
告訴 Venus 更新檔案的 RVM 屬性。
- 引數
輸入
struct cfs_fsync_in { ViceFid VFid; } cfs_fsync;輸出
無
- 描述
要求 Venus 更新物件 VFid 的 RVM 屬性。 這應該作為核心級別 fsync 型別呼叫的一部分來呼叫。 結果表明同步是否成功。
注意
Linux 不實現此呼叫。 它應該。
4.22. inactive¶
- 總結
告訴 Venus vnode 不再使用。
- 引數
輸入
struct cfs_inactive_in { ViceFid VFid; } cfs_inactive;輸出
無
- 描述
此操作返回 EOPNOTSUPP。
注意
這也許應該刪除。
4.23. rdwr¶
- 總結
從檔案讀取或寫入
- 引數
輸入
struct cfs_rdwr_in { ViceFid VFid; int rwflag; int count; int offset; int ioflag; caddr_t data; /* Place holder for data. */ } cfs_rdwr;輸出
struct cfs_rdwr_out { int rwflag; int count; caddr_t data; /* Place holder for data. */ } cfs_rdwr;- 描述
此向上呼叫要求 Venus 從檔案讀取或寫入。
注意
應該刪除它,因為它與 Coda 的理念背道而馳,即讀取/寫入操作永遠不會到達 Venus。 有人告訴我該操作不起作用。 當前未使用。
4.24. odymount¶
- 總結
允許在一個 Unix 掛載點上掛載多個 Coda “檔案系統”。
- 引數
輸入
struct ody_mount_in { char *name; /* Place holder for data. */ } ody_mount;輸出
struct ody_mount_out { ViceFid VFid; } ody_mount;- 描述
要求 Venus 返回名為 name 的 Coda 系統的 rootfid。 該 fid 在 VFid 中返回。
注意
David 曾使用此呼叫來進行動態集操作。它應該被移除,因為它會在 VFS 掛載區域造成指標的混亂。Coda 本身並沒有使用它。Venus 沒有實現此呼叫。
4.25. ody_lookup¶
- 總結
查詢某些東西。
- 引數
輸入
不相關
輸出
不相關
注意
刪除它。Venus 沒有實現此呼叫。
4.26. ody_expand¶
- 總結
在動態集中擴充套件某些東西。
- 引數
輸入
不相關
輸出
不相關
注意
刪除它。Venus 沒有實現此呼叫。
4.27. prefetch¶
- 總結
預取一個動態集。
引數
輸入
沒有文件。
輸出
沒有文件。
- 描述
Venus 的 worker.cc 擁有對此呼叫的支援,儘管已經註明它不能工作。這並不奇怪,因為核心沒有對此呼叫提供支援。(ODY_PREFETCH 未被定義的操作)。
注意
刪除它。它不能工作,並且 Coda 沒有使用它。
4.28. signal¶
- 總結
向 Venus 傳送一個關於 upcall 的訊號。
- 引數
輸入
無
輸出
不適用。
- 描述
這是一個帶外的 upcall,用於通知 Venus:呼叫程序在 Venus 從輸入佇列讀取訊息後接收到一個訊號。Venus 應該清理該操作。
- 錯誤
沒有給出回覆。
注意
我們需要更好地理解 Venus 需要清理什麼,以及它是否正確地執行了清理。此外,我們需要正確地處理每個系統呼叫多次 upcall 的情況。重要的是要知道在核心負責通知 Venus 清理的 upcall 之後,Venus 發生了哪些狀態變化(例如,open 肯定是一個這樣的狀態變化,但許多其他的可能不是)。
5. 迷你快取和 downcall¶
Coda FS 驅動程式可以快取查詢和訪問 upcall 的結果,以限制 upcall 的頻率。Upcall 帶來成本,因為需要進行程序上下文切換。快取資訊的對應物是 Venus 將通知 FS 驅動程式,快取的條目必須被重新整理或重新命名。
核心程式碼通常需要維護一個結構,將內部檔案控制代碼(在 BSD 中稱為 vnode,在 Linux 中稱為 inode,在 Windows 中稱為 FileHandle)與 Venus 維護的 ViceFid 連結起來。原因是需要頻繁地進行來回轉換,以便發出 upcall 並使用 upcall 的結果。這樣的連結物件被稱為 cnode。
當前迷你快取的實現具有記錄以下內容的快取條目:
檔案的名稱
包含物件的目錄的 cnode
允許查詢的 CodaCred 的列表。
物件的 cnode
Coda FS 驅動程式可以透過傳遞物件的名稱、目錄和呼叫者的 CodaCred,從快取中請求所需物件的 cnode。快取將返回 cnode 或指示無法找到它。當 Coda FS 驅動程式修改或刪除物件時,必須小心地使快取條目失效。
當 Venus 獲得表明快取條目不再有效的資訊時,它將對核心進行 downcall。Downcall 被 Coda FS 驅動程式攔截,並導致以下描述的快取失效。除非 downcall 資料無法讀取到核心記憶體中,否則 Coda FS 驅動程式不會返回錯誤。
5.1. INVALIDATE¶
沒有關於此呼叫的資訊可用。
5.2. FLUSH¶
- 引數
無
- 總結
完全重新整理名稱快取。
- 描述
Venus 在啟動和死亡時發出此呼叫。這是為了防止持有過時的快取資訊。某些作業系統允許動態關閉核心名稱快取。當這樣做時,會發出此 downcall。
5.3. PURGEUSER¶
- 引數
struct cfs_purgeuser_out {/* CFS_PURGEUSER is a venus->kernel call */ struct CodaCred cred; } cfs_purgeuser;- 描述
刪除快取中攜帶 Cred 的所有條目。當用戶的令牌過期或被重新整理時,會發出此呼叫。
5.4. ZAPFILE¶
- 引數
struct cfs_zapfile_out { /* CFS_ZAPFILE is a venus->kernel call */ ViceFid CodaFid; } cfs_zapfile;- 描述
刪除具有 (dir vnode, name) 對的所有條目。 這是因為 vnode 的快取屬性失效而發出的。
注意
在 NetBSD 和 Mach 中,此呼叫的名稱不正確。迷你快取 zapfile 例程採用不同的引數。Linux 沒有正確實現屬性的失效。
5.5. ZAPDIR¶
- 引數
struct cfs_zapdir_out { /* CFS_ZAPDIR is a venus->kernel call */ ViceFid CodaFid; } cfs_zapdir;- 描述
刪除快取中位於目錄 CodaFid 中的所有條目,以及該目錄的所有子項。當 Venus 接收到目錄的回撥時,會發出此呼叫。
5.6. ZAPVNODE¶
- 引數
struct cfs_zapvnode_out { /* CFS_ZAPVNODE is a venus->kernel call */ struct CodaCred cred; ViceFid VFid; } cfs_zapvnode;- 描述
刪除快取中攜帶 cred 和 VFid 的所有條目,如引數所示。這個 downcall 可能永遠不會發出。
5.7. PURGEFID¶
- 引數
struct cfs_purgefid_out { /* CFS_PURGEFID is a venus->kernel call */ ViceFid CodaFid; } cfs_purgefid;- 描述
重新整理檔案的屬性。如果它是一個目錄(奇數 vnode),則從 namecache 中清除其子項,並從 namecache 中刪除該檔案。
5.8. REPLACE¶
- 總結
替換名稱集合的 Fid。
- 引數
struct cfs_replace_out { /* cfs_replace is a venus->kernel call */ ViceFid NewFid; ViceFid OldFid; } cfs_replace;- 描述
此例程用另一個替換名稱快取中的 ViceFid。新增它是為了允許 Venus 在重新整合期間,即使這些 fid 上的引用計數不為零,也能用全域性 fid 替換本地分配的臨時 fid (當與網路斷開時)。
6. 初始化和清理¶
本節簡要提示 Coda FS 驅動程式在啟動和關閉時或 Venus 發生故障時需要的功能。在進入討論之前,有必要重複一下 Coda FS 驅動程式維護以下資料
訊息佇列
cnodes
名稱快取條目
名稱快取條目完全是驅動程式私有的,因此可以很容易地操作它們。訊息佇列通常具有清晰的初始化和銷燬點。 cnodes 更加微妙。使用者程序在 Coda 檔案系統中持有引用計數,因此很難清理 cnodes。
它可以期望透過以下方式發出請求
訊息子系統
VFS 層
pioctl 介面
目前 pioctl 透過 Coda 的 VFS 傳遞,因此我們可以類似地對待它們。
6.1. 要求¶
應滿足以下要求
訊息佇列應具有開啟和關閉例程。在 Unix 上,開啟字元裝置就是這樣的例程。
在開啟之前,不能放置任何訊息。
開啟將刪除任何仍在掛起的舊訊息。
關閉將通知任何睡眠程序,它們的 upcall 無法完成。
關閉將釋放訊息佇列分配的所有記憶體。
在開啟時,名稱快取應初始化為空狀態。
在訊息佇列開啟之前,所有 VFS 操作都將失敗。幸運的是,這可以透過確保在開啟之前無法成功掛載 Coda 檔案系統來實現。
關閉佇列後,不能成功進行任何 VFS 操作。這裡需要小心,因為一些操作(lookup, read/write, readdir)可以在沒有 upcall 的情況下進行。必須顯式阻止這些操作。
關閉時,應重新整理並停用名稱快取。
可以釋放 cnode 持有的所有記憶體,而無需依賴 upcall。
解除安裝檔案系統可以在不依賴 upcall 的情況下完成。
如果 Venus 無法獲得 rootfid 或 rootfid 的屬性,則掛載 Coda 檔案系統應優雅地失敗。最好的實現方法是 Venus 在嘗試掛載之前獲取這些物件。
注意
特別是 NetBSD,還有 Linux,尚未完全實現上述要求。為了平穩執行,需要對此進行糾正。