要約

  • 改訂11では、属性が設定されたディレクトリについて、別の列挙で得たREADDIR結果を新しい列挙に使わず、今回そのエントリを返した最新READDIRより前の属性値を報告しないことを、従うクライアントに求める。
  • 対象はアプリケーションに見える応答であり、キャッシュの内部構造ではない。パス単位、返されたエントリ単位、サーバー観測時点単位の狭い保証である。
  • 高頻度書き込み環境のバックアップ漏れを減らせる一方、READDIR負荷、設定権限、委譲の回収、クライアントごとの実効性を運用側が引き受ける。

テストできない命令から、禁止される結果へ

draft-ietf-nfsv4-uncacheable-directories-11 は2026年9月5日に提出された。NFSv4ワーキンググループの標準化過程にある文書で、HammerspaceサーバーとLinuxクライアントのプロトタイプが報告されている。しかしInternet-Draftであり、RFCでもIETFの承認でも、製品への普及を示す資料でもない。

改訂10の中心文は、各READDIRでサーバーからメタデータを取得せよとしていた。だがREADDIRはそもそもサーバーに送るプロトコル操作である。その表現だけなら、名前を再取得した後に、通常のinode属性キャッシュから古いサイズをstatへ渡す実装も排除できない。

改訂11は、実装の中身ではなく結果を規定する。対象ディレクトリの新しい列挙を、別の列挙で得たREADDIR結果だけで満たしてはならない。あるエントリが最新のREADDIRで返されたなら、そのREADDIRより前に受信した値を、そのエントリの属性として報告してはならない。古い値を格納した操作の種類は問わない。

これなら外から検査できる。一度列挙し、別クライアントがファイルを伸ばし、もう一度列挙してから属性を見る。二回目のREADDIRより前のサイズを返すことが不適合な結果になる。古いキャッシュ行を削除したか、世代管理したか、そのまま保持したかは、禁止された値を見せない限り仕様の関心外である。

変わらない名前が、変わったファイルを隠す

ディレクトリエントリは名前とfileidの組である。作成、削除、改名があれば親ディレクトリのchangeが動く。既存ファイルへの追記は、名前もfileidも変えずにsizeやtime_modifyだけを変えられる。親の時計は子の書き込み時刻を表していない。

RFC 8881はREADDIRで得た属性のキャッシュを認める。後続のGETATTRを省き、安定したディレクトリでは有効な設計だ。ところがHPCの出力領域や多数の送信元が集まる取り込み領域では、正のキャッシュ寿命が短くても、ほとんどのファイル属性が書き込みに追いつかない場合がある。

増分バックアップがサイズと更新時刻を基準に対象を決めれば、古い値のために変更済みファイルを飛ばしうる。新属性は、サーバーが危険なディレクトリを選び、列挙ごとの再観測を要求するための信号である。設定されていない場所のキャッシュが正しいことまでは証明しない。

仕様の単位は一回の列挙

改訂11は大文字と小文字の違いを意味の違いとして固定した。小文字のreaddirはアプリケーション要求、大文字のREADDIRはNFSv4.2操作である。enumerationはディレクトリを一巡する単位で、複数のアプリケーション呼び出しと、必要に応じた複数の継続READDIRからなる。一つのREADDIRが多数のreaddirを満たすのが普通だ。

したがって、エントリ一件につきネットワーク要求一回を求める仕様ではない。今回の列挙を今回のREADDIR群で根拠づける仕様である。クライアントは表示する属性をattr_requestで要求するのが望ましい。後からGETATTRしても規則は満たせるが、一件ずつの通信になり、この機構が避けたい負荷を復活させる。

列挙終了後も値は保持できる。次の列挙までは通常の属性キャッシュ規則が働く。次のREADDIRがエントリを返した時点で、それより古い値を今回の答えに使えなくなる。「uncacheable」という名称より、実際の規則は報告値の来歴を区切るものに近い。

設定時刻と効力発生時刻を分ける

サーバーが属性をTRUEにしても、クライアントがディレクトリ属性の古い値を持っていれば、直ちには行動が変わらない。RFC 8881の上限でキャッシュが期限切れになるか、再検証でディレクトリchangeの変化を見た後に、新しい規則が以後の列挙へ適用される。

監査上は、SETATTRの時刻、各クライアントがTRUEを初めて観測した時刻、アプリケーションが初めて新しい結果を受けた時刻を分ける必要がある。サーバー設定だけを見て「全クライアントで有効」と記録すれば、宣言を実行結果にすり替えることになる。

ディレクトリ委譲も移行を必要とする。委譲はクライアントがサーバーへ戻らずにディレクトリ状態を出せる仕組みで、新属性の列挙ごとの再取得と両立しない。属性を設定したサーバーは既存の委譲を回収し、TRUEの間は新しい委譲を出してはならない。子属性通知は任意機能で、実装されないことがあり、クライアント数と変更数の積で費用が増えるため、一般的な代替にはならない。

サーバーより新しい権威を持つクライアント

OPEN_DELEGATE_WRITEを持つクライアントは、サーバー側のコピーより新しいsizeやchangeを持ちうる。RFC 8881では、サーバーがCB_GETATTRで委譲先へ問い合わせる。そのクライアントに古いサーバー値を採用させれば、再取得が正しさを悪化させる。

改訂11はこの逆転を避ける。禁止されるのは、サーバーが返す値より古い値であり、委譲先のより新しい値を捨てることではない。鮮度は通信先だけで決まらず、現在の書き込み権威がどこにあるかで決まる。

もちろんREADDIRの値も永続的な「現在」ではない。直後に別の書き込みが起きる。ここで得られるのは、エントリを返した時点のサーバー相対の観測であって、データとメタデータの全体スナップショットではない。

一つの親がファイル全体を支配しない

属性はディレクトリごとに設定され、そのディレクトリを通じて列挙されたエントリの報告を制約する。同じファイルがハードリンクで設定済みと未設定の両方に現れる場合、未設定側の経路には影響しない。子ディレクトリへの自動継承もプロトコルでは定義されず、行うならサーバーのローカル方針である。

型の扱いも修正された。属性サポートはファイルシステム単位で広告されるため、非ディレクトリへのGETATTRにはFALSEを返す。非ディレクトリへのSETATTRはNFS4ERR_WRONG_TYPEとなる。拡張を知っていることと、そのオブジェクトに意味があることは別である。

問い合わせ履歴は遵守証明ではない

この属性はadvisoryである。GETATTRやSETATTRが見えても、クライアントが規則を実行しているとは限らない。サーバーは、遵守するクライアント、理解して無視するクライアント、未実装のクライアントを、その操作だけでは区別できない。全員の遵守を前提にサーバー自身の正しさを組み立ててはならない。

性能面では、設定ディレクトリを走査するたびにサーバー負荷が発生する。属性なしREADDIRの後に一件ずつGETATTRする実装ならさらに重い。設定権限を広げすぎると、一回の属性変更が全クライアントへ負荷を増幅する。認可、エクスポート方針、所有権、容量上限は機構の一部である。

公開資料が示すのは文書、改訂履歴、基礎RFC、コミット理由、自己申告されたプロトタイプまでである。リリース済みLinux、製品挙動、採用率、性能値、事故、改善率は示さない。別のファイルデータ用ドラフトは内容キャッシュと書き込み耐久性を扱い、今回のメタデータ範囲を広げない。

Heng Luの現実層に照らせば、サーバーの属性、クライアントの内部状態、READDIRの観測、アプリケーションへの応答は別々の事実である。この改訂の進歩は、その違いを消さずに接続条件を書いたことにある。

出典