@lizzy fsync functions as a barrier; it prevents changes after the fsync from being written before changes before the fsync. This is extremely useful for building reliable saving but does not suffice to achieve it alone. AFAIK it sometimes does not guarantee that the changes have been fully written to storage by the time it returns.
To build completely reliable writing of files, you need some way to roll back interrupted changes. There are several approaches; SQLite implements two fairly efficient ways of doing it, and has pretty good documentation on how.
@puppygirlhornypost2 @lizzy AFAIK fsync() works just fine for most cases, but for "must hit disk ASAP" writes, O_DIRECT will bypass the write cache for a given fd, so as long as the fd is blocking, writes will block until the data hits disk. (I had to do that to an imaging program to make the progress bar work, and given the workload in question, going through the write cache and potentially flushing more useful things was pointless)
EDIT: the biggest problem with fsync is if it fails for some reason, because the spec doesn't say what happens in that case.
fsyncing writes without interfering with other portions of ZFS's internals. fsync flushes to ZIL, but as the ZIL is stable storage, the rest of the FS is free to take however long it wants to do the 'normal' TXG write.@lizzy in particular, sqlite assumes that it works. from https://sqlite.org/atomiccommit.html#_hardware_assumptions :
"SQLite assumes that the operating system that it is running on works as advertised. If that is not quite the case, well then hopefully you will not lose power too often."