mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
make write_at
unsafe fn and add more safety comments
This commit is contained in:
parent
901986c82d
commit
05c8c17e06
@ -56,7 +56,15 @@ async fn write_uring(path: &Path, contents: OwnedBuf) -> io::Result<()> {
|
|||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
let mut buf = contents.as_ref();
|
let mut buf = contents.as_ref();
|
||||||
while !buf.is_empty() {
|
while !buf.is_empty() {
|
||||||
let n = Op::write_at(fd, buf, pos)?.await? as usize;
|
// SAFETY:
|
||||||
|
// If the operation completes successfully, `fd` and `buf` are still
|
||||||
|
// alive within the scope of this function, so remain valid.
|
||||||
|
//
|
||||||
|
// In the case of cancellation, local variables within the scope of
|
||||||
|
// this `async fn` are dropped in the reverse order of their declaration.
|
||||||
|
// Therefore, `Op` is dropped before `fd` and `buf`, ensuring that the
|
||||||
|
// operation finishes gracefully before these resources are dropped.
|
||||||
|
let n = unsafe { Op::write_at(fd, buf, pos) }?.await? as usize;
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return Err(io::ErrorKind::WriteZero.into());
|
return Err(io::ErrorKind::WriteZero.into());
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,12 @@ impl Cancellable for Write {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Op<Write> {
|
impl Op<Write> {
|
||||||
pub(crate) fn write_at(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result<Self> {
|
/// # SAFETY
|
||||||
|
///
|
||||||
|
/// The caller must ensure that `fd` and `buf` remain valid until the
|
||||||
|
/// operation finishes (or gets cancelled) and the `Op::drop` completes.
|
||||||
|
/// Otherwise, the kernel could access freed memory, breaking soundness.
|
||||||
|
pub(crate) unsafe fn write_at(fd: BorrowedFd<'_>, buf: &[u8], offset: u64) -> io::Result<Self> {
|
||||||
// There is a cap on how many bytes we can write in a single uring write operation.
|
// There is a cap on how many bytes we can write in a single uring write operation.
|
||||||
// ref: https://github.com/axboe/liburing/discussions/497
|
// ref: https://github.com/axboe/liburing/discussions/497
|
||||||
let len: u32 = cmp::min(buf.len(), u32::MAX as usize) as u32;
|
let len: u32 = cmp::min(buf.len(), u32::MAX as usize) as u32;
|
||||||
@ -32,8 +37,8 @@ impl Op<Write> {
|
|||||||
.offset(offset)
|
.offset(offset)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// SAFETY: `fd` and `buf` are owned by caller function, ensuring these params are
|
// SAFETY: `fd` and `buf` valid until the operation completes or gets cancelled
|
||||||
// valid until operation completes.
|
// and the `Op::drop` completes.
|
||||||
let op = unsafe { Op::new(sqe, Write) };
|
let op = unsafe { Op::new(sqe, Write) };
|
||||||
Ok(op)
|
Ok(op)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user