関数仕様
書式
1 2 3 4 |
#include <unistd.h> int fsync (int fd); |
引数
fd | fsync を行うファイルディスクリプタ |
戻り値
0 | fsync の実行に成功 |
-1 | エラーが発生 |
機能
- ファイルディスクリプタが指すメモリ上のキャッシュをストレージに書き込む
- カーネル内のディスクキャッシュをストレージデバイスに書き込む
注意すること
注意ポイント①
fsync にファイルを指すディスクリプタを指定した場合、ディレクトリエントリは書き込まれない。
fsync は引数 fd のファイルディスクリプタで指定したファイルについて、個別に sync 動作を行います。
つまり、fd で個別のファイルを指定した場合は、ファイルが存在しているディレクトリのエントリが
ディスクへ書き込まれたことを保証するわけではありません。
ファイルの書き込みを保証するためには、明示的にそのディレクトリのファイルディスクリプタに対しても
fsync を実行する必要があります。
注意ポイント②
fsync は、指定したファイルディスクリプタの同期処理が完了しないと返ってこない。
fsync の戻り値からも分かるように、引数 fd で指定した個別のファイルの同期処理が完了するまで
呼出し元に戻ってきません。
処理タイミングがシビアな場合や、遅延が許されないシステムでは、
書き出し用のスレッドを起こすなどして他の処理を止めない工夫が必要になります。
注意ポイント③
古いファイルシステムを使用する場合は、fsync に対応していない場合がある。
fsync のシステムコールは、ファイルシステムごとに実装されています。
古いファイルシステムの場合、fsync の処理が実装されていない場合がありますので、
使用する前に確認する必要があります。
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #define TMP_FILE_PATH "./tmp.dat" int main (void) { int fd, size; char buf[14]; fd = open (TMP_FILE_PATH, (O_RDWR | O_CREAT), 0664); if (fd < 0) return -1; sprintf (buf, "Hello world!!"); size = write (fd, buf, sizeof (buf)); if (size != sizeof (buf)) { close (fd); return -1; } if (fsync (fd) < 0) { close (fd); return -1; } close (fd); return 0; } |