Skip to content

Commit

Permalink
libublk: don't export UblkQueue::q_ring
Browse files Browse the repository at this point in the history
Now we don't have users for manipulating q_ring directly, but there
could be potential use cases, such as, changing uring flags, register
files, ...

So add UblkQueue::uring_op() and UblkQueue::uring_op_mut() for such
purpose.

Signed-off-by: Ming Lei <[email protected]>
  • Loading branch information
ming1 committed Mar 2, 2024
1 parent 6ec066b commit 4940e93
Showing 1 changed file with 69 additions and 3 deletions.
72 changes: 69 additions & 3 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,10 @@ pub struct UblkQueue<'a> {
bufs: RefCell<Vec<*mut u8>>,
state: RefCell<UblkQueueState>,

/// uring is shared for handling target IO, so has to be
/// public
pub q_ring: RefCell<IoUring<squeue::Entry>>,
// call uring_op() and uring_op_mut() for manipulating
// q_ring, and in future it is likely to change to
// thread_local variable
q_ring: RefCell<IoUring<squeue::Entry>>,
}

impl AsRawFd for UblkQueue<'_> {
Expand Down Expand Up @@ -563,6 +564,26 @@ impl UblkQueue<'_> {
Ok(q)
}

// Manipulate immutable queue uring
pub fn uring_op<R, H>(&self, op_handler: H) -> Result<R, UblkError>
where
H: Fn(&IoUring<squeue::Entry>) -> Result<R, UblkError>,
{
let uring = self.q_ring.borrow();

op_handler(&uring)
}

// Manipulate mutable queue uring
pub fn uring_op_mut<R, H>(&self, op_handler: H) -> Result<R, UblkError>
where
H: Fn(&mut IoUring<squeue::Entry>) -> Result<R, UblkError>,
{
let mut uring = self.q_ring.borrow_mut();

op_handler(&mut uring)
}

/// Return queue depth
///
/// Queue depth decides the max count of inflight io command
Expand Down Expand Up @@ -1200,3 +1221,48 @@ impl UblkQueue<'_> {
}
}
}

#[cfg(test)]
mod tests {
use crate::ctrl::UblkCtrlBuilder;
use crate::io::{UblkDev, UblkQueue};
use crate::{UblkError, UblkFlags};
use io_uring::IoUring;

fn __submit_uring_nop(ring: &mut IoUring<io_uring::squeue::Entry>) -> Result<usize, UblkError> {
let nop_e = io_uring::opcode::Nop::new().build().user_data(0x42).into();

unsafe {
let mut queue = ring.submission();
queue.push(&nop_e).expect("queue is full");
}

ring.submit_and_wait(1).map_err(UblkError::IOError)
}

#[test]
fn test_queue_uring_op() {
let ctrl = UblkCtrlBuilder::default()
.dev_flags(UblkFlags::UBLK_DEV_F_ADD_DEV)
.build()
.unwrap();

let tgt_init = |dev: &mut _| {
let q = UblkQueue::new(0, dev)?;

q.uring_op(|ring: &_| {
ring.submitter().unregister_files()?;
ring.submitter()
.register_files(&dev.tgt.fds)
.map_err(UblkError::IOError)
})?;
q.uring_op_mut(|ring: &mut _| -> Result<usize, UblkError> {
__submit_uring_nop(ring)
})?;

Ok(())
};

UblkDev::new(ctrl.get_name(), tgt_init, &ctrl).unwrap();
}
}

0 comments on commit 4940e93

Please sign in to comment.