このセクションは 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 に共有される様々なデータ構造 体を知る必要があります。
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 */ };
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 は行われないでしょう。
注記 データ構造体およびコードはむちゃくちゃです。これを整理する必 要があります。
個々のコールを説明します -
引き数
空
struct cfs_root_out { ViceFid VFid; } cfs_root;
詳細 このコールは Coda ファイルシステムの初期化中に Venus へ行われ
ます。結果
が 0 なら、cfs_root
構造体には Coda ファイルシステム
のルートの ViceFid が入っています。0 でない結果が生成される場合、その値
は Coda ファイルシステムのルートを見つける際に Venus が問題に出合ったこ
とを示すプラットフォームに依存したエラーコードです。
概要 ディレクトリにその 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
を属性を考慮しませんが、考慮すべきです。
概要 ファイルの属性を得ます。
引き数
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
構造体は余分で削除されるべきです。
概要 ファイルの属性を設定します。
引き数
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 から与えられないなど。
概要
引き数
struct cfs_access_in { ViceFid VFid; int flags; } cfs_access;
空
詳細 flags
に記載された操作を行うために、VFid
で指定され
るオブジェクトのアクセス権が得られるかどうか確認をします。結果はアクセス
権の有無を示します。Coda は保護を強化するために ACL を使っており、結局の
ところクライアントではなくサーバがシステムのセキュリティを保証していると
いうことを知っておくことは重要です。このコールの結果は、ユーザが
トークンを保持しているかどうかに依存するでしょう。
エラー オブジェクトは存在しないかもしれません、もしくは保護情報を記 載する ACL はアクセス可能ではないかもしれません。
概要 ファイルを作成するために呼び出されます。
引き数
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 が変更されるので、返されるはずで す。
概要 新しいディレクトリを作成します。
引き数
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 が変わるので、返されるはずです。
概要 既存ファイルへのリンクを作成します。
引き数
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 はディレクトリ
をまたいだハードリンクをサポートしていません。返り値は関連するものだけで
す。それは成功もしくは失敗の種別を示します。
エラー 通常のエラーが起こる可能性があります。
概要 シンボリックリンクを作成します。
引き数
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 が変更されるので、返され るはずです。
概要 ファイルを削除します。
引き数
struct cfs_remove_in { ViceFid VFid; char *name; /* Place holder for data. */ } cfs_remove;
なし
詳細 VFid
で指定されるディレクトリの中の
cfs_remove_in.name
で指定されたファイルを削除します。
エラー
注記 ディレクトリの属性は、size および mtime が変わるかもしれないの で、返されるはずです。
概要 ディレクトリを削除します。
引き数
struct cfs_rmdir_in { ViceFid VFid; char *name; /* Place holder for data. */ } cfs_rmdir;
なし
詳細 VFid
で指定されるディレクトリから name
で指定された
ディレクトリを削除します。
エラー
注記 親ディレクトリの属性は、size および mtime が変わるかもしれない ので、返されるはずです。
概要 シンボリックリンクの値を読み出します。
引き数
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??)。
エラー 通常のエラーだけです。
概要 ファイルを開きます。
引き数
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 を実装することが最
良かもしれません。
概要 ファイルを閉じ、サーバ上でそれを更新します。
引き数
struct cfs_close_in { ViceFid VFid; int flags; } cfs_close;
なし
詳細 VFid
で指定されるファイルを閉じます。
エラー
注記 flags
引き数は無意味で、使用されません。しかしながら、
Venus のコードは execp
入力フィールドを扱う余地があり、たぶん、この
フィールドは、ファイルは閉じられたが実行のためにメモリにマップされたまま
であることを、Venus に通知するために使われることになるはずです。Venus
vproc_vfscalls
でデータを取ってくることおよび取ってこないことについ
ての注釈があります。これは変です。ファイルが閉じられている場合、コンテナ
ファイルの中のデータは新しいデータになっているとすべきだからです。ここで
も execp
フラグは混乱の元になっているかもしれません - 現在の Venus
ではファイルが静的なメモリにマップされているのにもかかわらず、ファイルを
キャッシュからフラッシュできると考えるかもしれません。このことを理解する
必要があります。
概要 ファイルに対する 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 を何に使おうと言うつもりなんでしょう ?
概要 fid の名前を変更します。
引き数
struct cfs_rename_in { ViceFid sourceFid; char *srcname; ViceFid destFid; char *destname; } cfs_rename;
なし
詳細 ディレクトリ sourceFid
の中の srcname
という名前の
オブジェクトを destFid
の中の destname
に変更します。名前
srcname
および destname
の文字列は 0 でターミネートしてくださ
い。Unix カーネルにおける文字列はいつも null ターミネートされているとは
限りません。
エラー
概要 ディレクトリエントリを読み出します。
引き数
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 操作はコンテナファイルを消 費するためです。これから行うディレクトリの改良の間に、この件を再考します。
概要 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
で解放できます。
概要 ファイルの RVM 属性を更新するよう Venus に命じます。
引き数
struct cfs_fsync_in { ViceFid VFid; } cfs_fsync;
なし
詳細 オブジェクト VFid
の RVM 属性を更新するよう Venus に依頼
します。これはカーネルレベルの fsync
の類いのコールの一部として呼ば
れるはずです。結果
は同期が成功したかどうかを示します。
エラー
NOTE Linux はこのコールを実装していません。実装すべきです
概要 vnode をもう使用しないと Venus に命じます。
引き数
struct cfs_inactive_in { ViceFid VFid; } cfs_inactive;
なし
詳細 この操作は EOPNOTSUPP
が返ります。
エラー
注記 これはたぶん削除されるはずです。
概要 ファイルに対し読み出しか書き込みをします。
引き数
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 の主義 に逆らうことなので、これは削除されるはずです。この操作は動作しないと聞い ています。現在使用されていません。
概要 一つの 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 では実装されていませ ん。
概要 何かを調べます。
引き数
無関係
無関係
詳細
エラー
注記 中身はありません。このコールは Venus では実装されていません。
概要 dynamic set における何かを拡張します。
引き数
無関係
無関係
詳細
エラー
注記 中身はありません。このコールは Venus では実装されていません。
概要 dynamic set を先読みします。
引き数
ドキュメント化されていません。
ドキュメント化されていません。
詳細 Venus の worker.cc にはこのコールのサポートがありますが、動作 しないと記されています。カーネルはサポートしていませんので、これは驚くべ きことではありません (ODY_PREFETCH は動作が定義されていません)。
エラー
注記 中身はありません。コールは動作せず、Coda で使用されません。
概要 upcall に関する signal を Venus に送ります。
引き数
なし
非適用
詳細 これは Venus への upcall の通常処理範囲外のもので、Venus が入 力キューからメッセージを読んだ後、呼び出し元のプロセスが signal を受け取っ たことを Venus に通知します。Venus は操作を完了することになっています。
エラー 応答はありません。
注記 Venus の完了処理を正しく行うために Venus が何を完了する必要が あるのかを良く理解しておく必要があります。さらに、システムコールの状態毎 に複数の upcall を正確に扱う必要があります。また、Venus で upcall の後、 カーネルから (責任範囲として) 完了の通知を行う必要のあるどのような状態が Venus で起きるのかを知ることが重要です (例えば open は間違いなくこのよう な状態変化ですが、他の多くのものはそうではないかもしれません)。