This is how you can do what you want:
#include <fcntl.h>
int fd = open('/path/to/dir', O_RDONLY);
fsync(fd);
Don't forget to close the fd file descriptor when no longer needed of course.
Contrary to some misconceptions, the atomicity of rename() does not guarantee the file will be persisted to disk. The atomicity guarantee only ensures that the metadata in the file system buffers is in a consistent state but not that it has been persisted to disk.
This is how you can do what you want:
#include <fcntl.h>
int fd = open('/path/to/dir', O_RDONLY);
fsync(fd);
Don't forget to close the fd file descriptor when no longer needed of course.
Contrary to some misconceptions, the atomicity of rename() does not guarantee the file will be persisted to disk. The atomicity guarantee only ensures that the metadata in the file system buffers is in a consistent state but not that it has been persisted to disk.
rename() is atomic (on linux), so I don't think you need to worry about that
Atomicity is typically guaranteed in operations involving filename handling ; for example, for rename, “specification requires that the action of the function be atomic” – that is, when renaming a file from the old name to the new one, at no circumstances should you ever see the two files at the same time.
a power outage in the middle of a rename() operation shall not leave the filesystem in a “weird” state, with the filename being unreachable because its metadata has been corrupted. (ie. either the operation is lost, or the operation is committed.)
Source
So, I think you should only be worried about error value.
If you really want to be safe, fsync() also flush metadata (on linux), so you could fsync the directory and the file you want to be sure there are present on the disk.
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. fsync (among other things) allows you to control when the data should hit the drive.
Furthermore, fsync/commit works on a file descriptor. It has no knowledge of a FILE* and can't flush its buffers. FILE* lives in your application, file descriptors live in the OS kernel, typically.
The standard C function fflush() and the POSIX system call fsync() are conceptually somewhat similar. fflush() operates on C file streams (FILE objects), and is therefore portable.
fsync() operate on POSIX file descriptors.
Both cause buffered data to be sent to a destination.
On a POSIX system, each C file stream has an associated file descriptor, and all the operations on a C file stream will be implemented by delegating, when necessary, to POSIX system calls that operate on the file descriptor.
One might think that a call to fflush on a POSIX system would cause a write of any data in the buffer of the file stream, followed by a call of fsync() for the file descriptor of that file stream. So on a POSIX system there would be no need to follow a call to fflush with a call to fsync(fileno(fp)). But is that the case: is there a call to fsync from fflush?
No, calling fflush on a POSIX system does not imply that fsync will be called.
The C standard for fflush says (emphasis added) it
causes any unwritten data for [the] stream to be delivered to the host environment to be written to the file
Saying that the data is to be written, rather than that is is written implies that further buffering by the host environment is permitted. That buffering by the "host environment" could include, for a POSIX environment, the internal buffering that fsync flushes. So a close reading of the C standard suggests that the standard does not require the POSIX implementation to call fsync.
The POSIX standard description of fflush does not declare, as an extension of the C semantics, that fsync is called.