kvarn_tokio_uring/io/
write.rs

1use crate::{buf::BoundedBuf, io::SharedFd, BufResult, OneshotOutputTransform, UnsubmittedOneshot};
2use io_uring::cqueue::Entry;
3use std::io;
4use std::marker::PhantomData;
5
6/// An unsubmitted write operation.
7pub type UnsubmittedWrite<T> = UnsubmittedOneshot<WriteData<T>, WriteTransform<T>>;
8
9#[allow(missing_docs)]
10pub struct WriteData<T> {
11    /// Holds a strong ref to the FD, preventing the file from being closed
12    /// while the operation is in-flight.
13    _fd: SharedFd,
14
15    buf: T,
16}
17
18#[allow(missing_docs)]
19pub struct WriteTransform<T> {
20    _phantom: PhantomData<T>,
21}
22
23impl<T> OneshotOutputTransform for WriteTransform<T> {
24    type Output = BufResult<usize, T>;
25    type StoredData = WriteData<T>;
26
27    fn transform_oneshot_output(self, data: Self::StoredData, cqe: Entry) -> Self::Output {
28        let res = if cqe.result() >= 0 {
29            Ok(cqe.result() as usize)
30        } else {
31            Err(io::Error::from_raw_os_error(-cqe.result()))
32        };
33
34        (res, data.buf)
35    }
36}
37
38impl<T: BoundedBuf> UnsubmittedWrite<T> {
39    pub(crate) fn write_at(fd: &SharedFd, buf: T, offset: u64) -> Self {
40        use io_uring::{opcode, types};
41
42        // Get raw buffer info
43        let ptr = buf.stable_ptr();
44        let len = buf.bytes_init();
45
46        Self::new(
47            WriteData {
48                _fd: fd.clone(),
49                buf,
50            },
51            WriteTransform {
52                _phantom: PhantomData,
53            },
54            opcode::Write::new(types::Fd(fd.raw_fd()), ptr, len as _)
55                .offset(offset as _)
56                .build(),
57        )
58    }
59}