Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/target
/Cargo.lock
/.claude
/*.patch
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ async fn io_task(q: &UblkQueue<'_>, tag: u16) {
loop {
// Complete previous command with result and re-submit
// IO command for fetching new IO request from /dev/ublkbN
res = q.submit_io_cmd(tag, cmd_op, buf.as_mut_ptr(), res).await;
res = q.submit_io_cmd_unified(tag, cmd_op, BufDesc::Slice(buf.as_slice()), res).unwrap().await;
if res == libublk::sys::UBLK_IO_RES_ABORT {
break;
}
Expand Down
24 changes: 11 additions & 13 deletions examples/loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use clap::{Arg, ArgAction, Command};
use ilog::IntLog;
use io_uring::{opcode, squeue, types};
use libublk::helpers::IoBuf;
use libublk::io::{UblkDev, UblkIOCtx, UblkQueue};
use libublk::io::{UblkDev, UblkIOCtx, UblkQueue, BufDescList};
use libublk::uring_async::ublk_wait_and_handle_ios;
use libublk::{ctrl::UblkCtrl, sys, UblkError, UblkFlags, UblkIORes};
use libublk::{ctrl::UblkCtrl, sys, UblkError, UblkFlags, UblkIORes, BufDesc};
use serde::Serialize;
use std::os::unix::fs::FileTypeExt;
use std::os::unix::io::AsRawFd;
Expand Down Expand Up @@ -198,22 +198,22 @@ fn lo_handle_io_cmd_sync(q: &UblkQueue<'_>, tag: u16, i: &UblkIOCtx, io_slice: &
assert!(cqe_tag == tag as u32);

if res != -(libc::EAGAIN) {
q.complete_io_cmd(
q.complete_io_cmd_unified(
tag,
io_slice.as_ptr() as *mut u8,
BufDesc::Slice(io_slice),
Ok(UblkIORes::Result(res)),
);
).unwrap();
return;
}
}

let res = __lo_prep_submit_io_cmd(iod);
if res < 0 {
q.complete_io_cmd(
q.complete_io_cmd_unified(
tag,
io_slice.as_ptr() as *mut u8,
BufDesc::Slice(io_slice),
Ok(UblkIORes::Result(res)),
);
).unwrap();
} else {
let op = iod.op_flags & 0xff;
// either start to handle or retry
Expand Down Expand Up @@ -245,7 +245,7 @@ fn q_fn(qid: u16, dev: &UblkDev) {
UblkQueue::new(qid, dev)
.unwrap()
.regiser_io_bufs(Some(&bufs))
.submit_fetch_commands(Some(&bufs))
.submit_fetch_commands_unified(BufDescList::Slices(Some(&bufs))).unwrap()
.wait_and_handle_io(lo_io_handler);
}

Expand All @@ -261,15 +261,13 @@ fn q_a_fn(qid: u16, dev: &UblkDev, depth: u16) {
// Use IoBuf for safe I/O buffer management with automatic memory alignment
let mut buf = IoBuf::<u8>::new(q.dev.dev_info.max_io_buf_bytes as usize);

// Extract raw pointer only when required by libublk APIs for buffer registration
// The raw pointer is needed for the libublk buffer registration system
let buf_addr = buf.as_mut_ptr();
// No longer need raw pointer since we use the unified API with slices
let mut cmd_op = sys::UBLK_U_IO_FETCH_REQ;
let mut res = 0;

q.register_io_buf(tag, &buf);
loop {
let cmd_res = q.submit_io_cmd(tag, cmd_op, buf_addr, res).await;
let cmd_res = q.submit_io_cmd_unified(tag, cmd_op, BufDesc::Slice(buf.as_slice()), res).unwrap().await;
if cmd_res == sys::UBLK_IO_RES_ABORT {
break;
}
Expand Down
37 changes: 23 additions & 14 deletions examples/null.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use bitflags::bitflags;
use clap::{Arg, ArgAction, Command};
use libublk::helpers::IoBuf;
use libublk::io::{UblkDev, UblkIOCtx, UblkQueue};
use libublk::io::{UblkDev, UblkIOCtx, UblkQueue, BufDescList};
use libublk::uring_async::ublk_wait_and_handle_ios;
use libublk::{ctrl::UblkCtrl, UblkFlags, UblkIORes};
use libublk::{ctrl::UblkCtrl, UblkFlags, UblkIORes, BufDesc};
use std::rc::Rc;

bitflags! {
Expand All @@ -26,9 +26,17 @@ fn get_io_cmd_result(q: &UblkQueue, tag: u16) -> i32 {
#[inline]
fn handle_io_cmd(q: &UblkQueue, tag: u16, io_slice: Option<&[u8]>) {
let bytes = get_io_cmd_result(q, tag);
// Convert back to raw pointer only when required by the libublk API
let buf_addr = io_slice.map_or(std::ptr::null_mut(), |s| s.as_ptr() as *mut u8);
q.complete_io_cmd(tag, buf_addr, Ok(UblkIORes::Result(bytes)));

// Use unified buffer API - choose appropriate buffer descriptor based on mode
let buf_desc = if let Some(slice) = io_slice {
BufDesc::Slice(slice)
} else {
// For user_copy mode, create an empty slice since no buffer is needed
BufDesc::Slice(&[])
};

q.complete_io_cmd_unified(tag, buf_desc, Ok(UblkIORes::Result(bytes)))
.unwrap();
}

fn q_sync_fn(qid: u16, dev: &UblkDev, user_copy: bool) {
Expand All @@ -52,7 +60,7 @@ fn q_sync_fn(qid: u16, dev: &UblkDev, user_copy: bool) {
UblkQueue::new(qid, dev)
.unwrap()
.regiser_io_bufs(if user_copy { None } else { Some(&bufs_rc) })
.submit_fetch_commands(if user_copy { None } else { Some(&bufs_rc) })
.submit_fetch_commands_unified(BufDescList::Slices(if user_copy { None } else { Some(&bufs_rc) })).unwrap()
.wait_and_handle_io(io_handler);
}

Expand All @@ -68,20 +76,21 @@ fn q_async_fn(qid: u16, dev: &UblkDev, user_copy: bool) {
let mut cmd_op = libublk::sys::UBLK_U_IO_FETCH_REQ;
let mut res = 0;
// Use IoBuf with slice-based access for memory safety
let (_buf, buf_addr) = if user_copy {
(None, std::ptr::null_mut())
let _buf = if user_copy {
None
} else {
let buf = IoBuf::<u8>::new(q.dev.dev_info.max_io_buf_bytes as usize);

q.register_io_buf(tag, &buf);
// Extract raw pointer only when required by libublk APIs
// IoBuf provides safe slice access via Deref/DerefMut traits
let addr = buf.as_mut_ptr();
(Some(buf), addr)
Some(buf)
};

loop {
let cmd_res = q.submit_io_cmd(tag, cmd_op, buf_addr, res).await;
let buf_desc = if user_copy {
BufDesc::Slice(&[])
} else {
BufDesc::Slice(_buf.as_ref().unwrap().as_slice())
};
let cmd_res = q.submit_io_cmd_unified(tag, cmd_op, buf_desc, res).unwrap().await;
if cmd_res == libublk::sys::UBLK_IO_RES_ABORT {
break;
}
Expand Down
8 changes: 3 additions & 5 deletions examples/ramdisk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use libublk::ctrl::UblkCtrl;
use libublk::helpers::IoBuf;
use libublk::io::{UblkDev, UblkQueue};
use libublk::uring_async::ublk_run_ctrl_task;
use libublk::{UblkError, UblkFlags};
use libublk::{UblkError, UblkFlags, BufDesc};
use std::io::{Error, ErrorKind};
use std::rc::Rc;
use std::sync::Arc;
Expand Down Expand Up @@ -80,14 +80,12 @@ async fn io_task(q: &UblkQueue<'_>, tag: u16, ramdisk_storage: &mut [u8]) {
// IoBuf provides slice-based access through Deref/DerefMut traits
let mut buffer = IoBuf::<u8>::new(buf_size);

// Extract raw pointer only when required by libublk APIs
// For actual memory operations, we'll use safe slice access
let addr = buffer.as_mut_ptr();
// No longer need raw pointer since we use the unified API with slices
let mut cmd_op = libublk::sys::UBLK_U_IO_FETCH_REQ;
let mut res = 0;

loop {
let cmd_res = q.submit_io_cmd(tag, cmd_op, addr, res).await;
let cmd_res = q.submit_io_cmd_unified(tag, cmd_op, BufDesc::Slice(buffer.as_slice()), res).unwrap().await;
if cmd_res == libublk::sys::UBLK_IO_RES_ABORT {
break;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ctrl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,7 @@ mod tests {
Ok(())
};
let q_fn = move |qid: u16, dev: &UblkDev| {
use crate::BufDescList;
let bufs_rc = Rc::new(dev.alloc_queue_io_bufs());
let bufs = bufs_rc.clone();

Expand All @@ -1874,7 +1875,7 @@ mod tests {
UblkQueue::new(qid, dev)
.unwrap()
.regiser_io_bufs(Some(&bufs))
.submit_fetch_commands(Some(&bufs))
.submit_fetch_commands_unified(BufDescList::Slices(Some(&bufs))).unwrap()
.wait_and_handle_io(io_handler);
};

Expand Down
Loading