use core::future::poll_fn;
use core::task::Waker;
use std::io;
use std::sync::Arc;
use super::FileIo;
use super::positional::Out;
use super::work::{Work, counted};
use crate::fs::Allocate;
use crate::fs::call::{self, FileOutcome};
use crate::io::sys;
pub(crate) fn range_end(offset: u64, len: u64) -> io::Result<u64> {
offset
.checked_add(len)
.filter(|end| i64::try_from(*end).is_ok())
.ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"the range ends past the largest offset a file can have",
)
})
}
impl FileIo {
pub(crate) async fn allocate(
self: &Arc<Self>,
offset: u64,
len: u64,
mode: Allocate,
) -> io::Result<()> {
range_end(offset, len)?;
poll_fn(|cx| self.poll_ordered(cx)).await;
Out {
io: self,
work: Some(self.submit_allocate(offset, len, mode, Waker::noop())),
bytes: counted(0),
}
.finish()
.await
}
fn submit_allocate(
&self,
offset: u64,
len: u64,
mode: Allocate,
waker: &Waker,
) -> Work<io::Result<()>> {
#[cfg(ring)]
if self.on_ring()
&& let Ok(job) = crate::fs::ring::allocate(&self.fd, offset, len, mode)
{
return Work::Slot(job);
}
let fd = self.fd.clone();
Work::Slot(call::write_on_pool(
move || FileOutcome::Write(sys::allocate(fd.raw(), offset, len, mode)),
waker,
))
}
}