SYNC_FILE_RANGE(2)

名前
sync_file_range - ファイルセグメントをディスクと同期する

書式
#define _GNU_SOURCE         /* feature_test_macros(7) 参照 */
#include <fcntl.h>

int sync_file_range(int fd, off64_t offset, off64_t nbytes,
                    unsigned int flags);

説明
sync_file_range() を使うと、ファイルディスクリプター fd で参照されるオープンされたファイルのディスクとの同期に関して、 きめ細かな制御が可能となる。

offset は、同期を行うファイルの領域の開始バイトである。 nbytes には同期を行う領域の長さをバイト単位で指定する。 nbytes が 0 の場合は、 offset からファイル末尾までの全バイトを同期する。 同期はシステムのページサイズの単位で行われる。 offset はページ境界にあわせて切り下げられ、 (offset+nbytes-1) はページ境界にあわせて切り上げられる。

ビットマスク引数 flags には以下の値を指定することができる:

SYNC_FILE_RANGE_WAIT_BEFORE
    何らかの書き込みを行う前に、指定された領域のページで 書き出しを行うようにデバイスドライバにすでに要求が発行されている ページの書き出しが全て完了するのを待つ。

SYNC_FILE_RANGE_WRITE
    指定された領域のページで、書き出し要求が発行されていない 全ての dirty (キャッシュだけが変更されている) ページの 書き出しを開始する。 リクエストキューの大きさより多く書き込もうとした場合には、 この処理は停止 (block) する可能性がある点に注意すること。

SYNC_FILE_RANGE_WAIT_AFTER
    何らかの書き込み後に、指定された領域の全てのページの 書き出しが行われるのを待つ。

flags に 0 を指定した場合、何もしないことを表す。

  警告
このシステムコールは非常に危険であり、 移植性が必要なプログラムで使用すべきではない。 これらの操作ではどれもファイルのメタデータの書き出しを行わない。 したがって、アプリケーションにより作成済みのディスクブロックの 上書きの実行が確実に行われない限り、クラッシュの後でもデータが 利用できる保証はない。 書き込みが上書きだけであるかを知るためのユーザーインターフェースは存在しない。 (btrfs などの) copy-on-write 動作を使ったファイルシステムでは、 既存の割り当て済みのブロックに対する上書き自体ができない。 前もって割り当てられた領域に書き込みを行う場合、 多くのファイルシステムでは block allocator への書き込みも必要となるが、 このシステムコールは block allocator のディスクへの同期を行わない。 このシステムコールはディスク書き込みキャッシュのフラッシュを 行わないので、揮発性のディスク書き込みキャッシュを使ったシステムでは このシステムコールではデータの一貫性を確保できないことになる。

  詳細
SYNC_FILE_RANGE_WAIT_BEFORE と SYNC_FILE_RANGE_WAIT_AFTER は I/O エラーや ENOSPC 状態を検出し、呼び出し元にこれらの情報を返す。

flags の役に立つビットの組み合わせを以下に示す:

SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE
    指定された範囲内のページで、 sync_file_range() が呼び出された際に dirty であった全てのページが、 確実に書き出し対象となるようにする。 これは、start-write-for-data-integrity 操作 (データ完全性確保のための書き込み開始の操作) である。

SYNC_FILE_RANGE_WRITE
    指定された範囲内のページで、現在書き出し中でない全ての dirty ページの 書き出しを開始する。これは非同期のディスクへのフラッシュ (flush-to-disk) 操作である。データ完全性確保が必要な操作としては適切ではない。

SYNC_FILE_RANGE_WAIT_BEFORE (or SYNC_FILE_RANGE_WAIT_AFTER)
    指定された範囲内の全てのページの書き出しの完了を待つ。 このフラグは、前に行われた操作 SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE の後に使用でき、この操作の完了を待ち、結果を取得することができる。

SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER
    これは write-for-data-integrity 操作 (データ完全性確保のための書き込み) であり、指定された範囲内の、 sync_file_range() が呼ばれた時点で dirty な全てのページが ディスクに格納されることが保証される。

返り値
成功の場合、 sync_file_range() は 0 を返す。失敗の場合、-1 を返し、 errno にエラーを示す値を設定する。

エラー

EBADF
    fd が有効なファイルディスクリプターではない。

EINVAL
    flags に不正なビットが指定されている。または offset か nbytes が不正である。

EIO I/O エラー。

ENOMEM
    メモリー不足である。

ENOSPC
    ディスク領域不足である。

ESPIPE
    fd が、通常のファイル、ブロックデバイス、ディレクトリ以外のものを指している。

バージョン
sync_file_range() はカーネル 2.6.17 で Linux に登場した。

準拠
このシステムコールは Linux 独自であり、 移植性が必要なプログラムでは使用を避けるべきである。

注意

  sync_file_range2()
いくつかのアーキテクチャー (例えば、 PowerPC や ARM) では、 64 ビットの引数は適切なレジスターの組に割り当てる必要がある。 このようなアーキテクチャーでは、 「書式」に書かれている sync_file_range() の呼び出しシグネチャーで、 引数 fd と offset の間のパディング (詰めもの) でレジスターが一つ消費されてしまう (詳細は syscall(2) 参照)。 そのため、 これらのアーキテクチャーでは引数が適切な順序になった別のシステムコールが定義されている。

    int sync_file_range2(int fd, unsigned int flags,
                         off64_t offset, off64_t nbytes);

上記の点以外は、このシステムコールの動作は sync_file_range() と 全く同じである。このシステムコールに対するライブラリによるサポートは glibc では提供されていない。

このバージョンのシステムコールは、Linux 2.6.20 で ARM アーキテクチャーで 初めて登場し、 arm_sync_file_range() という名前であった。 Linux 2.6.22 で、同様のシステムコールが PowerPC 用に追加された際に、 システムコールの名前が変更された。 glibc によるサポートが提供されているアーキテクチャーでは、 glibc のラッパー関数は sync_file_range() という名前で sync_file_range2() を適切に使用するようになっている。

関連項目
fdatasync(2), fsync(2), msync(2), sync(2)

この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。