2. RPC情報 (RPC Information)
2.1 認証 (Authentication)
NFSサービスは、NULLプロシージャでAUTH_NONEを使用します。AUTH_UNIX、AUTH_DES、またはAUTH_KERBは、他のすべてのプロシージャで使用されます。将来的には他の認証タイプがサポートされる可能性があります。
2.2 定数 (Constants)
NFSバージョン3サービスを呼び出すために必要なRPC定数です。これらは10進数で示されています。
PROGRAM 100003
VERSION 3
2.3 トランスポートアドレス (Transport address)
NFSプロトコルは通常、TCPおよびUDPプロトコル上でサポートされます。NFSバージョン2プロトコルと同じポート2049を使用します。
2.4 サイズ (Sizes)
NFSバージョン3プロトコルで使用されるさまざまなXDR構造体のサイズを10進バイト単位で示します:
NFS3_FHSIZE 64
- 不透明なファイルハンドルの最大サイズ(バイト単位)。
NFS3_COOKIEVERFSIZE 8
- READDIRおよびREADDIRPLUSによって渡される不透明なクッキー検証子のサイズ(バイト単位)。
NFS3_CREATEVERFSIZE 8
- 排他的CREATEに使用される不透明な検証子のサイズ(バイト単位)。
NFS3_WRITEVERFSIZE 8
- 非同期WRITEに使用される不透明な検証子のサイズ(バイト単位)。
2.5 基本データ型 (Basic Data Types)
以下のXDR定義は、他の構造体で使用される基本定義です。
uint64
typedef unsigned hyper uint64;
int64
typedef hyper int64;
uint32
typedef unsigned long uint32;
int32
typedef long int32;
filename3
typedef string filename3<>;
nfspath3
typedef string nfspath3<>;
fileid3
typedef uint64 fileid3;
cookie3
typedef uint64 cookie3;
cookieverf3
typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
createverf3
typedef opaque createverf3[NFS3_CREATEVERFSIZE];
writeverf3
typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
uid3
typedef uint32 uid3;
gid3
typedef uint32 gid3;
size3
typedef uint64 size3;
offset3
typedef uint64 offset3;
mode3
typedef uint32 mode3;
count3
typedef uint32 count3;
nfsstat3
enum nfsstat3 {
NFS3_OK = 0,
NFS3ERR_PERM = 1,
NFS3ERR_NOENT = 2,
NFS3ERR_IO = 5,
NFS3ERR_NXIO = 6,
NFS3ERR_ACCES = 13,
NFS3ERR_EXIST = 17,
NFS3ERR_XDEV = 18,
NFS3ERR_NODEV = 19,
NFS3ERR_NOTDIR = 20,
NFS3ERR_ISDIR = 21,
NFS3ERR_INVAL = 22,
NFS3ERR_FBIG = 27,
NFS3ERR_NOSPC = 28,
NFS3ERR_ROFS = 30,
NFS3ERR_MLINK = 31,
NFS3ERR_NAMETOOLONG = 63,
NFS3ERR_NOTEMPTY = 66,
NFS3ERR_DQUOT = 69,
NFS3ERR_STALE = 70,
NFS3ERR_REMOTE = 71,
NFS3ERR_BADHANDLE = 10001,
NFS3ERR_NOT_SYNC = 10002,
NFS3ERR_BAD_COOKIE = 10003,
NFS3ERR_NOTSUPP = 10004,
NFS3ERR_TOOSMALL = 10005,
NFS3ERR_SERVERFAULT = 10006,
NFS3ERR_BADTYPE = 10007,
NFS3ERR_JUKEBOX = 10008
};
nfsstat3型は、NULLプロシージャを除くすべてのプロシージャの結果とともに返されます。NFS3_OKの値は、呼び出しが正常に完了したことを示します。その他の値は、エラーコードによって識別される呼び出しで何らかのエラーが発生したことを示します。正確な数値エンコーディングに従う必要があることに注意してください。サーバーは他の値を返すことはできません。サーバーは、定義されたエラーコードのセットへのエラー条件のマッピングに最善の努力をすることが期待されています。さらに、この仕様ではエラーの優先順位は指定されていません。エラーの優先順位は、特定の状況で複数のエラーが適用される場合に返すべきエラー値を決定します。エラーの優先順位は、個々のサーバー実装によって決定されます。クライアントが特定のエラーの優先順位を必要とする場合は、特定のエラーを自身でチェックする必要があります。
2.6 定義されたエラー番号 (Defined Error Numbers)
定義された各エラーの説明は以下の通りです:
NFS3_OK
- 呼び出しが正常に完了したことを示します。
NFS3ERR_PERM
- 所有者ではありません。呼び出し元が特権ユーザー(root)でないか、操作のターゲットの所有者でないため、操作が許可されませんでした。
NFS3ERR_NOENT
- ファイルまたはディレクトリが存在しません。指定されたファイルまたはディレクトリ名が存在しません。
NFS3ERR_IO
- I/Oエラー。要求された操作の処理中にハードエラー(ディスクエラーなど)が発生しました。
NFS3ERR_NXIO
- I/Oエラー。そのようなデバイスまたはアドレスはありません。
NFS3ERR_ACCES
- アクセス拒否。呼び出し元は、要求された操作を実行するための正しい権限を持っていません。これを、所有者または特権ユーザーの権限失敗に限定するNFS3ERR_PERMと対比してください。
NFS3ERR_EXIST
- ファイルが存在します。指定されたファイルはすでに存在します。
NFS3ERR_XDEV
- デバイス間のハードリンクを試みました。
NFS3ERR_NODEV
- そのようなデバイスはありません。
NFS3ERR_NOTDIR
- ディレクトリではありません。呼び出し元がディレクトリ操作で非ディレクトリを指定しました。
NFS3ERR_ISDIR
- ディレクトリです。呼び出し元が非ディレクトリ操作でディレクトリを指定しました。
NFS3ERR_INVAL
- 無効な引数または操作でサポートされていない引数。2つの例は、シンボリックリンク以外のオブジェクトに対してREADLINKを試みること、またはこの操作をサポートしていないサーバー上で時刻フィールドをSETATTRしようとすることです。
NFS3ERR_FBIG
- ファイルが大きすぎます。操作により、ファイルがサーバーの制限を超えて拡大されるところでした。
NFS3ERR_NOSPC
- デバイスに空き容量がありません。操作により、サーバーのファイルシステムがその制限を超えるところでした。
NFS3ERR_ROFS
- 読み取り専用ファイルシステム。読み取り専用ファイルシステムで変更操作が試みられました。
NFS3ERR_MLINK
- ハードリンクが多すぎます。
NFS3ERR_NAMETOOLONG
- 操作のファイル名が長すぎました。
NFS3ERR_NOTEMPTY
- 空でないディレクトリを削除しようとしました。
NFS3ERR_DQUOT
- リソース(クォータ)のハードリミットを超えました。サーバー上のユーザーのリソースリミットが超過されました。
NFS3ERR_STALE
- 無効なファイルハンドル。引数で指定されたファイルハンドルが無効でした。そのファイルハンドルによって参照されるファイルはもはや存在しないか、それへのアクセスが取り消されています。
NFS3ERR_REMOTE
- パスのリモートレベルが多すぎます。引数で指定されたファイルハンドルは、サーバー上の非ローカルファイルシステム上のファイルを参照していました。
NFS3ERR_BADHANDLE
- 不正なNFSファイルハンドル。ファイルハンドルが内部整合性チェックに失敗しました。
NFS3ERR_NOT_SYNC
- SETATTR操作中に更新同期の不一致が検出されました。
NFS3ERR_BAD_COOKIE
- READDIRまたはREADDIRPLUSクッキーが古くなっています。
NFS3ERR_NOTSUPP
- 操作はサポートされていません。
NFS3ERR_TOOSMALL
- バッファまたはリクエストが小さすぎます。
NFS3ERR_SERVERFAULT
- 正規のNFSバージョン3プロトコルエラー値のいずれにもマップされないエラーがサーバーで発生しました。クライアントはこれを適切なエラーに変換する必要があります。UNIXクライアントは、これをEIOに変換することを選択できます。
NFS3ERR_BADTYPE
- サーバーがサポートしていないタイプのオブジェクトを作成しようとしました。
NFS3ERR_JUKEBOX
- サーバーはリクエストを開始しましたが、タイムリーに完了できませんでした。クライアントは待機してから、新しいRPCトランザクションIDでリクエストを再試行する必要があります。たとえば、階層ストレージをサポートし、移行されたファイルを処理するリクエストを受信するサーバーからこのエラーが返される必要があります。この場合、サーバーは移入プロセスを開始し、このエラーでクライアントに応答する必要があります。
ftype3
enum ftype3 {
NF3REG = 1,
NF3DIR = 2,
NF3BLK = 3,
NF3CHR = 4,
NF3LNK = 5,
NF3SOCK = 6,
NF3FIFO = 7
};
列挙型ftype3は、ファイルのタイプを示します。タイプNF3REGは通常のファイル、NF3DIRはディレクトリ、NF3BLKはブロック特殊デバイスファイル、NF3CHRはキャラクタ特殊デバイスファイル、NF3LNKはシンボリックリンク、NF3SOCKはソケット、NF3FIFOは名前付きパイプです。正確な列挙エンコーディングに従う必要があることに注意してください。
specdata3
struct specdata3 {
uint32 specdata1;
uint32 specdata2;
};
2つのワードの解釈は、ファイルシステムオブジェクトのタイプによって異なります。ブロック特殊(NF3BLK)またはキャラクタ特殊(NF3CHR)ファイルの場合、specdata1とspecdata2はそれぞれメジャーデバイス番号とマイナーデバイス番号です。(これは明らかにUNIX固有の解釈です。)他のすべてのファイルタイプの場合、これら2つの要素は0に設定するか、クライアントとサーバーで値を合意する必要があります。クライアントとサーバーが値について合意しない場合、クライアントはこれらのフィールドを0に設定されているかのように扱う必要があります。このデータフィールドはfattr3構造体の一部として返されるため、属性を返すすべての応答から利用できます。これらのフィールドはデバイスでないオブジェクトには使用されないため、帯域外情報をサーバーからクライアントに渡すことができます。ただし、繰り返しになりますが、サーバーとクライアントの両方が渡される値について合意する必要があります。
nfs_fh3
struct nfs_fh3 {
opaque data<NFS3_FHSIZE>;
};
nfs_fh3は、LOOKUP、CREATE、SYMLINK、MKNOD、LINK、またはREADDIRPLUS操作でサーバーによって返される可変長の不透明オブジェクトであり、クライアントが後続の操作でファイルを参照するために使用されます。ファイルハンドルには、サーバーが個々のファイルを区別するために必要なすべての情報が含まれています。クライアントにとって、ファイルハンドルは不透明です。クライアントは後のリクエストで使用するためにファイルハンドルを保存し、バイトごとの比較を行うことで同じサーバーからの2つのファイルハンドルを等価性について比較できますが、それ以外の方法でファイルハンドルの内容を解釈することはできません。同じサーバーからの2つのファイルハンドルが等しい場合、それらは同じファイルを参照する必要がありますが、等しくない場合、結論を引き出すことはできません。サーバーは、ファイルハンドルとファイル間の1対1の対応を維持しようとする必要がありますが、これは必須ではありません。クライアントは、正しい動作のためではなく、パフォーマンスを向上させるためにのみファイルハンドルの比較を使用する必要があります。
サーバーは、ファイルハンドルによって提供されるアクセスをいつでも取り消すことができます。呼び出しで渡されたファイルハンドルがサーバー上にもはや存在しないファイルシステムオブジェクトを参照しているか、そのファイルハンドルへのアクセスが取り消されている場合、エラーNFS3ERR_STALEが返される必要があります。
nfstime3
struct nfstime3 {
uint32 seconds;
uint32 nseconds;
};
nfstime3構造体は、1970年1月1日グリニッジ標準時の真夜中からの秒数とナノ秒数を示します。時刻と日付情報を渡すために使用されます。ファイルに関連付けられた時刻は、クライアントがファイル時刻を明示的に設定できるSETATTR操作の場合を除いて、すべてサーバー時刻です。サーバーは、時刻値を処理する際にローカル時刻との間で変換を行い、可能な限り精度を保持します。ファイルに保存されるタイムスタンプの精度がNFSバージョン3プロトコルで定義されたものよりも低い場合、精度の損失が発生する可能性があります。クライアントとサーバーの時刻のずれを減らすために、補助的な時刻維持プロトコルが推奨されます。
fattr3
struct fattr3 {
ftype3 type;
mode3 mode;
uint32 nlink;
uid3 uid;
gid3 gid;
size3 size;
size3 used;
specdata3 rdev;
uint64 fsid;
fileid3 fileid;
nfstime3 atime;
nfstime3 mtime;
nfstime3 ctime;
};
この構造体は、ファイルシステムオブジェクトの属性を定義します。オブジェクトに対するほとんどの操作によって返されます。2つのオブジェクトに影響する操作の場合(たとえば、ターゲットディレクトリ属性を変更し、新しく作成されたディレクトリの新しい属性を定義するMKDIR)、両方の属性が返される場合があります。場合によっては、属性は以下で定義されるwcc_data構造体で返されます。他の場合、属性は単独で返されます。NFSバージョン2プロトコルからの主な変更点は、多くのフィールドが拡張され、メジャー/マイナーデバイス情報がワードにパックされるのではなく、別個の構造体で表示されるようになったことです。
fattr3構造体には、ファイルの基本属性が含まれています。すべてのサーバーは、一部のフィールドをシミュレートする必要がある場合でも、この属性セットをサポートする必要があります。Typeはファイルのタイプです。Modeは保護モードビットです。Nlinkはファイルへのハードリンクの数、つまり同じファイルの異なる名前の数です。Uidはファイルの所有者のユーザーIDです。Gidはファイルのグループのグループ IDです。Sizeはファイルのバイト単位のサイズです。Usedは、ファイルが実際に使用するディスクスペースのバイト数です(ファイルにホールがある場合はサイズより小さくなる可能性があり、断片化のためにより大きくなる可能性があります)。Rdevは、ファイルタイプがNF3CHRまたはNF3BLKの場合、デバイスファイルを記述します - 20ページのspecdata3を参照してください。Fsidは、ファイルシステムのファイルシステム識別子です。Fileidは、ファイルシステム内でファイルを一意に識別する番号です(UNIXではこれはinumberになります)。Atimeは、ファイルデータが最後にアクセスされた時刻です。Mtimeは、ファイルデータが最後に変更された時刻です。Ctimeは、ファイルの属性が最後に変更された時刻です。ファイルへの書き込みは、mtimeに加えてctimeも変更します。
モードビットは次のように定義されています:
0x00800 実行時にユーザーIDを設定
0x00400 実行時にグループIDを設定
0x00200 スワップされたテキストを保存(POSIXで定義されていません)
0x00100 所有者の読み取り権限
0x00080 所有者の書き込み権限
0x00040 ファイルに対する所有者の実行権限。またはディレクトリ内の所有者の検索権限。
0x00020 グループの読み取り権限
0x00010 グループの書き込み権限
0x00008 ファイルに対するグループの実行権限。またはディレクトリ内のグループの検索権限。
0x00004 その他の読み取り権限
0x00002 その他の書き込み権限
0x00001 ファイルに対するその他の実行権限。またはディレクトリ内のその他の検索権限。
post_op_attr
union post_op_attr switch (bool attributes_follow) {
case TRUE:
fattr3 attributes;
case FALSE:
void;
};
この構造体は、属性の操作に直接関与していない操作で属性を返すために使用されます。このNFSプロトコルの改訂の原則の1つは、付随的な操作からのエラーではなく、指定された操作からの実際の値を返すことです。post_op_attr構造体は、属性の取得中に発生したエラーからサーバーが回復できるように設計されました。
これは属性を返すことをオプションにしているように見えます。ただし、サーバー実装者は、エラーを返す場合でも、可能な限り属性を返すように最善の努力をすることを強く推奨されます。
wcc_attr
struct wcc_attr {
size3 size;
nfstime3 mtime;
nfstime3 ctime;
};
これは、弱いキャッシュ一貫性セマンティクスをよりよくサポートするために必要な操作前属性のサブセットです。Sizeは、操作前のオブジェクトのファイルサイズ(バイト単位)です。Mtimeは、操作前のオブジェクトの最終変更時刻です。Ctimeは、操作前のオブジェクトの属性の最終変更時刻です。24ページのwcc_attrの議論を参照してください。
クライアントがmtimeを使用してサーバー上にあるファイルシステムオブジェクトへの変更を検出することは、サーバー上の時間ベースの粒度に依存します。
pre_op_attr
union pre_op_attr switch (bool attributes_follow) {
case TRUE:
wcc_attr attributes;
case FALSE:
void;
};
wcc_data
struct wcc_data {
pre_op_attr before;
post_op_attr after;
};
クライアントがサーバー上のファイルまたはディレクトリの状態を変更する操作を実行する場合、クライアントが最後にオブジェクトの属性を受け取ったときから、実行された操作がオブジェクトに対する唯一の操作であったかどうかを、操作後の属性からすぐに判断することはできません。これは重要です。なぜなら、介在する操作がオブジェクトを変更した場合、クライアントはオブジェクトのキャッシュされたデータ(書き込んだばかりのデータを除く)を無効にする必要があるからです。
これに対処するために、弱いキャッシュ一貫性データまたはwcc_dataの概念が導入されています。wcc_data構造体は、操作前のオブジェクト属性の特定のキーフィールドと、操作後のオブジェクト属性で構成されます。この情報により、クライアントはNFSバージョン2プロトコル実装よりも正確にキャッシュを管理できます。弱いキャッシュ一貫性という用語は、このメカニズムがキャッシュ一貫性プロトコルが提供するような厳密なサーバー・クライアント一貫性を提供しないという事実を強調しています。
弱いキャッシュ一貫性モデルをサポートするために、サーバーはオブジェクトの操作前の属性を取得し、意図された変更操作を実行してから、操作後の属性をアトミックに取得できる必要があります。操作とget attributes操作のいずれかの間にオブジェクトが変更されるウィンドウがある場合、クライアントはオブジェクトを変更した唯一のエンティティであるかどうかを判断できません。一部の情報が失われ、弱いキャッシュ一貫性の保証が弱まります。
post_op_fh3
union post_op_fh3 switch (bool handle_follows) {
case TRUE:
nfs_fh3 handle;
case FALSE:
void;
};
このNFSプロトコルの改訂の原則の1つは、付随的な操作からのエラーではなく、指定された操作からの実際の値を返すことです。post_op_fh3構造体は、ファイルハンドルの構築中に発生したエラーからサーバーが回復できるように設計されました。
これは、CREATE、MKDIR、SYMLINK、MKNOD、およびREADDIRPLUSリクエストからファイルハンドルを返すために使用される構造体です。各ケースで、クライアントは、リストされた操作のいずれかからの正常な復帰後にLOOKUPリクエストを発行することでファイルハンドルを取得できます。ファイルハンドルを返すことは、クライアントがファイルハンドルを取得するためにすぐにLOOKUPリクエストを発行することを強制されないようにするための最適化です。
sattr3
enum time_how {
DONT_CHANGE = 0,
SET_TO_SERVER_TIME = 1,
SET_TO_CLIENT_TIME = 2
};
union set_mode3 switch (bool set_it) {
case TRUE:
mode3 mode;
default:
void;
};
union set_uid3 switch (bool set_it) {
case TRUE:
uid3 uid;
default:
void;
};
union set_gid3 switch (bool set_it) {
case TRUE:
gid3 gid;
default:
void;
};
union set_size3 switch (bool set_it) {
case TRUE:
size3 size;
default:
void;
};
union set_atime switch (time_how set_it) {
case SET_TO_CLIENT_TIME:
nfstime3 atime;
default:
void;
};
union set_mtime switch (time_how set_it) {
case SET_TO_CLIENT_TIME:
nfstime3 mtime;
default:
void;
};
struct sattr3 {
set_mode3 mode;
set_uid3 uid;
set_gid3 gid;
set_size3 size;
set_atime atime;
set_mtime mtime;
};
sattr3構造体には、クライアントから設定できるファイル属性が含まれています。フィールドは、fattr3構造体の同様の名前のフィールドと同じです。NFSバージョン3プロトコルでは、設定可能な属性は、判別共用体のセットを含む構造体によって記述されます。各共用体は、対応する属性を更新するかどうか、更新する場合はどのように更新するかを示します。
2つの形式の判別共用体が使用されます。mode、uid、gid、またはsizeを設定する場合、判別共用体はブール値set_itで切り替えられます。TRUEの場合、適切なタイプの値がエンコードされます。
atimeまたはmtimeを設定する場合、共用体は列挙型set_itで切り替えられます。set_itの値がDONT_CHANGEの場合、対応する属性は変更されません。値がSET_TO_SERVER_TIMEの場合、対応する属性はサーバーによってローカル時刻に設定されます。クライアントからデータは提供されません。最後に、set_itの値がSET_TO_CLIENT_TIMEの場合、属性はクライアントがnfstime3構造体で渡した時刻に設定されます。(時刻粒度の問題を扱う86ページのFSINFOを参照してください)。
diropargs3
struct diropargs3 {
nfs_fh3 dir;
filename3 name;
};
diropargs3構造体はディレクトリ操作で使用されます。ファイルハンドルdirは、ファイルnameを操作またはアクセスするディレクトリを識別します。101ページの「ファイル名コンポーネントの処理」の追加コメントを参照してください。