From: Danilo Krummrich <dakr@kernel.org>
To: gregkh@linuxfoundation.org, rafael@kernel.org, ojeda@kernel.org,
alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net,
bjorn3_gh@protonmail.com, lossin@kernel.org,
a.hindborg@kernel.org, aliceryhl@google.com, tmgross@umich.edu,
mmaurer@google.com
Cc: rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org, Danilo Krummrich <dakr@kernel.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>
Subject: [PATCH v3 01/10] rust: fs: add new type file::Offset
Date: Wed, 22 Oct 2025 16:30:35 +0200 [thread overview]
Message-ID: <20251022143158.64475-2-dakr@kernel.org> (raw)
In-Reply-To: <20251022143158.64475-1-dakr@kernel.org>
Add a new type for file offsets, i.e. bindings::loff_t. Trying to avoid
using raw bindings types, this seems to be the better alternative
compared to just using i64.
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
---
rust/kernel/fs/file.rs | 142 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 141 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs
index cf06e73a6da0..681b8a9e5d52 100644
--- a/rust/kernel/fs/file.rs
+++ b/rust/kernel/fs/file.rs
@@ -15,7 +15,147 @@
sync::aref::{ARef, AlwaysRefCounted},
types::{NotThreadSafe, Opaque},
};
-use core::ptr;
+use core::{num::TryFromIntError, ptr};
+
+/// Representation of an offset within a [`File`].
+///
+/// Transparent wrapper around `bindings::loff_t`.
+#[repr(transparent)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
+pub struct Offset(bindings::loff_t);
+
+impl Offset {
+ /// The largest value that can be represented by this type.
+ pub const MAX: Self = Self(bindings::loff_t::MAX);
+
+ /// The smallest value that can be represented by this type.
+ pub const MIN: Self = Self(bindings::loff_t::MIN);
+
+ /// Create a mutable [`Offset`] reference from the raw `*mut bindings::loff_t`.
+ ///
+ /// # Safety
+ ///
+ /// - `offset` must be a valid pointer to a `bindings::loff_t`.
+ /// - The caller must guarantee exclusive access to `offset`.
+ #[inline]
+ pub const unsafe fn from_raw<'a>(offset: *mut bindings::loff_t) -> &'a mut Self {
+ // SAFETY: By the safety requirements of this function
+ // - `offset` is a valid pointer to a `bindings::loff_t`,
+ // - we have exclusive access to `offset`.
+ unsafe { &mut *offset.cast() }
+ }
+
+ /// Returns `true` if the [`Offset`] is negative.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::fs::file::Offset;
+ ///
+ /// let offset = Offset::from(1);
+ /// assert!(!offset.is_negative());
+ ///
+ /// let offset = Offset::from(-1);
+ /// assert!(offset.is_negative());
+ /// ```
+ #[inline]
+ pub const fn is_negative(self) -> bool {
+ self.0.is_negative()
+ }
+
+ /// Saturating addition with another [`Offset`].
+ #[inline]
+ pub fn saturating_add(self, rhs: Offset) -> Offset {
+ Self(self.0.saturating_add(rhs.0))
+ }
+
+ /// Saturating addition with a [`usize`].
+ ///
+ /// If the [`usize`] fits in `bindings::loff_t` it is converted and added; otherwise the result
+ /// saturates to [`Offset::MAX`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::fs::file::Offset;
+ ///
+ /// let offset = Offset::from(40);
+ ///
+ /// let offset = offset.saturating_add_usize(2);
+ /// assert_eq!(offset, Offset::from(42));
+ ///
+ /// let offset = Offset::MAX.saturating_sub_usize(1);
+ /// let offset = offset.saturating_add_usize(usize::MAX);
+ /// assert_eq!(offset, Offset::MAX);
+ /// ```
+ pub fn saturating_add_usize(self, rhs: usize) -> Offset {
+ match bindings::loff_t::try_from(rhs) {
+ Ok(rhs_loff) => Self(self.0.saturating_add(rhs_loff)),
+ Err(_) => Self::MAX,
+ }
+ }
+
+ /// Saturating subtraction with another [`Offset`].
+ #[inline]
+ pub fn saturating_sub(self, rhs: Offset) -> Offset {
+ Offset(self.0.saturating_sub(rhs.0))
+ }
+
+ /// Saturating subtraction with a [`usize`].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::fs::file::Offset;
+ ///
+ /// let offset = Offset::from(100);
+ /// let offset = offset.saturating_sub_usize(58);
+ /// assert_eq!(offset, Offset::from(42));
+ ///
+ /// let offset = Offset::MIN.saturating_add_usize(1);
+ /// let offset = offset.saturating_sub_usize(usize::MAX);
+ /// assert_eq!(offset, Offset::MIN);
+ /// ```
+ #[inline]
+ pub fn saturating_sub_usize(self, rhs: usize) -> Offset {
+ match bindings::loff_t::try_from(rhs) {
+ Ok(rhs_loff) => Offset(self.0.saturating_sub(rhs_loff)),
+ Err(_) => Self::MIN,
+ }
+ }
+}
+
+impl From<bindings::loff_t> for Offset {
+ #[inline]
+ fn from(v: bindings::loff_t) -> Self {
+ Self(v)
+ }
+}
+
+impl From<Offset> for bindings::loff_t {
+ #[inline]
+ fn from(offset: Offset) -> Self {
+ offset.0
+ }
+}
+
+impl TryFrom<usize> for Offset {
+ type Error = TryFromIntError;
+
+ #[inline]
+ fn try_from(u: usize) -> Result<Self, Self::Error> {
+ Ok(Self(bindings::loff_t::try_from(u)?))
+ }
+}
+
+impl TryFrom<Offset> for usize {
+ type Error = TryFromIntError;
+
+ #[inline]
+ fn try_from(offset: Offset) -> Result<Self, Self::Error> {
+ usize::try_from(offset.0)
+ }
+}
/// Flags associated with a [`File`].
pub mod flags {
--
2.51.0
next prev parent reply other threads:[~2025-10-22 14:32 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-22 14:30 [PATCH v3 00/10] Binary Large Objects for Rust DebugFS Danilo Krummrich
2025-10-22 14:30 ` Danilo Krummrich [this message]
2025-10-22 14:42 ` [PATCH v3 01/10] rust: fs: add new type file::Offset Miguel Ojeda
2025-10-24 12:15 ` Alice Ryhl
2025-10-28 11:04 ` Danilo Krummrich
2025-11-01 14:16 ` Alexandre Courbot
2025-10-22 14:30 ` [PATCH v3 02/10] rust: uaccess: add UserSliceReader::read_slice_partial() Danilo Krummrich
2025-10-24 10:39 ` Alice Ryhl
2025-11-01 14:16 ` Alexandre Courbot
2025-10-22 14:30 ` [PATCH v3 03/10] rust: uaccess: add UserSliceReader::read_slice_file() Danilo Krummrich
2025-11-01 14:16 ` Alexandre Courbot
2025-10-22 14:30 ` [PATCH v3 04/10] rust: uaccess: add UserSliceWriter::write_slice_partial() Danilo Krummrich
2025-10-23 8:33 ` Alice Ryhl
2025-10-28 13:57 ` Miguel Ojeda
2025-11-01 14:19 ` Alexandre Courbot
2025-10-22 14:30 ` [PATCH v3 05/10] rust: uaccess: add UserSliceWriter::write_slice_file() Danilo Krummrich
2025-10-23 8:30 ` Alice Ryhl
2025-10-23 10:35 ` Danilo Krummrich
2025-10-23 10:37 ` Alice Ryhl
2025-10-23 11:03 ` Danilo Krummrich
2025-10-23 11:20 ` Alice Ryhl
2025-10-23 12:43 ` Danilo Krummrich
2025-10-24 10:37 ` Alice Ryhl
2025-10-24 18:02 ` Miguel Ojeda
2025-11-01 14:27 ` Alexandre Courbot
2025-11-01 15:06 ` Miguel Ojeda
2025-10-28 14:07 ` Miguel Ojeda
2025-10-22 14:30 ` [PATCH v3 06/10] rust: debugfs: support for binary large objects Danilo Krummrich
2025-10-23 8:26 ` Alice Ryhl
2025-10-23 10:09 ` Danilo Krummrich
2025-10-23 10:21 ` Alice Ryhl
2025-10-24 10:36 ` Alice Ryhl
2025-10-22 14:30 ` [PATCH v3 07/10] rust: debugfs: support blobs from smart pointers Danilo Krummrich
2025-10-23 8:24 ` Alice Ryhl
2025-10-22 14:30 ` [PATCH v3 08/10] samples: rust: debugfs: add example for blobs Danilo Krummrich
2025-10-22 14:30 ` [PATCH v3 09/10] rust: debugfs: support binary large objects for ScopedDir Danilo Krummrich
2025-10-23 8:23 ` Alice Ryhl
2025-10-22 14:30 ` [PATCH v3 10/10] samples: rust: debugfs_scoped: add example for blobs Danilo Krummrich
2025-10-28 13:47 ` [PATCH v3 00/10] Binary Large Objects for Rust DebugFS Miguel Ojeda
2025-11-05 0:25 ` Danilo Krummrich
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=20251022143158.64475-2-dakr@kernel.org \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=brauner@kernel.org \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=mmaurer@google.com \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=viro@zeniv.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.