$RodHat_/search
Syscall reference · I/O

sync_file_range(2)

Submits async writeback for a byte range and optionally waits for it, without syncing inode metadata. Lets sequential writers overlap I/O with compute while deferring the durability-barrier fdatasync to checkpoint time.

Since
Linux 2.6.17check your kernel →
glibc
n/a
System
Linux
Man page
sync_file_range(2)

Synopsis

#define _GNU_SOURCE
#include <fcntl.h>

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

Rod's take

Not a cheaper fdatasync — it pushes dirty pages to disk but does not sync inode metadata or the journal. Use SYNC_FILE_RANGE_WRITE to kick off async writeback, keep writing, then WAIT_BEFORE|WRITE|WAIT_AFTER to collect the previous range before your buffer recycles. Durability still requires fdatasync at checkpoint boundaries. Check return values on the wait form: deferred I/O errors surface there, not on the async write call.

Flags and arguments that matter

NameWhat it does
SYNC_FILE_RANGE_WRITEStart async writeback for dirty pages in the range. Returns immediately; use with WAIT_AFTER to collect later.
SYNC_FILE_RANGE_WAIT_BEFOREWait for writeback of pages already queued before this call before proceeding.
SYNC_FILE_RANGE_WAIT_AFTERWait for writeback of all pages in the range after issuing it. Combining WAIT_BEFORE|WRITE|WAIT_AFTER is the full synchronous form.

Errors you will actually hit

errnoMeaning
EBADFfd is not a valid file descriptor.
EINVALflags contains invalid bits, or offset+nbytes overflows.
EIOA writeback error occurred. Only surfaced on the waiting form (WAIT_BEFORE or WAIT_AFTER) — the async WRITE form returns 0 even if queuing deferred I/O that will fail later.
ENOMEMInsufficient kernel memory.

Example

#define _GNU_SOURCE
#include <fcntl.h>

/* kick off async writeback, do not wait */
sync_file_range(fd, prev_offset, prev_len, SYNC_FILE_RANGE_WRITE);

/* ... write next chunk ... */

/* wait for previous range before recycling buffer */
sync_file_range(fd, prev_offset, prev_len,
    SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE |
    SYNC_FILE_RANGE_WAIT_AFTER);

/* durability at checkpoint: still required */
fdatasync(fd);

Trimmed from the full walkthrough in sync_file_range(2): writeback without the fsync stall.

BSD equivalent

No direct BSD equivalent. FreeBSD and OpenBSD rely on msync(2) (MAP_ASYNC) or fdatasync(2) for range writeback. ZFS on FreeBSD makes msync less relevant for most use cases.

The long version, from the console

Sources

  1. sync_file_range(2), man7.org

Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.