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
| Name | What it does |
|---|---|
| SYNC_FILE_RANGE_WRITE | Start async writeback for dirty pages in the range. Returns immediately; use with WAIT_AFTER to collect later. |
| SYNC_FILE_RANGE_WAIT_BEFORE | Wait for writeback of pages already queued before this call before proceeding. |
| SYNC_FILE_RANGE_WAIT_AFTER | Wait 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
| errno | Meaning |
|---|---|
| EBADF | fd is not a valid file descriptor. |
| EINVAL | flags contains invalid bits, or offset+nbytes overflows. |
| EIO | A 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. |
| ENOMEM | Insufficient 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
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
