POSIX 1003.1 (2004) doesn't go so far as to require unrelated data to be committed (emphasis mine):
"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." (http://pubs.opengroup.org/onlinepubs/009695299/functions/fsy...)
I think there's a good argument that Linux and other workalike OSes go too far in flushing all dirty pages to disk when fsync() is called.
sync(), on the other hand, does require all dirty pages to be committed, though, ironically, it is permitted to return asynchronously (http://pubs.opengroup.org/onlinepubs/009695299/functions/syn...).
sync() is basically a relic. Historically it only existed so that a UNIX userland process could roughly control the rate that dirty buffers went to disk. This was the "update" daemon historically, known as "fsflush" on SYSV. At least on linux that's internal to the kernel these days.
Technically that's true, but it's not an issue in real life. Any sensible operating system will flush dirty buffers to disk eventually. Imagine if a sudden power outage lost writes you had made a month ago; it would be considered a pretty severe OS error.
So in reality, you might be waiting many seconds for the write to hit disk, but you won't be waiting hours.
> That's exactly what fsync() is supposed to do.
No, fsync is "Make sure the last write made it to disk. IN fact, force it out immediately. Also, all of the other pending writes as well, even if I'm not concerned about them. Oh, and block my thread until you're finished." It's an expensive operation.