Skip to content

Commit

Permalink
rust: use #[vtable] for kernel::file::Operations
Browse files Browse the repository at this point in the history
Signed-off-by: Gary Guo <[email protected]>
  • Loading branch information
nbdd0121 committed Jul 3, 2022
1 parent 5f7099e commit 19be350
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 92 deletions.
3 changes: 1 addition & 2 deletions drivers/android/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,12 +805,11 @@ impl IoctlHandler for Process {
}
}

#[vtable]
impl file::Operations for Process {
type Data = Ref<Self>;
type OpenData = Ref<Context>;

kernel::declare_file_operations!(ioctl, compat_ioctl, mmap, poll);

fn open(ctx: &Ref<Context>, file: &File) -> Result<Self::Data> {
Self::new(ctx.clone(), file.cred().into())
}
Expand Down
3 changes: 1 addition & 2 deletions drivers/char/hw_random/bcm2835_rng_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down
88 changes: 12 additions & 76 deletions rust/kernel/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -468,24 +469,24 @@ impl<A: OpenAdapter<T::OpenData>, T: Operations> OperationsVtable<A, T> {
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
Expand All @@ -496,7 +497,7 @@ impl<A: OpenAdapter<T::OpenData>, T: Operations> OperationsVtable<A, T> {
fasync: None,
flock: None,
flush: None,
fsync: if T::TO_USE.fsync {
fsync: if T::HAS_FSYNC {
Some(Self::fsync_callback)
} else {
None
Expand All @@ -506,19 +507,19 @@ impl<A: OpenAdapter<T::OpenData>, T: Operations> OperationsVtable<A, T> {
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
Expand All @@ -529,13 +530,13 @@ impl<A: OpenAdapter<T::OpenData>, T: Operations> OperationsVtable<A, T> {
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
Expand All @@ -552,69 +553,6 @@ impl<A: OpenAdapter<T::OpenData>, T: Operations> OperationsVtable<A, T> {
}
}

/// 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.
Expand Down Expand Up @@ -742,10 +680,8 @@ pub trait OpenAdapter<T: Sync> {
/// 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 = ();
Expand Down
5 changes: 2 additions & 3 deletions rust/kernel/miscdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,8 @@ impl<T: file::Operations<OpenData = ()>> crate::Module for Module<T> {
/// #[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 {
Expand Down
3 changes: 1 addition & 2 deletions samples/rust/rust_chrdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down
3 changes: 1 addition & 2 deletions samples/rust/rust_miscdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ impl SharedState {
}

struct Token;
#[vtable]
impl file::Operations for Token {
type Data = Ref<SharedState>;
type OpenData = Ref<SharedState>;

kernel::declare_file_operations!(read, write);

fn open(shared: &Ref<SharedState>, _file: &File) -> Result<Self::Data> {
Ok(shared.clone())
}
Expand Down
3 changes: 1 addition & 2 deletions samples/rust/rust_random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
Expand Down
5 changes: 2 additions & 3 deletions samples/rust/rust_semaphore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -61,12 +61,11 @@ impl FileState {
}
}

#[vtable]
impl file::Operations for FileState {
type Data = Box<Self>;
type OpenData = Ref<Semaphore>;

declare_file_operations!(read, write, ioctl);

fn open(shared: &Ref<Semaphore>, _file: &File) -> Result<Box<Self>> {
Ok(Box::try_new(Self {
read_count: AtomicU64::new(0),
Expand Down

0 comments on commit 19be350

Please sign in to comment.