diff --git a/drivers/android/process.rs b/drivers/android/process.rs index c41531896cb07f..cede106fd57a7e 100644 --- a/drivers/android/process.rs +++ b/drivers/android/process.rs @@ -805,12 +805,11 @@ impl IoctlHandler for Process { } } +#[vtable] impl file::Operations for Process { type Data = Ref; type OpenData = Ref; - kernel::declare_file_operations!(ioctl, compat_ioctl, mmap, poll); - fn open(ctx: &Ref, file: &File) -> Result { Self::new(ctx.clone(), file.cred().into()) } diff --git a/drivers/char/hw_random/bcm2835_rng_rust.rs b/drivers/char/hw_random/bcm2835_rng_rust.rs index 6d3cdc36a96aa0..f2dbd8606b3e7f 100644 --- a/drivers/char/hw_random/bcm2835_rng_rust.rs +++ b/drivers/char/hw_random/bcm2835_rng_rust.rs @@ -17,9 +17,8 @@ module_platform_driver! { struct RngDevice; +#[vtable] impl file::Operations for RngDevice { - kernel::declare_file_operations!(read); - fn open(_open_data: &(), _file: &File) -> Result { Ok(()) } diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index 8d5106dcc9dd00..aa52f1c9254e22 100644 --- a/rust/kernel/file.rs +++ b/rust/kernel/file.rs @@ -5,6 +5,7 @@ //! C headers: [`include/linux/fs.h`](../../../../include/linux/fs.h) and //! [`include/linux/file.h`](../../../../include/linux/file.h) +use crate::prelude::*; use crate::{ bindings, cred::Credential, @@ -468,24 +469,24 @@ impl, T: Operations> OperationsVtable { const VTABLE: bindings::file_operations = bindings::file_operations { open: Some(Self::open_callback), release: Some(Self::release_callback), - read: if T::TO_USE.read { + read: if T::HAS_READ { Some(Self::read_callback) } else { None }, - write: if T::TO_USE.write { + write: if T::HAS_WRITE { Some(Self::write_callback) } else { None }, - llseek: if T::TO_USE.seek { + llseek: if T::HAS_SEEK { Some(Self::llseek_callback) } else { None }, check_flags: None, - compat_ioctl: if T::TO_USE.compat_ioctl { + compat_ioctl: if T::HAS_COMPAT_IOCTL { Some(Self::compat_ioctl_callback) } else { None @@ -496,7 +497,7 @@ impl, T: Operations> OperationsVtable { fasync: None, flock: None, flush: None, - fsync: if T::TO_USE.fsync { + fsync: if T::HAS_FSYNC { Some(Self::fsync_callback) } else { None @@ -506,19 +507,19 @@ impl, T: Operations> OperationsVtable { iterate_shared: None, iopoll: None, lock: None, - mmap: if T::TO_USE.mmap { + mmap: if T::HAS_MMAP { Some(Self::mmap_callback) } else { None }, mmap_supported_flags: 0, owner: ptr::null_mut(), - poll: if T::TO_USE.poll { + poll: if T::HAS_POLL { Some(Self::poll_callback) } else { None }, - read_iter: if T::TO_USE.read_iter { + read_iter: if T::HAS_READ { Some(Self::read_iter_callback) } else { None @@ -529,13 +530,13 @@ impl, T: Operations> OperationsVtable { show_fdinfo: None, splice_read: None, splice_write: None, - unlocked_ioctl: if T::TO_USE.ioctl { + unlocked_ioctl: if T::HAS_IOCTL { Some(Self::unlocked_ioctl_callback) } else { None }, uring_cmd: None, - write_iter: if T::TO_USE.write_iter { + write_iter: if T::HAS_WRITE { Some(Self::write_iter_callback) } else { None @@ -552,69 +553,6 @@ impl, T: Operations> OperationsVtable { } } -/// Represents which fields of [`struct file_operations`] should be populated with pointers. -pub struct ToUse { - /// The `read` field of [`struct file_operations`]. - pub read: bool, - - /// The `read_iter` field of [`struct file_operations`]. - pub read_iter: bool, - - /// The `write` field of [`struct file_operations`]. - pub write: bool, - - /// The `write_iter` field of [`struct file_operations`]. - pub write_iter: bool, - - /// The `llseek` field of [`struct file_operations`]. - pub seek: bool, - - /// The `unlocked_ioctl` field of [`struct file_operations`]. - pub ioctl: bool, - - /// The `compat_ioctl` field of [`struct file_operations`]. - pub compat_ioctl: bool, - - /// The `fsync` field of [`struct file_operations`]. - pub fsync: bool, - - /// The `mmap` field of [`struct file_operations`]. - pub mmap: bool, - - /// The `poll` field of [`struct file_operations`]. - pub poll: bool, -} - -/// A constant version where all values are to set to `false`, that is, all supported fields will -/// be set to null pointers. -pub const USE_NONE: ToUse = ToUse { - read: false, - read_iter: false, - write: false, - write_iter: false, - seek: false, - ioctl: false, - compat_ioctl: false, - fsync: false, - mmap: false, - poll: false, -}; - -/// Defines the [`Operations::TO_USE`] field based on a list of fields to be populated. -#[macro_export] -macro_rules! declare_file_operations { - () => { - const TO_USE: $crate::file::ToUse = $crate::file::USE_NONE; - }; - ($($i:ident),+) => { - const TO_USE: kernel::file::ToUse = - $crate::file::ToUse { - $($i: true),+ , - ..$crate::file::USE_NONE - }; - }; -} - /// Allows the handling of ioctls defined with the `_IO`, `_IOR`, `_IOW`, and `_IOWR` macros. /// /// For each macro, there is a handler function that takes the appropriate types as arguments. @@ -742,10 +680,8 @@ pub trait OpenAdapter { /// File descriptors may be used from multiple threads/processes concurrently, so your type must be /// [`Sync`]. It must also be [`Send`] because [`Operations::release`] will be called from the /// thread that decrements that associated file's refcount to zero. +#[vtable] pub trait Operations { - /// The methods to use to populate [`struct file_operations`]. - const TO_USE: ToUse; - /// The type of the context data returned by [`Operations::open`] and made available to /// other methods. type Data: PointerWrapper + Send + Sync = (); diff --git a/rust/kernel/miscdev.rs b/rust/kernel/miscdev.rs index 8b1110b0143c9c..65b95d6dba906c 100644 --- a/rust/kernel/miscdev.rs +++ b/rust/kernel/miscdev.rs @@ -275,9 +275,8 @@ impl> crate::Module for Module { /// #[derive(Default)] /// struct MyFile; /// -/// impl kernel::file::Operations for MyFile { -/// kernel::declare_file_operations!(); -/// } +/// #[vtable] +/// impl kernel::file::Operations for MyFile {} /// ``` #[macro_export] macro_rules! module_misc_device { diff --git a/samples/rust/rust_chrdev.rs b/samples/rust/rust_chrdev.rs index 9f5d564671eaca..52f6e652d1a6c2 100644 --- a/samples/rust/rust_chrdev.rs +++ b/samples/rust/rust_chrdev.rs @@ -15,9 +15,8 @@ module! { struct RustFile; +#[vtable] impl file::Operations for RustFile { - kernel::declare_file_operations!(); - fn open(_shared: &(), _file: &file::File) -> Result { Ok(()) } diff --git a/samples/rust/rust_miscdev.rs b/samples/rust/rust_miscdev.rs index d1bf3c61f5cee8..647b77864f10ef 100644 --- a/samples/rust/rust_miscdev.rs +++ b/samples/rust/rust_miscdev.rs @@ -51,12 +51,11 @@ impl SharedState { } struct Token; +#[vtable] impl file::Operations for Token { type Data = Ref; type OpenData = Ref; - kernel::declare_file_operations!(read, write); - fn open(shared: &Ref, _file: &File) -> Result { Ok(shared.clone()) } diff --git a/samples/rust/rust_random.rs b/samples/rust/rust_random.rs index 8ec87119aa9bb8..341bf668dc6480 100644 --- a/samples/rust/rust_random.rs +++ b/samples/rust/rust_random.rs @@ -21,9 +21,8 @@ module_misc_device! { struct RandomFile; +#[vtable] impl file::Operations for RandomFile { - kernel::declare_file_operations!(read, write, read_iter, write_iter); - fn open(_data: &(), _file: &File) -> Result { Ok(()) } diff --git a/samples/rust/rust_semaphore.rs b/samples/rust/rust_semaphore.rs index 702ac1fcb48a8c..e91f82a6abfb42 100644 --- a/samples/rust/rust_semaphore.rs +++ b/samples/rust/rust_semaphore.rs @@ -15,7 +15,7 @@ use core::sync::atomic::{AtomicU64, Ordering}; use kernel::{ - condvar_init, declare_file_operations, + condvar_init, file::{self, File, IoctlCommand, IoctlHandler}, io_buffer::{IoBufferReader, IoBufferWriter}, miscdev::Registration, @@ -61,12 +61,11 @@ impl FileState { } } +#[vtable] impl file::Operations for FileState { type Data = Box; type OpenData = Ref; - declare_file_operations!(read, write, ioctl); - fn open(shared: &Ref, _file: &File) -> Result> { Ok(Box::try_new(Self { read_count: AtomicU64::new(0),