From 29a96d12e25a8638b7dac3cb5afb7483c22f8a1e Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Mon, 29 Nov 2021 13:56:28 +0000 Subject: [PATCH] rust: add `&File` argument to `open` callback. This is for cases when drivers need to get information from `File` during `open`, for example, the credentials. Such a need occurs is Binder. Signed-off-by: Wedson Almeida Filho --- drivers/android/process.rs | 2 +- drivers/char/hw_random/bcm2835_rng_rust.rs | 18 +++--------------- rust/kernel/file_operations.rs | 17 +++++++++++------ samples/rust/rust_miscdev.rs | 2 +- samples/rust/rust_semaphore.rs | 2 +- 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/drivers/android/process.rs b/drivers/android/process.rs index e6320adf4fc4c7..274e44375daf49 100644 --- a/drivers/android/process.rs +++ b/drivers/android/process.rs @@ -802,7 +802,7 @@ impl IoctlHandler for Process { } impl FileOpener> for Process { - fn open(ctx: &Ref) -> Result { + fn open(ctx: &Ref, _file: &File) -> Result { Self::new(ctx.clone()) } } diff --git a/drivers/char/hw_random/bcm2835_rng_rust.rs b/drivers/char/hw_random/bcm2835_rng_rust.rs index 6c7445f2036e44..3e8da4cd04e267 100644 --- a/drivers/char/hw_random/bcm2835_rng_rust.rs +++ b/drivers/char/hw_random/bcm2835_rng_rust.rs @@ -6,15 +6,8 @@ #![feature(allocator_api, global_asm)] use kernel::{ - file::File, - file_operations::{FileOpener, FileOperations}, - io_buffer::IoBufferWriter, - miscdev, - of::ConstOfMatchTable, - platdev::PlatformDriver, - prelude::*, - str::CStr, - ThisModule, {c_str, platdev}, + c_str, file::File, file_operations::FileOperations, io_buffer::IoBufferWriter, miscdev, + of::ConstOfMatchTable, platdev, platdev::PlatformDriver, prelude::*, }; module! { @@ -25,14 +18,9 @@ module! { license: b"GPL v2", } +#[derive(Default)] struct RngDevice; -impl FileOpener<()> for RngDevice { - fn open(_state: &()) -> Result { - Ok(Box::try_new(RngDevice)?) - } -} - impl FileOperations for RngDevice { kernel::declare_file_operations!(read); diff --git a/rust/kernel/file_operations.rs b/rust/kernel/file_operations.rs index a0ae134964ad24..3d96a32a3764b1 100644 --- a/rust/kernel/file_operations.rs +++ b/rust/kernel/file_operations.rs @@ -95,12 +95,17 @@ unsafe extern "C" fn open_callback>( // should point to data in the inode or file that lives longer // than the following use of `T::open`. let arg = unsafe { A::convert(inode, file) }; + // SAFETY: The C contract guarantees that `file` is valid. Additionally, + // `fileref` never outlives this function, so it is guaranteed to be + // valid. + let fileref = unsafe { FileRef::from_ptr(file) }; // SAFETY: `arg` was previously returned by `A::convert` and must // be a valid non-null pointer. - let ptr = T::open(unsafe { &*arg })?.into_pointer(); - // SAFETY: `ptr` was previously returned by `T::open`. The returned - // value should be a boxed value and should live the length of the - // given file. + let ptr = T::open(unsafe { &*arg }, &fileref)?.into_pointer(); + // SAFETY: The C contract guarantees that `private_data` is available + // for implementers of the file operations (no other C code accesses + // it), so we know that there are no concurrent threads/CPUs accessing + // it (it's not visible to any other Rust code). unsafe { (*file).private_data = ptr as *mut c_types::c_void }; Ok(0) } @@ -591,11 +596,11 @@ pub trait FileOpener: FileOperations { /// Creates a new instance of this file. /// /// Corresponds to the `open` function pointer in `struct file_operations`. - fn open(context: &T) -> Result; + fn open(context: &T, file: &File) -> Result; } impl> + Default> FileOpener<()> for T { - fn open(_: &()) -> Result { + fn open(_: &(), _file: &File) -> Result { Ok(Box::try_new(T::default())?) } } diff --git a/samples/rust/rust_miscdev.rs b/samples/rust/rust_miscdev.rs index 7172a3d749adb8..65dd400275243d 100644 --- a/samples/rust/rust_miscdev.rs +++ b/samples/rust/rust_miscdev.rs @@ -57,7 +57,7 @@ impl SharedState { struct Token; impl FileOpener> for Token { - fn open(shared: &Ref) -> Result { + fn open(shared: &Ref, _file: &File) -> Result { Ok(shared.clone()) } } diff --git a/samples/rust/rust_semaphore.rs b/samples/rust/rust_semaphore.rs index 3da4c24008a277..28f7a34d2942ed 100644 --- a/samples/rust/rust_semaphore.rs +++ b/samples/rust/rust_semaphore.rs @@ -66,7 +66,7 @@ impl FileState { } impl FileOpener> for FileState { - fn open(shared: &Ref) -> Result> { + fn open(shared: &Ref, _file: &File) -> Result> { Ok(Box::try_new(Self { read_count: AtomicU64::new(0), shared: shared.clone(),