Skip to content

Commit 1efbbe6

Browse files
authored
Merge pull request #185 from Sylfrena/expose-pointer
rust/kernel: Move PointerWrapper trait to types.rs
2 parents 99bec9d + ab9da39 commit 1efbbe6

File tree

2 files changed

+70
-66
lines changed

2 files changed

+70
-66
lines changed

rust/kernel/file_operations.rs

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@
55
//! C header: [`include/linux/fs.h`](../../../../include/linux/fs.h)
66
77
use core::convert::{TryFrom, TryInto};
8-
use core::{marker, mem, ops::Deref, pin::Pin, ptr};
8+
use core::{marker, mem, ptr};
99

1010
use alloc::boxed::Box;
11-
use alloc::sync::Arc;
1211

1312
use crate::{
1413
bindings, c_types,
1514
error::{Error, KernelResult},
1615
file::File,
1716
io_buffer::{IoBufferReader, IoBufferWriter},
1817
iov_iter::IovIter,
19-
sync::{CondVar, Ref, RefCounted},
18+
sync::CondVar,
19+
types::PointerWrapper,
2020
user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter},
2121
};
2222

@@ -555,7 +555,7 @@ pub trait FileOperations: Send + Sync + Sized {
555555
const TO_USE: ToUse;
556556

557557
/// The pointer type that will be used to hold ourselves.
558-
type Wrapper: PointerWrapper<Self> = Box<Self>;
558+
type Wrapper: PointerWrapper = Box<Self>;
559559

560560
/// Cleans up after the last reference to the file goes away.
561561
///
@@ -633,64 +633,3 @@ pub trait FileOperations: Send + Sync + Sized {
633633
Ok(bindings::POLLIN | bindings::POLLOUT | bindings::POLLRDNORM | bindings::POLLWRNORM)
634634
}
635635
}
636-
637-
/// Used to convert an object into a raw pointer that represents it.
638-
///
639-
/// It can eventually be converted back into the object. This is used to store objects as pointers
640-
/// in kernel data structures, for example, an implementation of [`FileOperations`] in `struct
641-
/// file::private_data`.
642-
pub trait PointerWrapper<T> {
643-
/// Returns the raw pointer.
644-
fn into_pointer(self) -> *const T;
645-
646-
/// Returns the instance back from the raw pointer.
647-
///
648-
/// # Safety
649-
///
650-
/// The passed pointer must come from a previous call to [`PointerWrapper::into_pointer()`].
651-
unsafe fn from_pointer(ptr: *const T) -> Self;
652-
}
653-
654-
impl<T> PointerWrapper<T> for Box<T> {
655-
fn into_pointer(self) -> *const T {
656-
Box::into_raw(self)
657-
}
658-
659-
unsafe fn from_pointer(ptr: *const T) -> Self {
660-
Box::from_raw(ptr as _)
661-
}
662-
}
663-
664-
impl<T: RefCounted> PointerWrapper<T> for Ref<T> {
665-
fn into_pointer(self) -> *const T {
666-
Ref::into_raw(self)
667-
}
668-
669-
unsafe fn from_pointer(ptr: *const T) -> Self {
670-
Ref::from_raw(ptr as _)
671-
}
672-
}
673-
674-
impl<T> PointerWrapper<T> for Arc<T> {
675-
fn into_pointer(self) -> *const T {
676-
Arc::into_raw(self)
677-
}
678-
679-
unsafe fn from_pointer(ptr: *const T) -> Self {
680-
Arc::from_raw(ptr)
681-
}
682-
}
683-
684-
impl<T, W: PointerWrapper<T> + Deref> PointerWrapper<T> for Pin<W> {
685-
fn into_pointer(self) -> *const T {
686-
// SAFETY: We continue to treat the pointer as pinned by returning just a pointer to it to
687-
// the caller.
688-
let inner = unsafe { Pin::into_inner_unchecked(self) };
689-
inner.into_pointer()
690-
}
691-
692-
unsafe fn from_pointer(p: *const T) -> Self {
693-
// SAFETY: The object was originally pinned.
694-
Pin::new_unchecked(W::from_pointer(p))
695-
}
696-
}

rust/kernel/types.rs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
//!
55
//! C header: [`include/linux/types.h`](../../../../include/linux/types.h)
66
7-
use core::ops::Deref;
7+
use core::{ops::Deref, pin::Pin};
8+
9+
use alloc::{boxed::Box, sync::Arc};
810

911
use crate::bindings;
12+
use crate::c_types;
13+
use crate::sync::{Ref, RefCounted};
1014

1115
/// Permissions.
1216
///
@@ -71,3 +75,64 @@ macro_rules! cstr {
7175
unsafe { $crate::CStr::new_unchecked(s) }
7276
}};
7377
}
78+
79+
/// Used to convert an object into a raw pointer that represents it.
80+
///
81+
/// It can eventually be converted back into the object. This is used to store objects as pointers
82+
/// in kernel data structures, for example, an implementation of [`FileOperations`] in `struct
83+
/// file::private_data`.
84+
pub trait PointerWrapper {
85+
/// Returns the raw pointer.
86+
fn into_pointer(self) -> *const c_types::c_void;
87+
88+
/// Returns the instance back from the raw pointer.
89+
///
90+
/// # Safety
91+
///
92+
/// The passed pointer must come from a previous call to [`PointerWrapper::into_pointer()`].
93+
unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self;
94+
}
95+
96+
impl<T> PointerWrapper for Box<T> {
97+
fn into_pointer(self) -> *const c_types::c_void {
98+
Box::into_raw(self) as _
99+
}
100+
101+
unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self {
102+
Box::from_raw(ptr as _)
103+
}
104+
}
105+
106+
impl<T: RefCounted> PointerWrapper for Ref<T> {
107+
fn into_pointer(self) -> *const c_types::c_void {
108+
Ref::into_raw(self) as _
109+
}
110+
111+
unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self {
112+
Ref::from_raw(ptr as _)
113+
}
114+
}
115+
116+
impl<T> PointerWrapper for Arc<T> {
117+
fn into_pointer(self) -> *const c_types::c_void {
118+
Arc::into_raw(self) as _
119+
}
120+
121+
unsafe fn from_pointer(ptr: *const c_types::c_void) -> Self {
122+
Arc::from_raw(ptr as _)
123+
}
124+
}
125+
126+
impl<T: PointerWrapper + Deref> PointerWrapper for Pin<T> {
127+
fn into_pointer(self) -> *const c_types::c_void {
128+
// SAFETY: We continue to treat the pointer as pinned by returning just a pointer to it to
129+
// the caller.
130+
let inner = unsafe { Pin::into_inner_unchecked(self) };
131+
inner.into_pointer()
132+
}
133+
134+
unsafe fn from_pointer(p: *const c_types::c_void) -> Self {
135+
// SAFETY: The object was originally pinned.
136+
Pin::new_unchecked(T::from_pointer(p))
137+
}
138+
}

0 commit comments

Comments
 (0)