rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Josef Zoller <josef@walterzollerpiano.com>
Cc: "Arnd Bergmann" <arnd@arndb.de>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org
Subject: Re: [PATCH 1/3] rust: char_dev: add character device abstraction
Date: Sat, 12 Oct 2024 09:36:52 +0200	[thread overview]
Message-ID: <2024101253-golf-detonator-592c@gregkh> (raw)
In-Reply-To: <20241011-rust-char-dev-v1-1-350225ae228b@walterzollerpiano.com>

On Fri, Oct 11, 2024 at 08:55:42PM +0200, Josef Zoller wrote:
> +unsigned int rust_helper_MAJOR(dev_t dev)
> +{
> +	return MAJOR(dev);
> +}

I don't think you use this function in the code anywhere.

> +unsigned int rust_helper_MINOR(dev_t dev)
> +{
> +	return MINOR(dev);
> +}

Is this really needed?  No driver should care about their minor number,
except to possibly set it, not read it.

> +dev_t rust_helper_MKDEV(unsigned int major, unsigned int minor)
> +{
> +	return MKDEV(major, minor);
> +}

If you are only doing dynamic creation, as your initial text said, I
don't think you need this either as the kernel should create it for you.


> diff --git a/rust/kernel/char_dev.rs b/rust/kernel/char_dev.rs
> new file mode 100644
> index 0000000000000000000000000000000000000000..b81c0d55ab60f18dc82a99991318a5ae0a26e560
> --- /dev/null
> +++ b/rust/kernel/char_dev.rs
> @@ -0,0 +1,976 @@
> +// SPDX-License-Identifier: GPL-2.0

Minor nit, you forgot a copyright line :)

> +
> +//! Character device support.
> +//!
> +//! C headers: [`include/linux/cdev.h`](srctree/include/linux/cdev.h) and
> +//! [`include/linux/fs.h`](srctree/include/linux/fs.h)
> +
> +use crate::{
> +    bindings, container_of,
> +    error::{to_result, VTABLE_DEFAULT_ERROR},
> +    fs::{File, LocalFile},
> +    ioctl::IoctlCommand,
> +    prelude::*,
> +    types::{ForeignOwnable, Opaque},
> +    uaccess::{UserPtr, UserSlice, UserSliceReader, UserSliceWriter},
> +};
> +use core::{ffi, mem, ops::Deref};
> +
> +/// Character device ID.
> +///
> +/// This is a wrapper around the kernel's `dev_t` type and identifies a
> +/// character device by its major and minor numbers.
> +#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
> +#[repr(transparent)]
> +pub struct CharDeviceID(bindings::dev_t); // u32
> +
> +impl CharDeviceID {
> +    /// Creates a new device ID from the given major and minor numbers.
> +    ///
> +    /// This corresponds to the kernel's `MKDEV` macro.
> +    pub fn new(major: u32, minor: u32) -> Self {
> +        // SAFETY: The kernel's `MKDEV` macro is safe to call with any values.
> +        Self(unsafe { bindings::MKDEV(major, minor) })
> +    }
> +
> +    /// Returns the major number of the device ID.
> +    ///
> +    /// This corresponds to the kernel's `MAJOR` macro.
> +    pub fn major(&self) -> u32 {
> +        // SAFETY: The kernel's `MAJOR` macro is safe to call with any value.
> +        unsafe { bindings::MAJOR(self.0) }
> +    }
> +
> +    /// Returns the minor number of the device ID.
> +    ///
> +    /// This corresponds to the kernel's `MINOR` macro.
> +    pub fn minor(&self) -> u32 {
> +        // SAFETY: The kernel's `MINOR` macro is safe to call with any value.
> +        unsafe { bindings::MINOR(self.0) }
> +    }
> +}
> +
> +/// Seek mode for the `llseek` method.
> +///
> +/// This enum corresponds to the `SEEK_*` constants in the kernel.
> +#[repr(u32)]
> +pub enum Whence {
> +    /// Set the file position to `offset`.
> +    Set = bindings::SEEK_SET,
> +    /// Set the file position to the current position plus `offset`.
> +    Cur = bindings::SEEK_CUR,
> +    /// Set the file position to the end of the file plus `offset`.
> +    End = bindings::SEEK_END,
> +    /// Set the file position to the next location in the file greater than or
> +    /// equal to `offset` containing data.
> +    Data = bindings::SEEK_DATA,
> +    /// Set the file position to the next hole in the file greater than or
> +    /// equal to `offset`.
> +    Hole = bindings::SEEK_HOLE,
> +}
> +
> +// Make sure at compile time that the `Whence` enum can be safely converted
> +// from integers up to `SEEK_MAX`.
> +const _: () = assert!(Whence::Hole as u32 == bindings::SEEK_MAX);
> +
> +/// Trait implemented by a registered character device.
> +///
> +/// A registered character device just handles the `open` operation on the
> +/// device file and returns an open device type (which implements the
> +/// [`OpenCharDevice`] trait) that handles the actual I/O operations on the
> +/// device file. Optionally, the `release` operation can be implemented to
> +/// handle the final close of the device file, but simple cleanup can also be
> +/// done in the `Drop` implementation of the open device type.

release is traditionally where you handle cleaning up what was allocated
for this "open", and then drop can handle any "global" state for the
device associated with this specific instance.  So "simple cleanup"
might not be possible in both places, as they are different parts of the
lifecycle of a device.

thanks,

greg k-h

  reply	other threads:[~2024-10-12  7:36 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-11 18:55 [PATCH 0/3] Character device abstractions for Rust Josef Zoller
2024-10-11 18:55 ` [PATCH 1/3] rust: char_dev: add character device abstraction Josef Zoller
2024-10-12  7:36   ` Greg Kroah-Hartman [this message]
2024-10-12 21:48     ` Josef Zoller
2024-10-17 11:38   ` kernel test robot
2024-10-11 18:55 ` [PATCH 2/3] rust: macros: add IoctlCommand derive macro Josef Zoller
2024-10-11 18:55 ` [PATCH 3/3] samples: rust: add character device sample Josef Zoller
2024-10-12 12:37   ` Greg Kroah-Hartman
2024-10-12 23:38     ` Josef Zoller
2024-10-12  7:29 ` [PATCH 0/3] Character device abstractions for Rust Greg Kroah-Hartman
2024-10-12 21:14   ` Josef Zoller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2024101253-golf-detonator-592c@gregkh \
    --to=gregkh@linuxfoundation.org \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=arnd@arndb.de \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=josef@walterzollerpiano.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).