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 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).