Filesystems & Storage

fsync semantics (the durability guarantee)

/ fsync = EFF-sink /

You have learned that a successful write() only reaches the page cache in RAM, not the disk. So how does a program that truly cares - a database, a text editor saving your document - make sure its bytes are actually, physically on stable storage that will survive a power cut? It calls fsync(). fsync(fd) blocks until all the modified data and metadata for that file have been forced from the page cache through to durable storage, and only then returns success. It is the one call that converts 'written' into 'durable'.

There are two related calls. fsync(fd) flushes both the file's data and its metadata (size, timestamps) and waits. fdatasync(fd) flushes the data plus only the metadata strictly needed to read that data back (so it can skip a timestamp-only update), which is slightly cheaper. Crucially, fsync must also ensure the bytes have left any volatile cache on the drive itself - a modern fsync issues a cache-flush command (or uses FUA, force-unit-access, writes) to the device so the data is not merely sitting in the drive's own RAM. There is also a subtlety about directories: after creating a new file, the file's data is durable only after fsync on the file, but the directory entry naming it is durable only after fsync on the parent directory - miss that and a crash can leave the data with no name pointing to it.

Why it matters: fsync is the durability primitive every reliable storage system is built on, and getting it wrong is a classic source of silent data loss. Be honest about its limits and costs. It is expensive - it forces the disk to actually commit, which can take milliseconds and stall the calling thread - so calling it after every tiny write destroys performance. It can FAIL, and its failure means your data is NOT durable; ignoring fsync's return value is a real bug. And historically some systems handled a failed fsync so badly (clearing the dirty flag, so a retry falsely succeeds) that the safe response to fsync failure is often to treat the data as lost rather than retry. fsync is not a formality - it is where the durability guarantee actually lives or dies.

safe save of a new file: write(fd, data, n); if (fsync(fd) != 0) { /* NOT durable - treat as data loss */ } /* also durably record the name: */ fsync(dirfd); // fsync the PARENT directory so the new entry survives a crash

Durability needs fsync on the file AND on its parent directory; the return value must be checked.

fsync can fail, and a failed fsync means the data is not durable - never ignore its return. Some kernels also clear the dirty flag on a failed writeback, so a later fsync can falsely report success; the robust response to fsync failure is often to treat the data as lost rather than retry. Also, fsync on a file does not make its directory entry durable - fsync the parent directory too.

Also called
fsyncfdatasyncdurability barrierfsync 語意持久性屏障