Linux Kernel 2.2 Documentation:
/usr/src/linux/Documentation/filesystems/coda.txt
filesystems/coda.txt
CODA ファイルシステムの解説
[プレインテキスト版]
- 原著作者: Peter J. Braam <braam@cs.cmu.edu>
- 翻訳者: 野本浩一 <hng@ps.ksky.ne.jp>
- バージョン: 2.2.18
- 翻訳日時: 2001/12/25
注記:
これは Coda の構成要素について書かかれているもので、この文書は、クライ
アントのカーネルと Venus 間のインターフェースについて技術的な説明をし
ています。
詳しくは次のところを参照してください -
http://www.coda.cs.cmu.edu
Coda を実行するのに必要なユーザレベルのソフトウェアは次のところにあり
ます -
ftp://ftp.coda.cs.cmu.edu
Coda を実行するために、Venus というクライアント向けユーザレベルキャッ
シュマネージャおよび ACL 操作やログインなどのためのツールも入手しなけ
ればなりません。クライアントはカーネルコンフィギュレーションで Coda ファ
イルシステムを選択しなければなりません。
サーバはユーザレベルのサーバを必要とし、今のところカーネルサポートには
依存していません。
The Venus kernel interface
Peter J. Braam
v1.2, Mar 18, 1998
野本 浩一 (hng@ps.ksky.or.jp)
v1.2j, November 26, 2001
この文書は Coda ファイルシステムの操作に必要な Venus とカーネルレベル
ファイルシステムのコードとの間のコミュニケーションについて記述します。
この文書改訂で現行のインターフェース (バージョン 1.0) と、私たちが考え
ている改善についても記述しています。
______________________________________________________________________
目次
1. はじめに
2. Coda ファイルシステムサービス用のコール
3. メッセージ層
3.1 実装の詳細
4. コールレベルのインターフェース
4.1 カーネルと Venus に共有されるデータ構造体
4.2 pioctl インターフェース
4.3 root
4.4 lookup
4.5 getattr
4.6 setattr
4.7 access
4.8 create
4.9 mkdir
4.10 link
4.11 symlink
4.12 remove
4.13 rmdir
4.14 readlink
4.15 open
4.16 close
4.17 ioctl
4.18 rename
4.19 readdir
4.20 vget
4.21 fsync
4.22 inactive
4.23 rdwr
4.24 odymount
4.25 ody_lookup
4.26 ody_expand
4.27 prefetch
4.28 signal
5. ミニキャッシュと downcall
5.1 INVALIDATE
5.2 FLUSH
5.3 PURGEUSER
5.4 ZAPFILE
5.5 ZAPDIR
5.6 ZAPVNODE
5.7 PURGEFID
5.8 REPLACE
6. 初期化とクリーンアップ
6.1 必須条件
7. Inode 番号
8. 日本語訳について
______________________________________________________________________
1. はじめに
Coda 分散ファイルシステムの鍵となる構成要素はキャッシュマネージャ
Venus です。
システムで Coda が有効な場合、プロセスが Coda ファイルシステム内のファ
イルにアクセスする際に、要求はオペレーティングシステム内のファイルシス
テム層に転送されます。プロセスの要求をサービスするために、オペレーティ
ングシステムは Venus と通信するでしょう。Venus はオペレーティングシス
テムからの要求を受信し、これをサービスするために永続的なクライアント
キャッシュを管理し、Coda ファイルサーバおよび (認証サーバのような) 関
連するサーバへリモートプロシージャコールを行います。Venus が要求のサー
ビスを完了した場合、適切なリターンコードおよび要求に関連するデータをオ
ペレーティングシステムへ応答します。実装は任意ですが、Coda のカーネル
サポートは Venus との会話を減らすために、最近処理した要求のミニキャッ
シュを保持するようにも出来ます。Venus はそのミニキャッシュの要素が無効
になった際に、そのことをカーネルに通知する機構を持っています。
この文書はカーネルと Venus 間のコミュニケーションの細部について記述し
ます。upcall および downcall と呼ばれる機構の定義を、それらが扱うデー
タのフォーマットとともに説明します。コールの結果の意味の不変部も記述し
ます。
歴史的に Coda は Mach 2.6 の BSD ファイルシステムで実装されました。カ
ーネルと Venus 間のインターフェースは BSD VFS インターフェースにとても
似ています。同様の機能性を提供し、引き数および返されるデータのフォー
マットも BSD VFS にとても似ています。これは BSD システムで Coda 用カー
ネルレベルファイルシステムドライバを実装するためのとても自然な環境をも
たらします。しかしながら、Linux や Windows95, NT のような他のオペレー
ティングシステムは、異なるインターフェースを備えたバーチャルファイルシ
ステムを持っています。
これらのシステム上で Coda を実装するには、Venus/カーネルプロトコルのリ
バースエンジニアリングが必要です。さらに、プロトコルに対するいくつかの
小さな最適化や修正により、他のシステムでは著しく性能の向上が図れること
が明らかになっています。この作業を促進し将来の移植を容易にするため
に、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 ドライバがエクスポートしているルーチンの呼び
出しを開始する場合もあります。ここが要求のファイルシステム固有な処理を
開始する地点で、ここで Coda 固有のカーネルコードが動き始めます。
Coda 用 FS 層はいくつかのインターフェースを公開し実装しなければなりま
せん。まず第一に、VFS は Coda FS 層への必要なコールをすべて行えなけれ
ばならないので、Coda FS ドライバはオペレーティングシステムで使える形式
で、 VFS インターフェースを公開しなければなりません。これらはオペレー
ティングシステム間で著しく異なりますが、オブジェクトを読む/書く、作成
する、削除する、ための機構といった機能で分かれます。Coda FS 層は、呼び
出しによる VFS 要求や、キャッシュマネージャ Venus から依頼される多くの
かなり明確なサービスを、サービスします。Venus からの応答が FS ドライバ
に返された場合、 VFS コールのサービスを続けて、カーネルの VFS への応答
を伴い終了します。最後に VFS 層はプロセスへ返ります。
この設計の結果、FS ドライバに公開された基本インターフェースは、メッセ
ージトラフィックの管理を Venus にさせるようにしなければなりません。特
に Venus はメッセージの受け取りおよび発行、新しいメッセージの到着の通
知を受けることができなければなりません。メッセージを待っていない場合や
メッセージを処理している場合でも、Venus は他のタスクに注意を払わなけれ
ばならないので、通知は Venus をブロックしない仕組みになっていなければ
なりません。
さらに、FS 層は、ユーザプロセスと Venus 間の pioctl インターフェースと
呼ばれる特別なコミュニケーションパスを提供します。pioctl インターフェ
ースは、Venus に管理される永続的なキャッシュに関する詳細な情報を要求す
るような、Coda 固有のサービスのために使われます。これはカーネルの関与
を最小限にします。呼び出しているプロセスを識別し、Venus へ情報を渡しま
す。Venus が応答する時、応答は修正されずに呼び出し元に返されます。
最後に、Venus は、カーネル FS ドライバが特定のサービスの結果をキャッ
シュすることを許します。これは過度のコンテキストスイッチを回避させ、結
果的に効率的なシステムにしています。しかしながら、Venus は、例えば
キャッシュされた情報をフラッシュもしくは置きかえなければならないという
情報をネットワークから得るかもしれません。そのような場合には Venus は
キャッシュ内をフラッシュあるいは更新する要求を Coda FS 層に downcall
します。カーネル FS ドライバはこのような要求を同期して扱います。
これらのインターフェースの中で、VFS インターフェースおよびメッセージを
発行、受け取る、通知を受ける機構はプラットフォーム固有です。VFS 層にエ
キスポートされたコールの説明は行いませんが、メッセージ交換の仕組みに必
要なことは述べます。
3. メッセージ層
最下層では、Venus と FS ドライバ間のコミュニケーションはメッセージに
よって進みます。Coda ファイルサービスを要求するプロセスと Venus 間の同
期は block (休止状態への移行) と wake (スケジュール待ち状態への移行)
に依ります。Coda FS ドライバはプロセス P のために VFS および pioctl の
要求を処理し、Venus 向けのメッセージを作成し、応答を待ち、最後に呼び出
し元に返ります。メッセージの交換の実装はプラットフォーム固有ですが、仕
組みは一般的に適用可能であると (今のところ) 考えています。プロセス P
用のためのデータバッファはカーネルメモリの中に FS ドライバによって作成
され、Venus 内のユーザメモリにコピーされます。
P をサービスする間 FS ドライバは Venus への upcall を行います。このよ
うな upcall はメッセージ構造体を作成することで、Venus へ送られます。構
造体は、P の識別子、メッセージシーケンス番号、要求のサイズおよび要求用
のカーネルメモリ内のデータへのポインタを含みます。データバッファは
Venus から応答を保持するために再利用されるので、返答のサイズ用のフィー
ルドがあります。フラグフィールドはメッセージの状態を正確に記録するため
にメッセージの中で使用されます。さらにプラットフォーム依存の構造体のメ
ンバ (キュー上のメッセージの位置を決めるポインタおよび同期化オブジェク
トへのポインタなど) があります。upcall ルーチンの中でメッセージ構造体
の諸情報が記入され、フラグは 0 に設定され、待機キューに置かれます。デ
ータバッファの割当ては upcall を呼ぶルーチンの責任です - データバッ
ファの構造は次のセクションで説明します。
メッセージが作成されたことを通知する機構が存在し、かつ OS 内で利用可能
な同期化オブジェクトを用いて実装されていなければなりません。この通知は
プロセス P の upcall コンテキストの中で行われます。メッセージが待機
キュー上にある時、プロセス P は upcall を行えません。ファイルシステム
要求ルーチン内の P の (カーネルモードの) 処理は、Venus が応答するま
で、サスペンドされなければなりません。したがって、P からスレッドを呼ぼ
うとすると upcall 中でブロックされます。メッセージ構造体のポインタは P
をスリープさせている同期化オブジェクトを示すでしょう。
Venus はメッセージが到着した通知を検出し、Venus は FS ドライバから
getmsg_from_kernel コールでメッセージを受け取ります。このコールの処理
はカーネル内で、処理するメッセージのキュー上にメッセージを置き、 READ
のフラグを設定することで終わります。Venus にはデータバッファの内容が渡
されます。getmsg_from_kernel コールは呼び出し元に返り、Venus は要求を
処理します。
すこししてから、FS ドライバは Venus からメッセージを受け取ります。具体
的には Venus が sendmsg_to_kernel をコールした際です。この時、 Coda FS
ドライバはメッセージの内容を見て、以下の分類を行い何をするか決定します
-
o メッセージがサスペンドされたスレッド P 向けの応答だった場合。この場
合、処理キューからメッセージを削除し、メッセージに WRITTEN とマーク
します。最後に FS ドライバは (Venus のカーネルモードのコンテキスト
中から) P をアンブロックし、sendmsg_to_kernel コールは Venus に返り
ます。プロセス P はその後スケジュールされ、Venus からの応答に置き換
えられたデータバッファを用いて upcall の処理を続けます。
o メッセージは downcall の場合。downcall は Venus から FS ドライバへ
の要求です。FS ドライバは要求を直ちに処理 (通常キャッシュの追い立て
か置き換え) し、終わった時、sendmsg_to_kernel は返ります。
この後 P は起きて upcall の処理を続けます。説明の必要な微妙なことがあ
ります。始めに P は、他のソースからシグナルにより upcall の中で起こさ
れた (例えば P を終了しようとした) か、もしくは sendmsg_to_kernel コー
ルから戻ったことで普通に Venus により起こされたか、を決定することにな
ります。通常の場合では、upcall を行ったルーチンはメッセージ構造体を解
放して返りますが、その際に FS ルーチンが upcall 処理を続けることがあり
ます。
Sleeping and IPC arrangements
P が Venus ではなくシグナルによって起こされる場合、始めにフラグフィー
ルドを見ます。メッセージがまだ READ でない場合、プロセス P は、Venus
に通知することなくそれを扱うことができます。Venus がそのメッセージをす
でに読んでおり (フラグが READ である)、要求を処理すべきではない場合、P
は前のメッセージを無視すべきことを示すシグナルメッセージを、Venus に送
ることができます。このようなシグナルはキューの先頭に置かれ、Venus は始
めに読みます。メッセージがすでに WRITTEN とマークされている場合、処理
を止めるには遅すぎます。VFS ルーチンはこの時点で続行します。 (-- VFS
要求が二つ以上の upcall を含む場合、これは複雑な状態になる可能性があり
ます。この場合の対処のため、すでに通過した返らない場所を示す特別なフィ
ールド "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 に行える upcall について記述
します。これらそれぞれの upcall は三つの構造体を使用し行われます - カ
ーネルから Venus への通信用 inputArgs、Venus からカーネルに返る
outputArgs、最後に cfs_downcalls で Venus からカーネルを起動する際に使
われます。
union inputArgs {
struct cfs_in_hdr ih; /* NB: every struct below begins with an ih */
struct cfs_open_in cfs_open;
struct cfs_close_in cfs_close;
struct cfs_ioctl_in cfs_ioctl;
struct cfs_getattr_in cfs_getattr;
struct cfs_setattr_in cfs_setattr;
struct cfs_access_in cfs_access;
struct cfs_lookup_in cfs_lookup;
struct cfs_create_in cfs_create;
struct cfs_remove_in cfs_remove;
struct cfs_link_in cfs_link;
struct cfs_rename_in cfs_rename;
struct cfs_mkdir_in cfs_mkdir;
struct cfs_rmdir_in cfs_rmdir;
struct cfs_readdir_in cfs_readdir;
struct cfs_symlink_in cfs_symlink;
struct cfs_readlink_in cfs_readlink;
struct cfs_fsync_in cfs_fsync;
struct cfs_inactive_in cfs_inactive;
struct cfs_vget_in cfs_vget;
struct cfs_rdwr_in cfs_rdwr;
struct cfs_open_by_path_in cfs_open_by_path;
};
union outputArgs {
struct cfs_out_hdr oh; /* NB: every struct below begins with an oh */
struct cfs_root_out cfs_root;
struct cfs_open_out cfs_open;
struct cfs_ioctl_out cfs_ioctl;
struct cfs_getattr_out cfs_getattr;
struct cfs_lookup_out cfs_lookup;
struct cfs_create_out cfs_create;
struct cfs_mkdir_out cfs_mkdir;
struct cfs_readdir_out cfs_readdir;
struct cfs_readlink_out cfs_readlink;
struct cfs_vget_out cfs_vget;
struct cfs_purgeuser_out cfs_purgeuser;
struct cfs_zapfile_out cfs_zapfile;
struct cfs_zapdir_out cfs_zapdir;
struct cfs_zapvnode_out cfs_zapvnode;
struct cfs_purgefid_out cfs_purgefid;
struct cfs_rdwr_out cfs_rdwr;
struct cfs_replace_out cfs_replace;
struct cfs_open_by_path_out cfs_open_by_path;
};
union cfs_downcalls {
/* CFS_FLUSH is also a down call */
struct cfs_purgeuser_out purgeuser;
struct cfs_zapfile_out zapfile;
struct cfs_zapdir_out zapdir;
struct cfs_zapvnode_out zapvnode;
struct cfs_purgefid_out purgefid;
struct cfs_replace_out replace;
};
ヘッダーはすべてのコールに共通で、プロセス、認証、opcode の情報を含み
ます -
struct cfs_in_hdr {
unsigned long opcode;
unsigned long unique; /* Keep multiple outstanding msgs distinct */
u_short pid; /* Common to all */
u_short pgid; /* Common to all */
u_short sid; /* to become the PAG */
struct coda_cred cred; /* to become a PAG */
};
/* Really important that opcode and unique are 1st two fields! */
struct cfs_out_hdr {
unsigned long opcode;
unsigned long unique;
unsigned long result;
};
先に進む前に、様々なフィールドの役割を説明します。inputArgs は、Venus
から要求されるサービスの種類を定義した opcode で始まります。30 ほどの
upcall があり、後で説明します。unique フィールドはメッセージを一意に識
別するユニークな数で inputArg を識別します。プロセスおよびプロセスグル
ープの id も渡されます。最後に、呼び出し元の信頼度の情報が含まれます。
特定のコールを調べる前に、カーネルと Venus に共有される様々なデータ構
造体を知る必要があります。
4.1. カーネルと Venus に共有されるデータ構造体
CodaCred 構造体は user および group id に関する様々なものを定義し、呼
び出し元のプロセスによって設定されます。vuid_t および guid_t は 32
ビット符号なし整数です。配列内の group メンバシップも定義します。 Unix
上では CodaCred は Coda 用のよいセキュリティの仕組みの実装に十分である
と分かっていますが、Windows 環境でのセキュリティ環境の成熟にあわせた構
造体の修正をしなければならないかもしれません。
struct CodaCred {
vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
vgid_t cr_gid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
vgid_t cr_groups[NGROUPS]; /* Group membership for caller */
};
注記 Venus 内で CodaCreds が必要かどうかは、疑問です。最終的に、 Venus
は デフォルトの uid/gid を持ったファイルを作成するとはいえ、Venus は
group について知りません。たぶん group メンバシップのリストは余分で
す。
次のアイテムは Coda ファイルを識別するために使われる基本的な識別子
ViceFid です。ファイルの fid は cell 内の Coda ファイルシステムのファ
イルもしくはディレクトリを一意的に定義します。 (-- cell は単一の
system control machine (SCM) の保護下で稼動する Coda サーバのグループ
です。--)
typedef struct ViceFid {
VolumeId Volume;
VnodeId Vnode;
Unique_t Unique;
} ViceFid;
構成中の各フィールド - VolumeId,VnodeId, Unique_t は符号なし 32 ビット
整数です。Coda cell を識別するためにもう一つフィールドを前に付ける必要
があるだろうと考えています - これはたぶん、DNS によって Coda cell を指
定する Ipv6 サイズの IP アドレスの形式になるでしょう。
Venus とカーネル間で共有された次に重要な構造体はファイルの属性です。続
く構造体は情報交換に使用されます。それはデバイスファイル向けのサポート
(現状 Coda にはありません) のような将来の拡張用の場所があります。
struct coda_vattr {
enum coda_vtype va_type; /* vnode type (for create) */
u_short va_mode; /* files access mode and type */
short va_nlink; /* number of references to file */
vuid_t va_uid; /* owner user id */
vgid_t va_gid; /* owner group id */
long va_fsid; /* file system id (dev for now) */
long va_fileid; /* file id */
u_quad_t va_size; /* file size in bytes */
long va_blocksize; /* blocksize preferred for i/o */
struct timespec va_atime; /* time of last access */
struct timespec va_mtime; /* time of last modification */
struct timespec va_ctime; /* time file changed */
u_long va_gen; /* generation number of file */
u_long va_flags; /* flags defined for file */
dev_t va_rdev; /* device special file represents */
u_quad_t va_bytes; /* bytes of disk space held by file */
u_quad_t va_filerev; /* file modification number */
u_int va_vaflags; /* operations flags, see below */
long va_spare; /* remain quad aligned */
};
4.2. pioctl インターフェース
Coda ファイルシステムに固有の要求を、pioctl インターフェースを介して、
アプリケーションから行うことができます。pioctl は仮想ファイル
/coda/.CONTROL に対する普通の ioctl として実装されます。pioctl コール
はこのファイルを開き、ファイルハンドルを得て ioctl コールを行います。
最後にそのファイルを閉じます。
ここでのカーネルの関与は open, close, 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 */
};
pathは Coda ファイルでなければならず、そうでなければ ioctl upcall は行
われないでしょう。
注記 データ構造体およびコードはむちゃくちゃです。これを整理する必要が
あります。
個々のコールを説明します -
4.3. root
引き数
入力
空
出力
struct cfs_root_out {
ViceFid VFid;
} cfs_root;
詳細 このコールは Coda ファイルシステムの初期化中に Venus へ行われま
す。結果が 0 なら、cfs_root 構造体には Coda ファイルシステムのルートの
ViceFid が入っています。0 でない結果が生成される場合、その値は Coda
ファイルシステムのルートを見つける際に Venus が問題に出合ったことを示
すプラットフォームに依存したエラーコードです。
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 および filetype を決め
るために行われます。要求されたディレクトリエントリは name という名前を
持ち、Venus は cfs_lookup_in.VFid で指定されたディレクトリを検索するで
しょう。結果は、名前が存在しないか、それを見つける際に問題に出合った
(例えばコネクションが切れた) ことを示すかもしれません。結果が 0 なら、
フィールド cfs_lookup_out.VFid は対象の ViceFid が入
り、cfs_lookup_out.vtype にはオブジェクトの種別を示す名前 coda_vtype
が入ります。
オブジェクトの名前は最大長 CFS_MAXNAMLEN の 8 ビット文字列で、現在
CFS_MAXNAMLEN は 256 に設定されています (文字数は 0 ターミネータ文字を
含みます)。
オブジェクトがカーネルのネームキャッシュに置かれてはならないことを示す
CFS_NOCACHE で、Venus がフィールド cfs_lookup.vtype をビット和している
ことを理解することは非常に重要です。各ホストで競合するファイルや Coda
管理下のファイルシステム内の実際のファイルはカーネルに決してキャッシュ
されてはならず、lookup は毎回 Venus に行われなければなりません。
注記 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) の多くは、内部の
"inode" や "FileHandle" のインスタンスを作成するために、Fid だけでなく
属性も得る必要があります。このようなシステムでは Venus/カーネル相互作
用レベルと RPC レベルの両方で、lookup と getattr コールを組合わせるこ
とによってパフォーマンスを著しく向上できるかもしれません。
入力の引き数内の vattr 構造体は余分で削除されるべきです。
4.6. setattr
概要 ファイルの属性を設定します。
引き数
入力
struct cfs_setattr_in {
ViceFid VFid;
struct coda_vattr attr;
} cfs_setattr;
出力
空
詳細 構造体 attr は BSD スタイルに変更された属性で記入されます。 VNON
に設定される vtype 以外の変更されない属性は -1 に設定されます。他は指
定された値に設定されます。ただし、FS ドライバが変更の要求を行ってよい
属性は、mode, ownner, groupid, atime, mtime, ctime だけです。返り値は
成功か失敗を示します。
エラー 様々なエラーが起こる可能性があります。オブジェクトが存在しな
い、アクセスできない、パーミッションが Venus から与えられないなど。
4.7. access
概要
引き数
入力
struct cfs_access_in {
ViceFid VFid;
int flags;
} cfs_access;
出力
空
詳細 flags に記載された操作を行うために、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;
詳細 この upcall はファイルの作成を要求するために呼び出されます。ファ
イルは VFid で指定されたディレクトリの中に作成され、その名前は name、
モードは mode になるでしょう。excl が設定された場合、ファイルが既に存
在すればエラーが返るでしょう。attr の size フィールドが 0 に設定された
場合、ファイルは切りつめられます。ファイルの uid および gid は
CodaCred を変換し設定され、uid はマクロ CRTOUID が用いられます (このマ
クロはプラットフォームに依存します)。成功した場合、ファイルの VFid お
よび属性が返されます。Coda FS ドライバは通常カーネルレベルで新しいオブ
ジェクトのために vnode, inode もしくはファイルハンドルのインスタンスを
作成するでしょう。
エラー 様々なエラーが起こる可能性があります。パーミッションは不十分か
もしれません。オブジェクトが存在しそれがファイルでない場合、Unix 下で
エラー EISDIR が返されます。
注記 パラメータの組みはとても非効率的で、システムコールの creat と VFS
操作の create との混同を示したものと思われます。VFS 操作の create は新
しいオブジェクトの作成の際にだけコールされます。この create コールは
Unix のコールとは異なり、ファイルディスクリプタを返すために呼び出され
ることはありません。トランケートとイクスクルシブのオプション、およびモ
ードは、単に Unix 下でのモードの一部にできるはずです。フラグの引き数が
あるべきではありません - 現在これは、READ もしくは WRITE モード用の
ファイルディスクプリタを返すために open (2) で使われています。
ディレクトリの属性も、size および 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 と同様です。
注記 入力パラメータは属性の変わりに mode へ変更されるはずです。
親の属性は、size および 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 が設定されます。
エラー
注記 ターゲットディレクトリの属性は、size が変更されるので、返されるは
ずです。
4.12. remove
概要 ファイルを削除します。
引き数
入力
struct cfs_remove_in {
ViceFid VFid;
char *name; /* Place holder for data. */
} cfs_remove;
出力
なし
詳細 VFid で指定されるディレクトリの中の cfs_remove_in.name で指定さ
れたファイルを削除します。
エラー
注記 ディレクトリの属性は、size および mtime が変わるかもしれないの
で、返されるはずです。
4.13. rmdir
概要 ディレクトリを削除します。
引き数
入力
struct cfs_rmdir_in {
ViceFid VFid;
char *name; /* Place holder for data. */
} cfs_rmdir;
出力
なし
詳細 VFid で指定されるディレクトリから name で指定されたディレクトリを
削除します。
エラー
注記 親ディレクトリの属性は、size および 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 で指定されるシンボリックリンクの内容をバッ
ファ data の中に読み出します。バッファ data はどんな名前でも保持できる
ように CFS_MAXNAMLEN の大きさが必要です (PATH もしくは NAME??)。
エラー 通常のエラーだけです。
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;
詳細 これは VFid で指定されるファイルを Venus のキャッシュに置くよう
Venus に依頼し、次に呼び出し元のプロセスが open(2) の flags の値でその
キャッシュ内のファイルを開くよう指定する一連の要求です。カーネルへの返
り値は Unix と Windows システムでは異なります。Unix システムでは Coda
FS ドライバは dev および inode のフィールドの中のコンテナファイルのデ
バイスおよび inode の番号を通知されます。 Windows では、コンテナファイ
ルのパスがカーネルに返されます。
エラー
注記 現状、cfs_open_out 構造体は Windows 環境での操作と厳密には整合性
がとれていません。一つはコンテナファイルの名前で開く、もう一つはコンテ
ナファイルの inode で開く、という二つの upcall を実装することが最良か
もしれません。
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 引き数
は通常記載されます。flags を Venus は使用しません。
エラー
注記 ここでも無用なパラメータです。flags は使われません。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 バイト読み出
します。データは data の中に返され、そのサイズを示す size が返ります。
エラー
注記 このコールは使用されません。Readdir 操作はコンテナファイルを消費
するためです。これから行うディレクトリの改良の間に、この件を再考しま
す。
4.20. vget
概要 FSDB->Get を行うよう Venus に指示します。
引き数
入力
struct cfs_vget_in {
ViceFid VFid;
} cfs_vget;
出力
struct cfs_vget_out {
ViceFid VFid;
int vtype;
} cfs_vget;
詳細 この upcall は VFid でラベル付けされた fsobj に対して、get 操作を
行うよう Venus に依頼します。
エラー
注記 この操作は使用されません。しかしながら、メモリにマップされたファ
イルの読み出し/書き込みに対応するために使うことができるので、非常に有
用です。これらのファイルは vget を使用して Venus のキャッシュの中に
「固定」でき、inactive で解放できます。
4.21. fsync
概要 ファイルの RVM 属性を更新するよう Venus に命じます。
引き数
入力
struct cfs_fsync_in {
ViceFid VFid;
} cfs_fsync;
出力
なし
詳細 オブジェクト VFid の RVM 属性を更新するよう Venus に依頼します。
これはカーネルレベルの fsync の類いのコールの一部として呼ばれるはずで
す。結果は同期が成功したかどうかを示します。
エラー
NOTE Linux はこのコールを実装していません。実装すべきです
4.22. inactive
概要 vnode をもう使用しないと Venus に命じます。
引き数
入力
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;
詳細 この upcall はファイルに対し読み出しか書き込みを行うよう Venus に
依頼します。
エラー
注記 読み出し/書き込みの操作を Venus は行わないという Coda の主義に逆
らうことなので、これは削除されるはずです。この操作は動作しないと聞いて
います。現在使用されていません。
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;
詳細 name で指定された Coda システムの rootfid を返すよう Venus に依
頼します。fid は VFid の中に返されます。
エラー
注記 このコールは dynamic set 向けに David が使っていました。これは
VFS マウンティング領域のポインタを複雑にしてしまうので、削除されるはず
です。普通の Coda は使用しません。このコールは Venus では実装されてい
ません。
4.25. ody_lookup
概要 何かを調べます。
引き数
入力
無関係
出力
無関係
詳細
エラー
注記 中身はありません。このコールは Venus では実装されていません。
4.26. ody_expand
概要 dynamic set における何かを拡張します。
引き数
入力
無関係
出力
無関係
詳細
エラー
注記 中身はありません。このコールは Venus では実装されていません。
4.27. prefetch
概要 dynamic set を先読みします。
引き数
入力
ドキュメント化されていません。
出力
ドキュメント化されていません。
詳細 Venus の worker.cc にはこのコールのサポートがありますが、動作し
ないと記されています。カーネルはサポートしていませんので、これは驚くべ
きことではありません (ODY_PREFETCH は動作が定義されていません)。
エラー
注記 中身はありません。コールは動作せず、Coda で使用されません。
4.28. signal
概要 upcall に関する signal を Venus に送ります。
引き数
入力
なし
出力
非適用
詳細 これは Venus への upcall の通常処理範囲外のもので、Venus が入力
キューからメッセージを読んだ後、呼び出し元のプロセスが signal を受け
取ったことを Venus に通知します。Venus は操作を完了することになってい
ます。
エラー 応答はありません。
注記 Venus の完了処理を正しく行うために Venus が何を完了する必要がある
のかを良く理解しておく必要があります。さらに、システムコールの状態毎に
複数の upcall を正確に扱う必要があります。また、Venus で upcall の後、
カーネルから (責任範囲として) 完了の通知を行う必要のあるどのような状態
が Venus で起きるのかを知ることが重要です (例えば open は間違いなくこ
のような状態変化ですが、他の多くのものはそうではないかもしれません)。
5. ミニキャッシュと downcall
Coda FS ドライバは、upcall の回数を抑制するために、lookup および
access の結果をキャッシュできます。upcall は、プロセスコンテキストス
イッチを行う必要があるので、コストがかかります。情報をキャッシュするこ
とに対応して、Venus から FS ドライバにキャッシュされたエントリのフラッ
シュや名前の変更を行わなければならないという通知が行われます。
一般的にカーネルコードは、Venus が管理する ViceFid と共に内部のファイ
ルハンドル (BSD で vnode, Linux で inode, Windows で FileHandle と呼ば
れます) にリンクした構造体を管理しなければなりません。その理由は、頻繁
な双方向の変換が、upcall を行ったり、その upcall の結果を使用する際必
要となるからです。こういったリンクされたオブジェクトは cnode と呼ばれ
ます。
現行のミニキャッシュの実装は以下を記録したキャッシュエントリになってい
ます -
1. ファイルの名前
2. オブジェクトを含んでいるディレクトリの cnode
3. lookup が許される CodaCred の一覧
4. オブジェクトの cnode
Coda FS ドライバにおける lookup コールは、呼び出し元の名前、ディレクト
リ、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;
詳細 ディレクトリの vnode と名前の組みを持つすべてのエントリを削除しま
す。キャッシュされた 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 がディレクトリの
callback を受け取った時に発行されます。
5.6. ZAPVNODE
引き数
struct cfs_zapvnode_out { /* CFS_ZAPVNODE is a venus->kernel call */
struct CodaCred cred;
ViceFid VFid;
} cfs_zapvnode;
詳細 引き数で渡される cred および VFid を持つキャッシュの中のエントリ
をすべて削除します。このコールはたぶん発行されることはありません。
5.7. PURGEFID
概要
引き数
struct cfs_purgefid_out { /* CFS_PURGEFID is a venus->kernel call */
ViceFid CodaFid;
} cfs_purgefid;
詳細 ファイルのための属性をフラッシュします。それがディレクトリ (や変
な vnode) なら、ネームキャッシュからのその子を除去し、ネームキャッシュ
からファイルを削除します。
5.8. REPLACE
概要 名前のコレクションのための Fid を置きかえます。
引き数
struct cfs_replace_out { /* cfs_replace is a venus->kernel call */
ViceFid NewFid;
ViceFid OldFid;
} cfs_replace;
詳細 このルーチンはネームキャッシュの中の ViceFid を別のものに置きかえ
ます。切断されている間ローカルに割当てられたテンポラリ fid をグローバ
ル fid に置きかえるための再統合の間、それらの fid の参照カウントが 0
でないときでさえ、Venus に許可を追加します。
6. 初期化とクリーンアップ
起動時および停止時あるいは Venus の故障時に Coda FS ドライバ用に望まれ
る機能を、簡潔にこのセクションで述べます。説明を始める前に、Coda FS ド
ライバが次のデータを管理していることを再確認しておきましょう。
1. メッセージキュー
2. cnode
3. ネームキャッシュエントリ
ネームキャッシュエントリは完全にドライバが私有するので、それらは簡
単に操作できます。一般にメッセージキューには明確に初期化および後処
理のルーチンがあるでしょう。cnode ははるかに扱いづらいもので
す。Coda ファイルシステム中にユーザプロセスから参照されている回数を
保持しているので、cnode をクリーンアップするのは困難かもしれませ
ん。
次のものから要求が来る可能性があります -
1. メッセージサブシステム
2. VFS 層
3. pioctl インターフェース
現在、 pioctl は VFS を介して Coda に渡されるので、これらを同様に扱
うことができます。
6.1. 必須条件
次の必須条件に対応するべきです -
1. メッセージキューは open および close ルーチンを持っているはずで
す。Unix 上のキャラクタデバイスのオープンはそういったルーチンです。
o オープンの前に、メッセージを置くことはできません。
o オープンは保留のままの古いメッセージをすべて削除します。
o クローズは upcall を完了できないスリープ中のプロセスすべてに通知
を行うでしょう。
o クローズはメッセージキューに割当てられたすべてのメモリを解放する
でしょう。
2. オープンでネームキャッシュは空の状態に初期化すべきです。
3. メッセージキューをオープンする前は、VFS 操作はすべて失敗するでしょ
う。幸運にも、オープンする前は Coda ファイルシステムのマウントが成
功しないので、これにより確認することができます。
4. キューのクローズの後は、VFS 操作は成功しません。ここで気を付けなけ
ればならないことは、少数の操作 (lookup, read/write, readdir) は
upcall なしで成功してしまうことです。これらは明示的に阻止しなければ
なりません。
5. クローズに際してネームキャッシュはフラッシュされ無効になるものとし
ます。
6. cnode に保持されたすべてのメモリは upcall に依存せずにすべてを解放
することができます。
7. ファイルシステムのアンマウントは upcall に依存せずに行うことができ
ます。
8. Venus が rootfid もしくは rootfid の属性を得られない場合、コーダ
ファイルシステムのマウントは優雅に失敗するべきです。マウントを試み
る前に、これらのオブジェクトを先読みするために、Venus が lattr を実
行すると良いでしょう。
注記 特に NetBSD で、さらに Linux も上記の必須条件を完全に実装しては
いません。円滑な操作のために、これを改善していく必要があります。
7. Inode 番号
Unix の stat システムコールはファイル用の inode を返します。getwd や
tar のようなライブラリコールが正しく機能するように、Coda ファイル用に
改善する必要があります。
ボリュームのマウントポイントは、Venus が statbuf 構造体の中に割当てる
inode 番号の値を複雑にします。規則は次のとおりです -
1. fid は整数 (vol<<20) + (vnode<<10) + (uniq) に変換されます。
2. fid がボリュームのルートである場合、そのマウントポイントであるシン
ボリックリンクの inode 番号が割当てられます。
カーネルはマウントポイントのシンボリックリンクをキャッシュしてはなりま
せんが、それらをカバーすることができない場合見ることはかまいません。さ
らにキャッシュからシンボリックリンク fid を除去する downcall が、カー
ネルがマウントポイントの fid を以前に見ていないという事実にかかわら
ず、行われます。
Coda 用のカーネルコードは Fid に基づき vnode (BSD), inode (Linux),
FileHandle (Win) を探す lookup の仕組みを実装するために必要で、ボリュ
ームのルートを正しく得るよう気をつける必要があるでしょう。
8. 日本語訳について
日本語訳は Linux Japanese FAQ Project が行いました。翻訳に関するご意見
は JF プロジェクト <JF@linux.or.jp> 宛に連絡してください。
v1.2
翻訳: 野本浩一 <hng@ps.ksky.ne.jp>
校正:
中谷 千絵さん <jeanne@mbox.kyoto-inet.or.jp>、
Seiji Kanekoさん <skaneko@a2.mbn.or.jp>
Linux カーネル 2.2 付属文書一覧へ戻る