diff --git a/tokio-epoll-uring/src/ops/statx.rs b/tokio-epoll-uring/src/ops/statx.rs index 7c63190..c505c50 100644 --- a/tokio-epoll-uring/src/ops/statx.rs +++ b/tokio-epoll-uring/src/ops/statx.rs @@ -1,6 +1,6 @@ use crate::system::submission::op_fut::Op; use crate::util::submitting_box::SubmittingBox; -use std::os::fd::AsRawFd; +use std::{mem::MaybeUninit, os::fd::AsRawFd}; use uring_common::libc; pub use uring_common::libc::statx; use uring_common::{ @@ -28,7 +28,7 @@ where { ByFileDescriptor { file: F, - statxbuf: Box, + statxbuf: Box>, }, } diff --git a/tokio-epoll-uring/src/system/lifecycle/handle.rs b/tokio-epoll-uring/src/system/lifecycle/handle.rs index 0957a2f..ce8beae 100644 --- a/tokio-epoll-uring/src/system/lifecycle/handle.rs +++ b/tokio-epoll-uring/src/system/lifecycle/handle.rs @@ -1,7 +1,7 @@ //! Owned handle to an explicitly [`System::launch`](crate::System::launch)ed system. use futures::FutureExt; -use std::{os::fd::OwnedFd, path::Path, task::ready}; +use std::{mem::MaybeUninit, os::fd::OwnedFd, path::Path, task::ready}; use uring_common::{buf::BoundedBufMut, io_fd::IoFd}; use crate::{ @@ -182,12 +182,8 @@ impl crate::SystemHandle { crate::system::submission::op_fut::Error, >, ) { - // TODO: avoid the allocation, or optimize using a slab cacke? - let buf: Box = Box::new( - // TODO replace with Box, https://github.com/rust-lang/rust/issues/63291 - // SAFETY: we only use the memory if the fstat succeeds, should be using MaybeUninit here. - unsafe { std::mem::zeroed() }, - ); + // TODO: avoid the allocation, or optimize using a slab cache? + let buf: Box> = Box::new(MaybeUninit::uninit()); let op = statx::op(statx::Resources::ByFileDescriptor { file, statxbuf: buf, @@ -196,7 +192,20 @@ impl crate::SystemHandle { let (resources, result) = execute_op(op, inner.submit_side.weak(), None).await; let crate::ops::statx::Resources::ByFileDescriptor { file, statxbuf } = resources; match result { - Ok(()) => (file, Ok(statxbuf)), + Ok(()) => ( + file, + Ok({ + // TODO: replace this with Box::assume_init once it stabilizes + // SAFETY: if the kernel tells us the call went ok, we know the statx has been initialized + unsafe { + // It seems weird that current rust 1.75 Box::assume_init doesn't do the assert_inhabited + // that the regular MaybeUninit::assume_init does. Out of precaution, do that here. + statxbuf.assume_init_ref(); + let raw = Box::into_raw(statxbuf); + Box::from_raw(raw as *mut uring_common::libc::statx) + } + }), + ), Err(e) => (file, Err(e)), } } diff --git a/tokio-epoll-uring/src/util/submitting_box.rs b/tokio-epoll-uring/src/util/submitting_box.rs index f8dbbd6..80ded48 100644 --- a/tokio-epoll-uring/src/util/submitting_box.rs +++ b/tokio-epoll-uring/src/util/submitting_box.rs @@ -1,20 +1,22 @@ //! See [`SubmittingBox`]. +use std::mem::MaybeUninit; + /// A wrapper around [`Box`] with an API that forces users to spell out /// ownerhsip transitions of the memory between kernel and userspace. pub enum SubmittingBox where T: 'static, { - NotSubmitting { inner: Box }, - Submitting(*mut T), + NotSubmitting { inner: Box> }, + Submitting(*mut MaybeUninit), Undefined, } unsafe impl Send for SubmittingBox where T: Send {} impl SubmittingBox { - pub(crate) fn new(inner: Box) -> Self { + pub(crate) fn new(inner: Box>) -> Self { Self::NotSubmitting { inner } } @@ -29,7 +31,7 @@ impl SubmittingBox { SubmittingBox::NotSubmitting { inner } => { let leaked = Box::into_raw(inner); *self = Self::Submitting(leaked); - leaked + leaked as *mut T } SubmittingBox::Submitting(_) => { panic!("must not call this function more than once without ownership_back_in_userspace() inbetween") @@ -50,7 +52,7 @@ impl SubmittingBox { /// /// Callers must ensure that userspace, and in particular, _the caller_ has again exclusive ownership /// over the memory. - pub(crate) unsafe fn ownership_back_in_userspace(mut self) -> Box { + pub(crate) unsafe fn ownership_back_in_userspace(mut self) -> Box> { match std::mem::replace(&mut self, SubmittingBox::Undefined) { SubmittingBox::NotSubmitting { .. } => { panic!("must not call this function without prior call to start_submitting()")