Skip to content

Commit 55813d4

Browse files
committed
seq_file.rs: Borrow data from C pointer.
Instead of taking ownership of the data from the C side, borrow it using the new `PointerWrapper` interface. Signed-off-by: Adam Bratschi-Kaye <[email protected]>
1 parent 2fc05b5 commit 55813d4

File tree

3 files changed

+24
-21
lines changed

3 files changed

+24
-21
lines changed

rust/kernel/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub mod user_ptr;
8585
pub use build_error::build_error;
8686

8787
pub use crate::error::{Error, Result};
88-
pub use crate::types::{Mode, ScopeGuard};
88+
pub use crate::types::{Mode, ScopeGuard, UnsafeReference};
8989

9090
/// Page size defined in terms of the `PAGE_SHIFT` macro from C.
9191
///

rust/kernel/seq_file.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use core::{
1616
iter::{Iterator, Peekable},
1717
marker::PhantomData,
1818
mem,
19-
ops::{Deref, DerefMut},
19+
ops::DerefMut,
2020
ptr,
2121
};
2222

@@ -30,7 +30,7 @@ use crate::{bindings, c_str, c_types, str::CStr, types::PointerWrapper, Result};
3030
/// #![feature(allocator_api)]
3131
///
3232
/// use core::iter::Peekable;
33-
/// use kernel::{Error, Result, seq_file};
33+
/// use kernel::{Error, Result, seq_file, UnsafeReference};
3434
///
3535
/// struct Data(&'static [String]);
3636
///
@@ -40,8 +40,8 @@ use crate::{bindings, c_str, c_types, str::CStr, types::PointerWrapper, Result};
4040
/// type DataWrapper = Box<Self>;
4141
/// type IteratorWrapper = Box<Peekable<Self::Iterator>>;
4242
///
43-
/// fn start(&self) -> Result<Self::IteratorWrapper> {
44-
/// let iter = self.0.iter();
43+
/// fn start(data: UnsafeReference<Data>) -> Result<Self::IteratorWrapper> {
44+
/// let iter = data.0.iter();
4545
/// Box::try_new(iter.peekable()).map_err(|_| Error::ENOMEM)
4646
/// }
4747
///
@@ -56,17 +56,20 @@ pub trait SeqOperations {
5656
/// Type produced on each iteration.
5757
type Item;
5858

59-
/// Type created when the seq file is opened.
59+
/// Type created when the seq file is read and then iterated through to
60+
/// produce the file's contents.
6061
type Iterator: Iterator<Item = Self::Item>;
6162

62-
/// Wrapper used to store a pointer to `Self` on the C side.
63-
type DataWrapper: PointerWrapper + Deref<Target = Self>;
63+
/// Wrapper used to store a pointer to the data on the C side.
64+
type DataWrapper: PointerWrapper;
6465

6566
/// Wrapper used to store a pointer to the iterator on the C side.
6667
type IteratorWrapper: PointerWrapper + DerefMut<Target = Peekable<Self::Iterator>>;
6768

68-
/// Called once each time the `seq_file` is opened.
69-
fn start(&self) -> Result<Self::IteratorWrapper>;
69+
/// Called once each time the `seq_file` is read.
70+
fn start(
71+
data: <Self::DataWrapper as PointerWrapper>::Borrowed,
72+
) -> Result<Self::IteratorWrapper>;
7073

7174
/// How the item will be displayed to the reader.
7275
fn display(item: &Self::Item) -> &str;
@@ -153,15 +156,15 @@ extern "C" fn start_callback<T: SeqOperations>(
153156
m: *mut bindings::seq_file,
154157
pos: *mut bindings::loff_t,
155158
) -> *mut c_types::c_void {
156-
// SAFETY: This function will be called by opening a proc file generated
159+
// SAFETY: This function will be called by reading a proc file generated
157160
// from `proc_create_seq_private` on the C side with data created via
158-
// `T::DataWrapper::into_pointer`. We don't move the data in the wrapper
159-
// so the pointer will remain valid for later calls.
160-
let data_wrapper =
161-
unsafe { T::DataWrapper::from_pointer(bindings::PDE_DATA((*(*m).file).f_inode)) };
162-
let iterator = data_wrapper.start().ok();
163-
// Data is still used in the `proc_dir_entry`.
164-
mem::forget(data_wrapper);
161+
// `T::DataWrapper::into_pointer`. The data will not be destroyed until
162+
// the proc_dir_entry is destroyed and that operation will wait for all
163+
// readers to finish, so the data will be valid for the entire borrow. No
164+
// mutable borrows will be created because this is the only point at which
165+
// the data is accessed (other than when it is freed).
166+
let data = unsafe { T::DataWrapper::borrow(bindings::PDE_DATA((*(*m).file).f_inode)) };
167+
let iterator = T::start(data).ok();
165168
// SAFETY: The caller guarantees that `pos` points to a valid `loff_t`.
166169
let pos = unsafe { *pos };
167170
match iterator {

samples/rust/rust_seq_file.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use kernel::{
2626
miscdev, mutex_init,
2727
prelude::*,
2828
proc_fs, seq_file,
29-
sync::{Mutex, Ref},
29+
sync::{Mutex, Ref, RefBorrow},
3030
Error, Result,
3131
};
3232

@@ -63,12 +63,12 @@ impl seq_file::SeqOperations for State {
6363
&item[..]
6464
}
6565

66-
fn start(&self) -> Result<Self::IteratorWrapper> {
66+
fn start(state: RefBorrow<State>) -> Result<Self::IteratorWrapper> {
6767
const MAX_DIGITS: usize = 3;
6868
const MAX_LENGTH: usize = MAX_DIGITS + 1;
6969
const MAX_COUNT: u32 = 10u32.pow(MAX_DIGITS as u32) - 1;
7070

71-
let count = self.0.lock();
71+
let count = state.0.lock();
7272
let mut message = String::new();
7373

7474
let template = if *count <= MAX_COUNT {

0 commit comments

Comments
 (0)