@@ -95,12 +95,17 @@ unsafe extern "C" fn open_callback<A: FileOpenAdapter, T: FileOpener<A::Arg>>(
9595 // should point to data in the inode or file that lives longer
9696 // than the following use of `T::open`.
9797 let arg = unsafe { A :: convert( inode, file) } ;
98+ // SAFETY: The C contract guarantees that `file` is valid. Additionally,
99+ // `fileref` never outlives this function, so it is guaranteed to be
100+ // valid.
101+ let fileref = unsafe { FileRef :: from_ptr( file) } ;
98102 // SAFETY: `arg` was previously returned by `A::convert` and must
99103 // be a valid non-null pointer.
100- let ptr = T :: open( unsafe { & * arg } ) ?. into_pointer( ) ;
101- // SAFETY: `ptr` was previously returned by `T::open`. The returned
102- // value should be a boxed value and should live the length of the
103- // given file.
104+ let ptr = T :: open( unsafe { & * arg } , & fileref) ?. into_pointer( ) ;
105+ // SAFETY: The C contract guarantees that `private_data` is available
106+ // for implementers of the file operations (no other C code accesses
107+ // it), so we know that there are no concurrent threads/CPUs accessing
108+ // it (it's not visible to any other Rust code).
104109 unsafe { ( * file) . private_data = ptr as * mut c_types:: c_void } ;
105110 Ok ( 0 )
106111 }
@@ -591,11 +596,11 @@ pub trait FileOpener<T: ?Sized>: FileOperations {
591596 /// Creates a new instance of this file.
592597 ///
593598 /// Corresponds to the `open` function pointer in `struct file_operations`.
594- fn open ( context : & T ) -> Result < Self :: Wrapper > ;
599+ fn open ( context : & T , file : & File ) -> Result < Self :: Wrapper > ;
595600}
596601
597602impl < T : FileOperations < Wrapper = Box < T > > + Default > FileOpener < ( ) > for T {
598- fn open ( _: & ( ) ) -> Result < Self :: Wrapper > {
603+ fn open ( _: & ( ) , _file : & File ) -> Result < Self :: Wrapper > {
599604 Ok ( Box :: try_new ( T :: default ( ) ) ?)
600605 }
601606}
0 commit comments