Skip to content

Commit

Permalink
Merge branch 'rust' into macros
Browse files Browse the repository at this point in the history
  • Loading branch information
wedsonaf authored Jul 5, 2022
2 parents 36bb99a + b3e8654 commit d2b8246
Show file tree
Hide file tree
Showing 15 changed files with 394 additions and 25 deletions.
6 changes: 6 additions & 0 deletions rust/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,12 @@ void rust_helper___INIT_WORK_WITH_KEY(struct work_struct *work,
}
EXPORT_SYMBOL_GPL(rust_helper___INIT_WORK_WITH_KEY);

struct dentry *rust_helper_dget(struct dentry *dentry)
{
return dget(dentry);
}
EXPORT_SYMBOL_GPL(rust_helper_dget);

/*
* We use `bindgen`'s `--size_t-is-usize` option to bind the C `size_t` type
* as the Rust `usize` type, so we can use it in contexts where Rust
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/amba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl<T: Driver> driver::DriverOps for Adapter<T> {
}
// SAFETY: By the safety requirements of this function, `reg` is valid and fully
// initialised.
to_result(|| unsafe { bindings::amba_driver_register(reg) })
to_result(unsafe { bindings::amba_driver_register(reg) })
}

unsafe fn unregister(reg: *mut bindings::amba_driver) {
Expand Down
2 changes: 1 addition & 1 deletion rust/kernel/clk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl Clk {
/// This function should not be called in atomic context.
pub fn prepare_enable(self) -> Result<EnabledClk> {
// SAFETY: The pointer is valid by the type invariant.
to_result(|| unsafe { bindings::clk_prepare_enable(self.0) })?;
to_result(unsafe { bindings::clk_prepare_enable(self.0) })?;
Ok(EnabledClk(self))
}
}
Expand Down
7 changes: 3 additions & 4 deletions rust/kernel/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,10 +551,9 @@ pub(crate) fn from_kernel_err_ptr<T>(ptr: *mut T) -> Result<*mut T> {
Ok(ptr)
}

/// Calls a kernel function that returns an integer error code on failure and converts the result
/// to a [`Result`].
pub fn to_result(func: impl FnOnce() -> core::ffi::c_int) -> Result {
let err = func();
/// Converts an integer as returned by a C kernel function to an error if it's negative, and
/// `Ok(())` otherwise.
pub fn to_result(err: core::ffi::c_int) -> Result {
if err < 0 {
Err(Error::from_kernel_errno(err))
} else {
Expand Down
52 changes: 52 additions & 0 deletions rust/kernel/fs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0

//! File systems.
//!
//! C headers: [`include/linux/fs.h`](../../../../include/linux/fs.h)
use crate::{bindings, AlwaysRefCounted};
use core::{cell::UnsafeCell, ptr};

/// Wraps the kernel's `struct inode`.
///
/// # Invariants
///
/// Instances of this type are always ref-counted, that is, a call to `ihold` ensures that the
/// allocation remains valid at least until the matching call to `iput`.
#[repr(transparent)]
pub struct INode(pub(crate) UnsafeCell<bindings::inode>);

// SAFETY: The type invariants guarantee that `INode` is always ref-counted.
unsafe impl AlwaysRefCounted for INode {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
unsafe { bindings::ihold(self.0.get()) };
}

unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
// SAFETY: The safety requirements guarantee that the refcount is nonzero.
unsafe { bindings::iput(obj.cast().as_ptr()) }
}
}

/// Wraps the kernel's `struct dentry`.
///
/// # Invariants
///
/// Instances of this type are always ref-counted, that is, a call to `dget` ensures that the
/// allocation remains valid at least until the matching call to `dput`.
#[repr(transparent)]
pub struct DEntry(pub(crate) UnsafeCell<bindings::dentry>);

// SAFETY: The type invariants guarantee that `DEntry` is always ref-counted.
unsafe impl AlwaysRefCounted for DEntry {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
unsafe { bindings::dget(self.0.get()) };
}

unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
// SAFETY: The safety requirements guarantee that the refcount is nonzero.
unsafe { bindings::dput(obj.cast().as_ptr()) }
}
}
2 changes: 1 addition & 1 deletion rust/kernel/hwrng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl<T: Operations> Registration<T> {
);

// SAFETY: `bindings::hwrng` is initialized above which guarantees safety.
to_result(|| unsafe { bindings::hwrng_register(this.hwrng.get()) })?;
to_result(unsafe { bindings::hwrng_register(this.hwrng.get()) })?;

this.registered = true;
this.name = Some(name);
Expand Down
Loading

0 comments on commit d2b8246

Please sign in to comment.