Using sync and fsync calls

If a file is opened with O_SYNC or O_DSYNC, then each write will cause the data for that write to be flushed to disk before the write returns. If the write causes a new disk allocation (the file is being extended instead of overwriting an existing page), then that write will also cause a corresponding JFS log write.

Forced synchronization of the contents of real memory and disk takes place in several ways:

  • An application program makes an fsync() call for a specified file. This causes all of the pages that contain modified data for that file to be written to disk. The writing is complete when the fsync() call returns to the program.
  • An application program makes a sync() call. This causes all of the file pages in memory that contain modified data to be scheduled for writing to disk. The writing is not necessarily complete when the sync() call returns to the program.
  • A user can enter the sync command, which in turn issues a sync() call. Again, some of the writes may not be complete when the user is prompted for input (or the next command in a shell script is processed).
  • The /usr/sbin/syncd daemon issues a sync() call at regular intervals, usually every 60 seconds. This ensures that the system does not accumulate large amounts of data that exists only in volatile RAM.

A sync operation has several effects, aside from its small CPU consumption:

  • It causes writes to be clumped, rather than spread out.
  • It causes at least 28 KB of system data to be written, even if there has been no I/O activity since the previous sync operation.
  • It accelerates the writing of data to disk, defeating the write-behind algorithm. This effect is significant mainly in programs that issue an fsync() call after every write.
  • When sync() or fsync() calls occur, log records are written to the JFS log device to indicate that the modified data has been committed to disk.