Do I need to call `flush` before `sync_data`?

In fixing a system crash bug related to writing to a temporary file and then renaming/replacing an existing file to update it, you must call fsync/sync_data before the rename. My question is, does the call to fsync/sync_data make calling flush redundant? This is applicable to all languages fyi. In File in std::fs - Rust, there is no flush, so I'm leaning towards not needing to call flush. Can anyone more knowledgeable in OSes shed some light?

Example

let mut file = NamedTempFile::new_in(MY_DIR)?;
file.write_all(&json)?;
file.flush()?; // is this redundant now that sync_data is being called?
file.as_file_mut().sync_data()?;
file.persist(PATH)?;

From my python app

try:
    tmp_file = SETTINGS_FILE.with_suffix('.json.tmp')
    with open(tmp_file, 'w', encoding='utf-8') as outfile:
        json.dump(settings, outfile, indent=2, escape_forward_slashes=False)
        outfile.flush()  # is this redundant because of fsync?
        os.fsync(outfile.fileno()) # I made a post on Python forum asking for macos support
        # assume the system crashes before the file is closed
    os.replace(tmp_file, SETTINGS_FILE)

Either it's a no-op or it's required. In either case, there's no harm from calling it so go ahead and do so.

The sync_data example in the docs doesn't include flush, so my question is asking if it's harmless to not use flush since the docs doesn't either. I guess if it's a no-op it's not required.

I agree with Alice. You should call it to be future-proof, based on the doc.

https://doc.rust-lang.org/std/fs/struct.File.html#method.flush

§Platform-specific behavior

Since a File structure doesn’t contain any buffers, this function is currently a no-op on Unix and Windows. Note that this may change in the future.

1 Like

Just saw that myself. If File doesn't use any buffers, why is not a no-op on macOS?

Dunno. The point is that it is unspecified, and therefore best to call it to avoid problems, now or in the future. I'd look at the source code to find more details.

macOS is Unix, so I'd expect it to be a no-op there as well.