Skip to content

Implement a #[vtable] macro #322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
rust: use #[vtable] for kernel::file::Operations
Signed-off-by: Gary Guo <gary@garyguo.net>
  • Loading branch information
nbdd0121 committed Jul 5, 2022
commit dbf1cf745b50f14f2fa7cc1431aa23392d52220f
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 @@ -19,6 +19,7 @@ use crate::{
};
use core::convert::{TryFrom, TryInto};
use core::{cell::UnsafeCell, marker, mem, ptr};
use macros::vtable;

/// Wraps the kernel's `struct file`.
///
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