From: Wedson Almeida Filho <wedsonaf@gmail.com>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>,
Matthew Wilcox <willy@infradead.org>,
Dave Chinner <david@fromorbit.com>
Cc: Kent Overstreet <kent.overstreet@gmail.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-fsdevel@vger.kernel.org, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org,
Wedson Almeida Filho <walmeida@microsoft.com>
Subject: [RFC PATCH v2 12/30] rust: fs: introduce `file::Operations::seek`
Date: Tue, 14 May 2024 10:16:53 -0300 [thread overview]
Message-ID: <20240514131711.379322-13-wedsonaf@gmail.com> (raw)
In-Reply-To: <20240514131711.379322-1-wedsonaf@gmail.com>
From: Wedson Almeida Filho <walmeida@microsoft.com>
This allows file systems to customise their behaviour when callers want
to seek to a different file location, which may also be used when
reading directory entries.
Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
---
rust/kernel/fs/file.rs | 73 ++++++++++++++++++++++++++++++++++++++-
samples/rust/rust_rofs.rs | 6 +++-
2 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs
index 6d61723f440d..77eb6d230568 100644
--- a/rust/kernel/fs/file.rs
+++ b/rust/kernel/fs/file.rs
@@ -270,12 +270,65 @@ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
}
}
+/// Indicates how to interpret the `offset` argument in [`Operations::seek`].
+#[repr(u32)]
+pub enum Whence {
+ /// `offset` bytes from the start of the file.
+ Set = bindings::SEEK_SET,
+
+ /// `offset` bytes from the end of the file.
+ End = bindings::SEEK_END,
+
+ /// `offset` bytes from the current location.
+ Cur = bindings::SEEK_CUR,
+
+ /// The next location greater than or equal to `offset` that contains data.
+ Data = bindings::SEEK_DATA,
+
+ /// The next location greater than or equal to `offset` that contains a hole.
+ Hole = bindings::SEEK_HOLE,
+}
+
+impl TryFrom<i32> for Whence {
+ type Error = crate::error::Error;
+
+ fn try_from(v: i32) -> Result<Self> {
+ match v {
+ v if v == Self::Set as i32 => Ok(Self::Set),
+ v if v == Self::End as i32 => Ok(Self::End),
+ v if v == Self::Cur as i32 => Ok(Self::Cur),
+ v if v == Self::Data as i32 => Ok(Self::Data),
+ v if v == Self::Hole as i32 => Ok(Self::Hole),
+ _ => Err(EDOM),
+ }
+ }
+}
+
+/// Generic implementation of [`Operations::seek`].
+pub fn generic_seek(
+ file: &File<impl FileSystem + ?Sized>,
+ offset: Offset,
+ whence: Whence,
+) -> Result<Offset> {
+ let n = unsafe { bindings::generic_file_llseek(file.0.get(), offset, whence as i32) };
+ if n < 0 {
+ Err(Error::from_errno(n.try_into()?))
+ } else {
+ Ok(n)
+ }
+}
+
/// Operations implemented by files.
#[vtable]
pub trait Operations {
/// File system that these operations are compatible with.
type FileSystem: FileSystem + ?Sized;
+ /// Seeks the file to the given offset.
+ fn seek(_file: &File<Self::FileSystem>, _offset: Offset, _whence: Whence) -> Result<Offset> {
+ Err(EINVAL)
+ }
+
/// Reads directory entries from directory files.
///
/// [`DirEmitter::pos`] holds the current position of the directory reader.
@@ -298,7 +351,11 @@ pub const fn new<U: Operations<FileSystem = T> + ?Sized>() -> Self {
impl<T: Operations + ?Sized> Table<T> {
const TABLE: bindings::file_operations = bindings::file_operations {
owner: ptr::null_mut(),
- llseek: None,
+ llseek: if T::HAS_SEEK {
+ Some(Self::seek_callback)
+ } else {
+ None
+ },
read: None,
write: None,
read_iter: None,
@@ -336,6 +393,20 @@ impl<T: Operations + ?Sized> Table<T> {
uring_cmd_iopoll: None,
};
+ unsafe extern "C" fn seek_callback(
+ file_ptr: *mut bindings::file,
+ offset: bindings::loff_t,
+ whence: i32,
+ ) -> bindings::loff_t {
+ from_result(|| {
+ // SAFETY: The C API guarantees that `file` is valid for the duration of the
+ // callback. Since this callback is specifically for filesystem T, we know `T`
+ // is the right filesystem.
+ let file = unsafe { File::from_raw(file_ptr) };
+ T::seek(file, offset, whence.try_into()?)
+ })
+ }
+
unsafe extern "C" fn read_dir_callback(
file_ptr: *mut bindings::file,
ctx_ptr: *mut bindings::dir_context,
diff --git a/samples/rust/rust_rofs.rs b/samples/rust/rust_rofs.rs
index 9da01346d8f8..abec084360da 100644
--- a/samples/rust/rust_rofs.rs
+++ b/samples/rust/rust_rofs.rs
@@ -2,7 +2,7 @@
//! Rust read-only file system sample.
-use kernel::fs::{dentry, file, file::File, inode, inode::INode, sb::SuperBlock};
+use kernel::fs::{dentry, file, file::File, inode, inode::INode, sb::SuperBlock, Offset};
use kernel::prelude::*;
use kernel::{c_str, fs, time::UNIX_EPOCH, types::Either, types::Locked};
@@ -76,6 +76,10 @@ fn init_root(sb: &SuperBlock<Self>) -> Result<dentry::Root<Self>> {
impl file::Operations for RoFs {
type FileSystem = Self;
+ fn seek(file: &File<Self>, offset: Offset, whence: file::Whence) -> Result<Offset> {
+ file::generic_seek(file, offset, whence)
+ }
+
fn read_dir(
_file: &File<Self>,
inode: &Locked<&INode<Self>, inode::ReadSem>,
--
2.34.1
next prev parent reply other threads:[~2024-05-14 13:17 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-14 13:16 [RFC PATCH v2 00/30] Rust abstractions for VFS Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 01/30] rust: fs: add registration/unregistration of file systems Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 02/30] rust: fs: introduce the `module_fs` macro Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 03/30] samples: rust: add initial ro file system sample Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 04/30] rust: fs: introduce `FileSystem::fill_super` Wedson Almeida Filho
2024-05-20 19:38 ` Darrick J. Wong
2024-05-14 13:16 ` [RFC PATCH v2 05/30] rust: fs: introduce `INode<T>` Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 06/30] rust: fs: introduce `DEntry<T>` Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 07/30] rust: fs: introduce `FileSystem::init_root` Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 08/30] rust: file: move `kernel::file` to `kernel::fs::file` Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 09/30] rust: fs: generalise `File` for different file systems Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 10/30] rust: fs: add empty file operations Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 11/30] rust: fs: introduce `file::Operations::read_dir` Wedson Almeida Filho
2024-05-14 13:16 ` Wedson Almeida Filho [this message]
2024-05-14 13:16 ` [RFC PATCH v2 13/30] rust: fs: introduce `file::Operations::read` Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 14/30] rust: fs: add empty inode operations Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 15/30] rust: fs: introduce `inode::Operations::lookup` Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 16/30] rust: folio: introduce basic support for folios Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 17/30] rust: fs: add empty address space operations Wedson Almeida Filho
2024-05-14 13:16 ` [RFC PATCH v2 18/30] rust: fs: introduce `address_space::Operations::read_folio` Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 19/30] rust: fs: introduce `FileSystem::read_xattr` Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 20/30] rust: fs: introduce `FileSystem::statfs` Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 21/30] rust: fs: introduce more inode types Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 22/30] rust: fs: add per-superblock data Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 23/30] rust: fs: allow file systems backed by a block device Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 24/30] rust: fs: allow per-inode data Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 25/30] rust: fs: export file type from mode constants Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 26/30] rust: fs: allow populating i_lnk Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 27/30] rust: fs: add `iomap` module Wedson Almeida Filho
2024-05-20 19:32 ` Darrick J. Wong
2024-05-14 13:17 ` [RFC PATCH v2 28/30] rust: fs: add memalloc_nofs support Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 29/30] tarfs: introduce tar fs Wedson Almeida Filho
2024-05-14 13:17 ` [RFC PATCH v2 30/30] WIP: fs: ext2: add rust ro ext2 implementation Wedson Almeida Filho
2024-05-20 20:01 ` Darrick J. Wong
2024-05-31 14:34 ` [RFC PATCH v2 00/30] Rust abstractions for VFS 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=20240514131711.379322-13-wedsonaf@gmail.com \
--to=wedsonaf@gmail.com \
--cc=brauner@kernel.org \
--cc=david@fromorbit.com \
--cc=gregkh@linuxfoundation.org \
--cc=kent.overstreet@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=walmeida@microsoft.com \
--cc=willy@infradead.org \
/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.