ファイルの変更を保存装置へ送るとき、内容だけ送れば足りるように思えるかもしれません。しかし、後からその内容を正しく読むには、ファイルの長さなども必要です。Linuxのfdatasyncは、単純に「データだけ」を同期する関数ではありません。読み出しに必要かどうかで、同期するメタデータを選びます。[1]
簡単にまとめると?
- fsyncはファイルの変更されたデータと関連するメタデータを同期します。fdatasyncは、後のデータ取得に必要なメタデータを残して、不要なものの同期を省けます。
- アクセス時刻や更新時刻は、内容を読み出すためには必須ではありません。一方、ファイルを長くしたときのサイズは、どこまでデータがあるかを決めるため同期対象です。
- fdatasyncを選んだだけで高速化や障害耐性を実証したことにはなりません。必要な性質、戻り値、ファイルシステムと装置の条件を別に確認します。
メタデータにも、役割の違いがある
メタデータは、ファイルの内容そのものを説明・管理する情報です。例えば、ファイルサイズ、最後にアクセスした時刻、最後に内容を変更した時刻があります。同じ「内容以外の情報」でも、読み手がバイト列を正しく取得するために必要なものと、履歴や管理のために使うものは同じではありません。
Linux man-pages 6.19は、fsyncがファイルの変更されたデータに加えて、関連するメタデータも同期すると説明しています。これに対してfdatasyncは、後のデータ取得を正しく行うために必要でない限り、変更されたメタデータの同期を要求しません。[1、DESCRIPTION] 判断の軸は、情報の大きさや名前ではなく、読み出しへの役割です。
ここで「省ける」は、その情報が必ず書き出されないという意味ではありません。実際のファイルシステムでは複数の情報が同じ保存単位に載るなど、実装上まとめて書かれる場合があります。関数が最低限どの情報の同期を求めるかと、実装が実際に行う入出力は分けて読みます。
長さが古いままなら、追加した部分を読めない
単純な例として、長さが4バイトのファイルにABCDが入っているとします。末尾へEFを追加すると、内容はABCDEF、長さは6になります。変更後のバイト列が保存されても、長さを示す情報だけが4のままなら、通常のファイル読取りでは末尾のEFまで到達できません。
この例の読み出しモデルは、保存されたバイト列の先頭から、保存された長さの分だけを返すものです。内容をABCDEFへ変え、長さを4に据え置くとABCDが返ります。長さも6へ更新して初めてABCDEFが返ります。実際のファイルシステムのブロック配置やクラッシュ後の状態を再現する実験ではありませんが、サイズを内容から切り離せない理由を示せます。

マニュアルも、ファイルサイズst_sizeの変更を、fdatasyncでメタデータの同期が必要になる例として挙げています。[1] 「メタデータは省略する関数」と覚えると、まさに内容を正しく読むために必要な情報まで省くように誤解してしまいます。
同じ長さの上書きと、長さの変更を分ける
今度はABCDをWXYZに上書きし、長さは4のままとします。このモデルでは、新しい内容と長さ4がそろえばWXYZを読み出せます。追加の例と異なり、サイズの値を4から6へ変更する必要はありません。
ただし、これを「同じ長さならメタデータは一切不要」と一般化することはできません。内容へ到達するための管理情報が更新されるかどうかは、ファイルシステムの構成にも関係します。fdatasyncの条件は、特定の一項目だけを固定リストから除くことではなく、正しいデータ取得に必要な情報を同期することです。
この違いは、ログへの追記と、既存の固定長領域への上書きを比較するときに役立ちます。どちらもwriteを呼ぶ処理でも、ファイルの長さが変わるかは異なります。比較の前提に操作の種類を残せば、「同じデータ量なのに同期の負担が違う」場合にも、何が変わったのかを調べやすくなります。本稿は両方式の速度差を測定したものではありません。
時刻が重要な用途では、判断が変わる
マニュアルは、最終アクセス時刻st_atimeと最終更新時刻st_mtimeについて、後のデータ読取りを正しく処理するためには必須でないため、fdatasyncでの同期は必要ないと説明しています。[1] ファイルの内容を取得できることに注目すれば、更新時刻が以前の値でも、読み出すバイト列そのものは別に定義できます。
一方、アプリケーションが更新時刻を使って再処理の要否や表示順を決めるなら、時刻はそのアプリケーションにとって重要です。「内容を読み出せるためには必須ではない」と「自分の用途では失ってよい」は同じではありません。保存したい性質に時刻などのメタデータも含まれるなら、fdatasyncだけを選ぶ理由を見直します。
fsyncとfdatasyncを比べる際は、まず、後から必要になる情報を列挙します。内容と長さで足りるのか、関連するメタデータも含めて同期したいのか。そのうえで、使う環境が提供する動作と照合します。関数名だけで一方を常に優れた選択肢と決めることはできません。
同期した範囲と、残る条件を記録する
fsyncとfdatasyncは成功時に0、エラー時に−1を返し、errnoで理由を知らせます。[1、RETURN VALUE・ERRORS] 内容を書けたことと、必要な同期が成功したことを別々に記録すると、保存完了の判断を追いやすくなります。容量不足や入出力の問題など、同期の段階で表面化するエラーを成功として扱わないことが必要です。
また、ファイルの同期は、その名前を含むディレクトリ項目の同期まで一括して保証するものではありません。[1] 名前の置換とディレクトリの保存は、別の対象として確認が必要です。本稿の比較は、ファイルの内容を正しく取得するためにどのメタデータが必要か、という範囲です。
fdatasyncの目的は、すべてのメタデータの同期を必要としない用途で、ディスク活動を減らせるようにすることです。しかし、削減できる書込みや待ち時間は実装と操作に依存します。装置が返す完了の意味や、使うファイルシステムの条件も含めて、必要な試験を別に行います。短い独自モデルの結果を、実装の性能や電源断後の復旧保証へ広げないことが大切です。
出典
- [1] Linux man-pages 6.19 — fsync(2), fdatasync(2)(本文日付2026年2月8日、2026年10月22日保存)。DESCRIPTION、RETURN VALUE、ERRORSを参照。ABCDEF・WXYZと長さの比較は独自モデルです。
