// Copyright (C) 2019 Alibaba Cloud Computing. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause

//! Safe wrapper over [`Linux AIO`](http://man7.org/linux/man-pages/man7/aio.7.html).

#![allow(non_camel_case_types)]

/* automatically generated by rust-bindgen from file linux/include/uapi/linux/aio_abi.h
 * of commit 69973b8 and then manually edited */

use std::io::{Error, Result};
use std::os::raw::{c_int, c_long, c_uint, c_ulong};
use std::ptr::null_mut;

type __s16 = ::std::os::raw::c_short;
type __u16 = ::std::os::raw::c_ushort;
type __u32 = ::std::os::raw::c_uint;
type __s64 = ::std::os::raw::c_longlong;
type __u64 = ::std::os::raw::c_ulonglong;

/// Read from a file descriptor at a given offset.
pub const IOCB_CMD_PREAD: u32 = 0;
/// Write to a file descriptor at a given offset.
pub const IOCB_CMD_PWRITE: u32 = 1;
/// Synchronize a file's in-core metadata and data to storage device.
pub const IOCB_CMD_FSYNC: u32 = 2;
/// Synchronize a file's in-core data to storage device.
pub const IOCB_CMD_FDSYNC: u32 = 3;
/// Noop, this defined by never used by linux kernel.
pub const IOCB_CMD_NOOP: u32 = 6;
/// Read from a file descriptor at a given offset into multiple buffers.
pub const IOCB_CMD_PREADV: u32 = 7;
/// Write to a file descriptor at a given offset from multiple buffers.
pub const IOCB_CMD_PWRITEV: u32 = 8;

/// Valid flags for the "aio_flags" member of the "struct iocb".
/// Set if the "aio_resfd" member of the "struct iocb" is valid.
pub const IOCB_FLAG_RESFD: u32 = 1;

/// Maximum number of concurrent requests.
pub const MAX_REQUESTS: usize = 0x10000;

/// Wrapper over the [`iocb`](https://elixir.bootlin.com/linux/v4.9/source/include/uapi/linux/aio_abi.h#L79) structure.
#[allow(missing_docs)]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct IoControlBlock {
    pub aio_data: __u64,
    pub aio_key: __u32,
    pub aio_reserved1: __u32,
    pub aio_lio_opcode: __u16,
    pub aio_reqprio: __s16,
    pub aio_fildes: __u32,
    pub aio_buf: __u64,
    pub aio_nbytes: __u64,
    pub aio_offset: __s64,
    pub aio_reserved2: __u64,
    pub aio_flags: __u32,
    pub aio_resfd: __u32,
}

/// Wrapper over the [`io_event`](https://elixir.bootlin.com/linux/v4.9/source/include/uapi/linux/aio_abi.h#L58) structure.
#[allow(missing_docs)]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct IoEvent {
    pub data: __u64,
    pub obj: __u64,
    pub res: __s64,
    pub res2: __s64,
}

/// Newtype for [`aio_context_t`](https://elixir.bootlin.com/linux/v4.9/source/include/uapi/linux/aio_abi.h#L33).
#[repr(transparent)]
#[derive(Debug)]
pub struct IoContext(::std::os::raw::c_ulong);

impl IoContext {
    /// Create a new aio context instance.
    ///
    /// Refer to Linux [`io_setup`](http://man7.org/linux/man-pages/man2/io_setup.2.html).
    ///
    /// # Arguments
    /// * `nr_events`: maximum number of concurrently processing IO operations.
    #[allow(clippy::new_ret_no_self)]
    pub fn new(nr_events: c_uint) -> Result<Self> {
        if nr_events as usize > MAX_REQUESTS {
            return Err(Error::from_raw_os_error(libc::EINVAL));
        }

        let mut ctx = IoContext(0);
        let rc =
            // SAFETY: Safe because we use valid parameters and check the result.
            unsafe { libc::syscall(libc::SYS_io_setup, nr_events, &mut ctx as *mut Self) as c_int };
        if rc < 0 {
            Err(Error::last_os_error())
        } else {
            Ok(ctx)
        }
    }

    /// Submit asynchronous I/O blocks for processing.
    ///
    /// Refer to Linux [`io_submit`](http://man7.org/linux/man-pages/man2/io_submit.2.html).
    ///
    /// # Arguments
    /// * `iocbs`: array of AIO control blocks, which will be submitted to the context.
    ///
    /// # Examples
    /// ```
    /// extern crate vmm_sys_util;
    /// use vmm_sys_util::aio::*;
    /// # use std::fs::File;
    /// # use std::os::unix::io::AsRawFd;
    ///
    /// let file = File::open("/dev/zero").unwrap();
    /// let ctx = IoContext::new(128).unwrap();
    /// let mut buf: [u8; 4096] = unsafe { std::mem::uninitialized() };
    /// let iocbs = [&mut IoControlBlock {
    ///     aio_fildes: file.as_raw_fd() as u32,
    ///     aio_lio_opcode: IOCB_CMD_PREAD as u16,
    ///     aio_buf: buf.as_mut_ptr() as u64,
    ///     aio_nbytes: buf.len() as u64,
    ///     ..Default::default()
    /// }];
    /// assert_eq!(ctx.submit(&iocbs[..]).unwrap(), 1);
    /// ```
    pub fn submit(&self, iocbs: &[&mut IoControlBlock]) -> Result<usize> {
        // SAFETY: It's safe because parameters are valid and we have checked the result.
        let rc = unsafe {
            libc::syscall(
                libc::SYS_io_submit,
                self.0,
                iocbs.len() as c_ulong,
                iocbs.as_ptr(),
            ) as c_int
        };
        if rc < 0 {
            Err(Error::last_os_error())
        } else {
            Ok(rc as usize)
        }
    }

    /// Cancel an outstanding asynchronous I/O operation.
    ///
    /// Refer to Linux [`io_cancel`](http://man7.org/linux/man-pages/man2/io_cancel.2.html).
    /// Note: according to current Linux kernel implementation(v4.19), libc::SYS_io_cancel always
    /// return failure, thus rendering it useless.
    ///
    /// # Arguments
    /// * `iocb`: The iocb for the operation to be canceled.
    /// * `result`: If the operation is successfully canceled, the event will be copied into the
    ///             memory pointed to by result without being placed into the completion queue.
    pub fn cancel(&self, iocb: &IoControlBlock, result: &mut IoEvent) -> Result<()> {
        // SAFETY: It's safe because parameters are valid and we have checked the result.
        let rc = unsafe {
            libc::syscall(
                libc::SYS_io_cancel,
                self.0,
                iocb as *const IoControlBlock,
                result as *mut IoEvent,
            ) as c_int
        };
        if rc < 0 {
            Err(Error::last_os_error())
        } else {
            Ok(())
        }
    }

    /// Read asynchronous I/O events from the completion queue.
    ///
    /// Refer to Linux [`io_getevents`](http://man7.org/linux/man-pages/man2/io_getevents.2.html).
    ///
    /// # Arguments
    /// * `min_nr`: read at least min_nr events.
    /// * `events`: array to receive the io operation results.
    /// * `timeout`: optional amount of time to wait for events.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate vmm_sys_util;
    /// use vmm_sys_util::aio::*;
    /// # use std::fs::File;
    /// # use std::os::unix::io::AsRawFd;
    ///
    /// let file = File::open("/dev/zero").unwrap();
    /// let ctx = IoContext::new(128).unwrap();
    /// let mut buf: [u8; 4096] = unsafe { std::mem::uninitialized() };
    /// let iocbs = [
    ///     &mut IoControlBlock {
    ///         aio_fildes: file.as_raw_fd() as u32,
    ///         aio_lio_opcode: IOCB_CMD_PREAD as u16,
    ///         aio_buf: buf.as_mut_ptr() as u64,
    ///         aio_nbytes: buf.len() as u64,
    ///         ..Default::default()
    ///     },
    ///     &mut IoControlBlock {
    ///         aio_fildes: file.as_raw_fd() as u32,
    ///         aio_lio_opcode: IOCB_CMD_PREAD as u16,
    ///         aio_buf: buf.as_mut_ptr() as u64,
    ///         aio_nbytes: buf.len() as u64,
    ///         ..Default::default()
    ///     },
    /// ];
    ///
    /// let mut rc = ctx.submit(&iocbs[..]).unwrap();
    /// let mut events = [unsafe { std::mem::uninitialized::<IoEvent>() }];
    /// rc = ctx.get_events(1, &mut events, None).unwrap();
    /// assert_eq!(rc, 1);
    /// assert!(events[0].res > 0);
    /// rc = ctx.get_events(1, &mut events, None).unwrap();
    /// assert_eq!(rc, 1);
    /// assert!(events[0].res > 0);
    /// ```
    pub fn get_events(
        &self,
        min_nr: c_long,
        events: &mut [IoEvent],
        timeout: Option<&mut libc::timespec>,
    ) -> Result<usize> {
        let to = match timeout {
            Some(val) => val as *mut libc::timespec,
            None => null_mut(),
        };

        // SAFETY: It's safe because parameters are valid and we have checked the result.
        let rc = unsafe {
            libc::syscall(
                libc::SYS_io_getevents,
                self.0,
                min_nr,
                events.len() as c_long,
                events.as_mut_ptr(),
                to,
            ) as c_int
        };
        if rc < 0 {
            Err(Error::last_os_error())
        } else {
            Ok(rc as usize)
        }
    }
}

impl Drop for IoContext {
    fn drop(&mut self) {
        if self.0 != 0 {
            // SAFETY: It's safe because the context is created by us.
            let _ = unsafe { libc::syscall(libc::SYS_io_destroy, self.0) as c_int };
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::fs::File;
    use std::os::unix::io::AsRawFd;

    #[test]
    fn test_new_context() {
        let _ = IoContext::new(0).unwrap_err();
    }

    #[test]
    fn test_cancel_request() {
        let file = File::open("/dev/zero").unwrap();

        let ctx = IoContext::new(128).unwrap();
        let mut buf: [u8; 16384] = [0u8; 16384];
        let iocbs = [&mut IoControlBlock {
            aio_fildes: file.as_raw_fd() as u32,
            aio_lio_opcode: IOCB_CMD_PREAD as u16,
            aio_buf: buf.as_mut_ptr() as u64,
            aio_nbytes: buf.len() as u64,
            ..Default::default()
        }];

        let mut rc = ctx.submit(&iocbs).unwrap();
        assert_eq!(rc, 1);

        let mut result = Default::default();
        let err = ctx
            .cancel(iocbs[0], &mut result)
            .unwrap_err()
            .raw_os_error()
            .unwrap();
        assert_eq!(err, libc::EINVAL);

        let mut events = [IoEvent::default()];
        rc = ctx.get_events(1, &mut events, None).unwrap();
        assert_eq!(rc, 1);
        assert!(events[0].res > 0);
    }

    #[test]
    fn test_read_zero() {
        let file = File::open("/dev/zero").unwrap();

        let ctx = IoContext::new(128).unwrap();
        let mut buf: [u8; 4096] = [0u8; 4096];
        let iocbs = [
            &mut IoControlBlock {
                aio_fildes: file.as_raw_fd() as u32,
                aio_lio_opcode: IOCB_CMD_PREAD as u16,
                aio_buf: buf.as_mut_ptr() as u64,
                aio_nbytes: buf.len() as u64,
                ..Default::default()
            },
            &mut IoControlBlock {
                aio_fildes: file.as_raw_fd() as u32,
                aio_lio_opcode: IOCB_CMD_PREAD as u16,
                aio_buf: buf.as_mut_ptr() as u64,
                aio_nbytes: buf.len() as u64,
                ..Default::default()
            },
        ];

        let mut rc = ctx.submit(&iocbs[..]).unwrap();
        assert_eq!(rc, 2);

        let mut events = [IoEvent::default()];
        rc = ctx.get_events(1, &mut events, None).unwrap();
        assert_eq!(rc, 1);
        assert!(events[0].res > 0);

        rc = ctx.get_events(1, &mut events, None).unwrap();
        assert_eq!(rc, 1);
        assert!(events[0].res > 0);
    }

    #[test]
    fn bindgen_test_layout_io_event() {
        assert_eq!(
            ::std::mem::size_of::<IoEvent>(),
            32usize,
            concat!("Size of: ", stringify!(IoEvent))
        );
        assert_eq!(
            ::std::mem::align_of::<IoEvent>(),
            8usize,
            concat!("Alignment of", stringify!(IoEvent))
        );
    }

    #[test]
    fn bindgen_test_layout_iocb() {
        assert_eq!(
            ::std::mem::size_of::<IoControlBlock>(),
            64usize,
            concat!("Size of:", stringify!(IoControlBlock))
        );
        assert_eq!(
            ::std::mem::align_of::<IoControlBlock>(),
            8usize,
            concat!("Alignment of", stringify!(IoControlBlock))
        );
    }
}
