use dragonfly_client_core::Result;
use tokio::fs;
#[cfg(target_os = "linux")]
use tracing::warn;
#[allow(unused_variables)]
pub async fn fallocate(f: &fs::File, length: u64) -> Result<()> {
if length == 0 {
return Ok(());
}
#[cfg(target_os = "linux")]
{
use dragonfly_client_core::Error;
use rustix::fs::{fallocate, FallocateFlags};
use std::os::unix::io::AsFd;
use tokio::io;
f.set_len(length).await?;
let f = f.try_clone().await?;
tokio::task::spawn_blocking(move || {
let fd = f.as_fd();
let offset = 0;
let flags = FallocateFlags::KEEP_SIZE;
loop {
match fallocate(fd, flags, offset, length) {
Ok(_) => return Ok(()),
Err(rustix::io::Errno::INTR) => continue,
Err(err)
if err == rustix::io::Errno::NOTSUP
|| err == rustix::io::Errno::OPNOTSUPP =>
{
warn!("fallocate not supported, skipping preallocation");
return Ok(());
}
Err(err) => {
return Err(Error::IO(io::Error::from_raw_os_error(err.raw_os_error())))
}
}
}
})
.await
.map_err(io::Error::other)??;
}
Ok(())
}