まず、fsync() (そして sync() ) は POSIX 標準関数ですが、syncfs() は は Linux 専用です。
そのため、可用性が大きな違いの 1 つです。
fsync() の POSIX 標準から :
fsync() 関数は要求する fildes で指定された開いているファイル記述子のすべてのデータ fildes で記述されたファイルに関連付けられたストレージデバイスに転送されます .転送の性質は実装定義です。 fsync() システムがそのアクションを完了するまで、またはエラーが検出されるまで、関数は戻りません。
これは単なるリクエストであることに注意してください。
sync() の POSIX 標準から :
sync() 関数は、ファイル システムを更新するメモリ内のすべての情報を書き込みのスケジュールにします。
書き込みは予定されていますが、sync() から戻った時点で完了しているとは限りません。 .
繰り返しますが、それは必ず起こるというわけではありません.
syncfs() の Linux man ページ (そして sync() )状態
sync() ファイルシステムのメタデータとキャッシュされたファイル データに対するすべての保留中の変更が、基になるファイル システムに書き込まれます。
syncfs() sync() のようなものです 、ただし、開いているファイル記述子 fd によって参照されるファイルシステムを含むファイルのみを同期します .
いつに注意してください 関数が返す値は指定されていません。
Linux fsync() の man ページ 状態:
fsync() ファイル記述子 fd によって参照されるファイル (つまり、変更されたバッファ キャッシュ ページ) のすべての変更されたコア内データを転送 (「フラッシュ」) します。 システムがクラッシュしたり再起動したりした場合でも、変更されたすべての情報を取得できるように、ディスク デバイス (またはその他の永続的なストレージ デバイス) に保存します。これには、存在する場合、ディスク キャッシュの書き込みまたはフラッシュが含まれます。転送が完了したことをデバイスが報告するまで、通話はブロックされます。
ファイルデータをフラッシュするだけでなく、 fsync() ファイルに関連付けられたメタデータ情報もフラッシュします (inode(7) を参照)。
fsync() を呼び出す ファイルを含むディレクトリ内のエントリがディスクに到達したことを必ずしも保証するわけではありません。そのための明示的な fsync() ディレクトリのファイル記述子も必要です。
Linux が fsync() に対して提供する保証に注意してください。 sync() で提供されているものよりもはるかに強力です または syncfs() 、および両方の fsync() の POSIX による と sync() .
要約:
<オール>fsync() :"このファイルのデータをディスクに書き込んでください"sync() :"ディスクにアクセスしたら、すべてのデータをディスクに書き込みます"sync() :"すべてのデータをディスクに書き込みます (いつディスクに取り掛かることができますか?)"syncfs() :"このファイルに関連付けられたファイルシステムのすべてのデータをディスクに書き込みます (いつディスクにアクセスできますか?)"fsync() :「このファイルのすべてのデータとメタデータをディスクに書き込み、完了するまで戻らないでください」
Linux の man ページでは sync() が指定されていないことに注意してください。 と syncfs() 戻る。
現在の答えは完全ではないと思います。 Linux の場合:
<ブロック引用>
標準仕様 (POSIX.1-2001 など) によると、sync() 書き込みをスケジュールしますが、実際の書き込みが完了する前に戻る場合があります。ただし、Linux は I/O の完了を待つため、sync() またはsyncfs() fsync と同じ保証を提供します システムまたはファイルシステム内のすべてのファイルでそれぞれ呼び出されます。
そして
<ブロック引用>バージョン 1.3.20 より前の Linux は、I/O が完了するのを待たずに戻っていました。
これは sync(2) に記載されています 「メモ」および「バグ」セクションのページ。