@@ -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 {
0 commit comments