Linux カーネル内の flush と fsync

re ディスクの情報とメモリ上の情報 - odz buffer
re 辞書が壊れない仮名漢字変換エンジンの作者を雇うのは案外に難しいのかもしれない,という話 - NyaRuRuが地球にいたころ
re Linux の close は fsync 相当を調べる - naoyaのはてなダイアリー

以下の理解であってると思う。たぶん... だよね?

  • file_operations::flush は、ネットワークファイルシステムにおいて書き込みの成否を確認するための呼び出し ファイルの内容が「ユーザプロセスAが書き込んだ最新のデータを他のユーザプロセスBが読める」ことを保証するための呼び出し
    • ext3 において noop なのは、ext3ローカルファイルシステムであり flush を呼ばなくても書き込みの成功が保証されるから
    • nfs 等においては nfs サーバへの書き出しを保証する?
  • 「ディスク上にデータが書き込まれた」ことを保証するのは file_operations::fsync

9:40 追記: そういえば、nfs に対してデータが書き込めたかどうかは close(2) を呼ぶまで確認できないってのは man にも書いてある。大学の環境は nfs+quota だったので、先生がわざわざ念を押して話していた記憶がある。

Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota.

close(2): close file descriptor - Linux man page

気になるのは、ローカルファイルシステムだったら write(2) の呼び出しだけで、他のプロセスから読めることが保証されるんじゃないかなぁという辺り。un*x 関連の仕様がどうなっているか、というのと、じゃあ xfs の flush は一体何をやっているんだ *1、というあたりがわからない。

10:25 追記: というわけで linux-2.6.24.3 のソースで確認。file_operations::flush を定義しているのは nfs と cifs のみ。 (id:naoya の記述と異なり) xfs を含むそれ以外のファイルシステムは flush を定義していない。なので、同一マシンのプロセス間同期なら write(2) で十分 (カーネル内でプロセス毎に別個にキャッシュする必要はないわけだし、普通そうなるだろう)、ネットワークファイルシステムの場合は fsync(2) あるいは close(2) を呼び出すまで同期されない (ことがある)というのが正解。

*1:「reiserfs も flush なし、xfs にはあった」 Linux の close は fsync 相当を調べる - naoyaのはてなダイアリー