use std::io;
use std::path::Path;
#[cfg(unix)]
use fs_err::File;
pub fn bulk_sync_dir(dir: &Path) -> io::Result<()> {
#[cfg(any(target_os = "linux", target_os = "android", target_os = "hurd"))]
match nix::unistd::syncfs(File::open(dir)?) {
Ok(()) => return Ok(()),
Err(e) => log::warn!("syncfs failed for {}: {e}", dir.display()),
}
#[cfg(unix)]
sync_dir_with_fsync(dir)?;
#[cfg(not(unix))]
let _ = dir;
Ok(())
}
#[cfg(unix)]
fn sync_dir_with_fsync(dir: &Path) -> io::Result<()> {
for entry in fs_err::read_dir(dir)? {
let entry = entry?;
if entry.file_type()?.is_dir() {
sync_dir_with_fsync(&entry.path())?;
} else {
File::open(entry.path())?.sync_all()?;
}
}
File::open(dir)?.sync_all()?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bulk_sync_dir_succeeds() {
let dir = tempfile::tempdir().unwrap();
fs_err::write(dir.path().join("applied_seq.json"), b"{}").unwrap();
fs_err::create_dir(dir.path().join("sub")).unwrap();
fs_err::write(dir.path().join("sub").join("data"), b"x").unwrap();
bulk_sync_dir(dir.path()).unwrap();
}
}