diff --git a/rust/kernel/file_operations.rs b/rust/kernel/file_operations.rs index ad379ac981ca44..8166f4b2364f19 100644 --- a/rust/kernel/file_operations.rs +++ b/rust/kernel/file_operations.rs @@ -5,10 +5,9 @@ //! C header: [`include/linux/fs.h`](../../../../include/linux/fs.h) use core::convert::{TryFrom, TryInto}; -use core::{marker, mem, ops::Deref, pin::Pin, ptr}; +use core::{marker, mem, ptr}; use alloc::boxed::Box; -use alloc::sync::Arc; use crate::{ bindings, c_types, @@ -16,7 +15,8 @@ use crate::{ file::File, io_buffer::{IoBufferReader, IoBufferWriter}, iov_iter::IovIter, - sync::{CondVar, Ref, RefCounted}, + sync::CondVar, + types::PointerWrapper, user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter}, }; @@ -555,7 +555,7 @@ pub trait FileOperations: Send + Sync + Sized { const TO_USE: ToUse; /// The pointer type that will be used to hold ourselves. - type Wrapper: PointerWrapper = Box; + type Wrapper: PointerWrapper = Box; /// Cleans up after the last reference to the file goes away. /// @@ -633,64 +633,3 @@ pub trait FileOperations: Send + Sync + Sized { Ok(bindings::POLLIN | bindings::POLLOUT | bindings::POLLRDNORM | bindings::POLLWRNORM) } } - -/// Used to convert an object into a raw pointer that represents it. -/// -/// It can eventually be converted back into the object. This is used to store objects as pointers -/// in kernel data structures, for example, an implementation of [`FileOperations`] in `struct -/// file::private_data`. -pub trait PointerWrapper { - /// Returns the raw pointer. - fn into_pointer(self) -> *const T; - - /// Returns the instance back from the raw pointer. - /// - /// # Safety - /// - /// The passed pointer must come from a previous call to [`PointerWrapper::into_pointer()`]. - unsafe fn from_pointer(ptr: *const T) -> Self; -} - -impl PointerWrapper for Box { - fn into_pointer(self) -> *const T { - Box::into_raw(self) - } - - unsafe fn from_pointer(ptr: *const T) -> Self { - Box::from_raw(ptr as _) - } -} - -impl PointerWrapper for Ref { - fn into_pointer(self) -> *const T { - Ref::into_raw(self) - } - - unsafe fn from_pointer(ptr: *const T) -> Self { - Ref::from_raw(ptr as _) - } -} - -impl PointerWrapper for Arc { - fn into_pointer(self) -> *const T { - Arc::into_raw(self) - } - - unsafe fn from_pointer(ptr: *const T) -> Self { - Arc::from_raw(ptr) - } -} - -impl + Deref> PointerWrapper for Pin { - fn into_pointer(self) -> *const T { - // SAFETY: We continue to treat the pointer as pinned by returning just a pointer to it to - // the caller. - let inner = unsafe { Pin::into_inner_unchecked(self) }; - inner.into_pointer() - } - - unsafe fn from_pointer(p: *const T) -> Self { - // SAFETY: The object was originally pinned. - Pin::new_unchecked(W::from_pointer(p)) - } -} diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 6207670c329049..5af7cf8cf80664 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -4,9 +4,13 @@ //! //! C header: [`include/linux/types.h`](../../../../include/linux/types.h) -use core::ops::Deref; +use core::{ops::Deref, pin::Pin}; + +use alloc::{boxed::Box, sync::Arc}; use crate::bindings; +use crate::c_types; +use crate::sync::{Ref, RefCounted}; /// Permissions. /// @@ -71,3 +75,64 @@ macro_rules! cstr { unsafe { $crate::CStr::new_unchecked(s) } }}; } + +/// Used to convert an object into a raw pointer that represents it. +/// +/// It can eventually be converted back into the object. This is used to store objects as pointers +/// in kernel data structures, for example, an implementation of [`FileOperations`] in `struct +/// file::private_data`. +pub trait PointerWrapper { + /// Returns the raw pointer. + fn into_pointer(self) -> *const c_types::c_void; + + /// Returns the instance back from the raw pointer. + /// + /// # Safety + /// + /// The passed pointer must come from a previous call to [`PointerWrapper::into_pointer()`]. + unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self; +} + +impl PointerWrapper for Box { + fn into_pointer(self) -> *const c_types::c_void { + Box::into_raw(self) as _ + } + + unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self { + Box::from_raw(ptr as _) + } +} + +impl PointerWrapper for Ref { + fn into_pointer(self) -> *const c_types::c_void { + Ref::into_raw(self) as _ + } + + unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self { + Ref::from_raw(ptr as _) + } +} + +impl PointerWrapper for Arc { + fn into_pointer(self) -> *const c_types::c_void { + Arc::into_raw(self) as _ + } + + unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self { + Arc::from_raw(ptr as _) + } +} + +impl PointerWrapper for Pin { + fn into_pointer(self) -> *const c_types::c_void { + // SAFETY: We continue to treat the pointer as pinned by returning just a pointer to it to + // the caller. + let inner = unsafe { Pin::into_inner_unchecked(self) }; + inner.into_pointer() + } + + unsafe fn from_pointer(p: *const c_types::c_void) -> Self { + // SAFETY: The object was originally pinned. + Pin::new_unchecked(T::from_pointer(p)) + } +}