When flushing a file to disk on a POSIX system, WiredTiger will call either fdatasync() or fsync(), depending on whether the HAVE_FDATASYNC compile file was set. The difference between these calls is that fsync() flushes both file content and file metadata, such as update time and file size, while fdatasync() flushes just the file data. On some systems, such as Linux, fdatasync() will also flush the file size if it has changed. But other systems, including some (all?) BSD variants don't flush the file size with fdatasync().
This means that if a developer configures WT with HAVE_FDATASYNC on a BSD system, we might update the turtle file, sync it, but fail to update the size, leaving us with a zero-size file after a poorly timed failure.
I can't prove that this could actually happen. But given the differences in operating system and file system implementations, I can't convince myself that it isn't a risk. So it seems that it would be safest to always use fsync() when updating the turtle file.
Here's what the Linux man page says about fdatasync:
Here's the corresponding information from FreeBSD:
I only call out the turtle file here because we typically update other files (logs and tables) by using fallocate() to extend them, which should update the on-disk file size, after which we don't care if fdatasync() updates the file size, because it shouldn't change.
Note that MacOS uses a different mechanism to implement a reliable data sync, so none of this applies there.