Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between fsync and syncfs?

What is the difference between fsync and syncfs ?

int syncfs(int fd);
int fsync(int fd);

The manpage for fync says the following :

fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or other permanent stor‐ age device) so that all changed information can be retrieved even after the system crashed or was rebooted. This includes writing through or flushing a disk cache if present. The call blocks until the device reports that the transfer has completed. It also flushes metadata information associated with the file (see stat(2)).

The manpage for syncfs says the following:

sync() causes all buffered modifications to file metadata and data to be written to the underly‐ ing filesystems.

syncfs() is like sync(), but synchronizes just the filesystem containing file referred to by the open file descriptor fd.

For me both seem equal. They are sychronizing the file referred by the filedescriptor and the associated metadata.

like image 706
cominfotty Avatar asked Jan 09 '18 15:01

cominfotty


People also ask

What is fsync used for?

The fsync() function transfers all data for the file indicated by the open file descriptor file_descriptor to the storage device associated with file_descriptor. fsync() does not return until the transfer is complete, or until an error is detected.

What is fsync call?

DESCRIPTION. fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or other permanent storage device) where that file resides. The call blocks until the device reports that the transfer has completed.

Does fsync block?

The primary use of fsync is to lock the mongod instance in order to back up the files within mongod 's dbPath . The operation flushes all data to the storage layer and blocks all write operations until you unlock the mongod instance.

What Fflush and fsync functions do?

fflush() works on FILE* , it just flushes the internal buffers in the FILE* of your application out to the OS. fsync works on a lower level, it tells the OS to flush its buffers to the physical media. OSs heavily cache data you write to a file. If the OS enforced every write to hit the drive, things would be very slow.


2 Answers

I think the current answer is not complete. For Linux:

According to the standard specification (e.g., POSIX.1-2001), sync() schedules the writes, but may return before the actual writing is done. However Linux waits for I/O completions, and thus sync() or syncfs() provide the same guarantees as fsync called on every file in the system or filesystem respectively.

and

Before version 1.3.20 Linux did not wait for I/O to complete before returning.

This is mentioned on the sync(2) page in the "notes" and "bugs" sections.

like image 54
user869887 Avatar answered Oct 07 '22 17:10

user869887


First, fsync() (and sync()) are POSIX-standard functions while syncfs() is Linux-only.

So availability is one big difference.

From the POSIX standard for fsync():

The fsync() function shall request that all data for the open file descriptor named by fildes is to be transferred to the storage device associated with the file described by fildes. The nature of the transfer is implementation-defined. The fsync() function shall not return until the system has completed that action or until an error is detected.

Note that it's just a request.

From the POSIX standard for sync():

The sync() function shall cause all information in memory that updates file systems to be scheduled for writing out to all file systems.

The writing, although scheduled, is not necessarily complete upon return from sync().

Again, that's not something guaranteed to happen.

The Linux man page for syncfs() (and sync()) states

sync() causes all pending modifications to filesystem metadata and cached file data to be written to the underlying filesystems.

syncfs() is like sync(), but synchronizes just the filesystem containing file referred to by the open file descriptor fd.

Note that when the function returns is unspecified.

The Linux man page for fsync() states:

fsync() transfers ("flushes") all modified in-core data of (i.e., modified buffer cache pages for) the file referred to by the file descriptor fd to the disk device (or other permanent storage device) so that all changed information can be retrieved even if the system crashes or is rebooted. This includes writing through or flushing a disk cache if present. The call blocks until the device reports that the transfer has completed.

As well as flushing the file data, fsync() also flushes the metadata information associated with the file (see inode(7)).

Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed.

Note that the guarantees Linux provides for fsync() are much stronger than those provided for sync() or syncfs(), and by POSIX for both fsync() and sync().

In summary:

  1. POSIX fsync(): "please write data for this file to disk"
  2. POSIX sync(): "write all data to disk when you get around to it"
  3. Linux sync(): "write all data to disk (when you get around to it?)"
  4. Linux syncfs(): "write all data for the filesystem associated with this file to disk (when you get around to it?)"
  5. Linux fsync(): "write all data and metadata for this file to disk, and don't return until you do"

Note that the Linux man page doesn't specify when sync() and syncfs() return.

like image 42
Andrew Henle Avatar answered Oct 07 '22 16:10

Andrew Henle