If you're generating an immutable file, a common technique is to play fsync + rename tricks although I think a more modern technique would be:
1. open directory (dir_fd)
2. create an unnamed O_TMPFILE file (file_fd)
3. write to file_fd
4. fdatasync(file_fd)
5. linkat(dir_fd, "", dir_fd, "file name", AT_EMPTY_PATH)
5. fsync(dir_fd)
This should guarantee that either "file name" will have the old contents or the new contents and no transient version is observed. The "old" mechanism is similar in that you write out to a temporary sibling and rename (these days you'd use RENAME_EXCHANGE w/ renameat2 to guarantee the atomicity or get an error) with the differentiating difference being that the temporary data could be observed on the filesystem / left around if you have a machine reboot.