Rust-for-linux archive mirror
 help / color / mirror / Atom feed
From: Ariel Miculas <amiculas@cisco.com>
To: rust-for-linux@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk,
	ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com,
	shallyn@cisco.com, Ariel Miculas <amiculas@cisco.com>
Subject: [RFC PATCH v3 10/22] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount
Date: Thu, 16 May 2024 22:03:33 +0300	[thread overview]
Message-ID: <20240516190345.957477-11-amiculas@cisco.com> (raw)
In-Reply-To: <20240516190345.957477-1-amiculas@cisco.com>

Provide an abstraction over vfsmount so that we can create a new private
mount from Rust code.

PuzzleFS needs a private mount of the PuzzleFS image, so it can access
the chunks from the data store independent of the future changes to the
mount namespace.

Signed-off-by: Ariel Miculas <amiculas@cisco.com>
---
 rust/bindings/bindings_helper.h |  1 +
 rust/kernel/lib.rs              |  1 +
 rust/kernel/mount.rs            | 73 +++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+)
 create mode 100644 rust/kernel/mount.rs

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 629fce394dbe..2d87bb9f87c9 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -16,6 +16,7 @@
 #include <linux/iomap.h>
 #include <linux/jiffies.h>
 #include <linux/mdio.h>
+#include <linux/namei.h>
 #include <linux/pagemap.h>
 #include <linux/phy.h>
 #include <linux/refcount.h>
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 445599d4bff6..7f0d89b902ce 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -37,6 +37,7 @@
 #[cfg(CONFIG_KUNIT)]
 pub mod kunit;
 pub mod mem_cache;
+pub mod mount;
 #[cfg(CONFIG_NET)]
 pub mod net;
 pub mod prelude;
diff --git a/rust/kernel/mount.rs b/rust/kernel/mount.rs
new file mode 100644
index 000000000000..50cfe7f7437a
--- /dev/null
+++ b/rust/kernel/mount.rs
@@ -0,0 +1,73 @@
+//! Mount interface
+//!
+//! C headers: [`include/linux/mount.h`](../../../../include/linux/mount.h)
+
+use kernel::bindings;
+use kernel::error::from_err_ptr;
+use kernel::pr_err;
+use kernel::prelude::*;
+use kernel::str::CStr;
+use kernel::types::Opaque;
+
+/// Wraps the kernel's `struct path`.
+#[repr(transparent)]
+pub struct Path(pub(crate) Opaque<bindings::path>);
+
+/// Wraps the kernel's `struct vfsmount`.
+#[repr(transparent)]
+#[derive(Debug)]
+pub struct Vfsmount {
+    vfsmount: *mut bindings::vfsmount,
+}
+
+// SAFETY: No one besides us has the raw pointer, so we can safely transfer Vfsmount to another thread
+unsafe impl Send for Vfsmount {}
+// SAFETY: It's OK to access `Vfsmount` through references from other threads because we're not
+// accessing any properties from the underlying raw pointer
+unsafe impl Sync for Vfsmount {}
+
+impl Vfsmount {
+    /// Create a new private mount clone based on a path name
+    pub fn new_private_mount(path_name: &CStr) -> Result<Self> {
+        let path: Path = Path(Opaque::uninit());
+        // SAFETY: path_name is a &CStr, so it's a valid string pointer; path is an uninitialized
+        // struct stored on the stack and it's ok because kern_path expects an out parameter
+        let err = unsafe {
+            bindings::kern_path(
+                path_name.as_ptr().cast::<i8>(),
+                bindings::LOOKUP_FOLLOW | bindings::LOOKUP_DIRECTORY,
+                path.0.get(),
+            )
+        };
+        if err != 0 {
+            pr_err!("failed to resolve '{}': {}\n", path_name, err);
+            return Err(EINVAL);
+        }
+
+        // SAFETY: path is a struct stored on the stack and it is  initialized because the call to
+        // kern_path succeeded
+        let vfsmount = unsafe { from_err_ptr(bindings::clone_private_mount(path.0.get()))? };
+
+        // Don't inherit atime flags
+        // CAST: these flags fit into i32
+        let skip_flags =
+            !(bindings::MNT_NOATIME | bindings::MNT_NODIRATIME | bindings::MNT_RELATIME) as i32;
+        // SAFETY: we called from_err_ptr so it's safe to dereference this pointer
+        unsafe {
+            (*vfsmount).mnt_flags &= skip_flags;
+        }
+        Ok(Self { vfsmount })
+    }
+
+    /// Returns a raw pointer to vfsmount
+    pub fn get(&self) -> *mut bindings::vfsmount {
+        self.vfsmount
+    }
+}
+
+impl Drop for Vfsmount {
+    fn drop(&mut self) {
+        // SAFETY new_private_mount makes sure to return a valid pointer
+        unsafe { bindings::kern_unmount(self.vfsmount) };
+    }
+}
-- 
2.34.1


  parent reply	other threads:[~2024-05-16 19:05 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-16 19:03 [RFC PATCH v3 00/22] Rust PuzzleFS filesystem driver Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 01/22] kernel: configs: add qemu-busybox-min.config Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 02/22] rust: hex: import crate Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 03/22] rust: hex: add SPDX license identifiers Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 04/22] rust: Kbuild: enable `hex` Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 05/22] rust: hex: add encode_hex_iter and encode_hex_upper_iter methods Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 06/22] rust: capnp: import crate Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 07/22] rust: capnp: add SPDX License Identifiers Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 08/22] rust: capnp: return an error when trying to display floating point values Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 09/22] rust: Kbuild: enable `capnp` Ariel Miculas
2024-05-16 19:03 ` Ariel Miculas [this message]
2024-05-16 19:03 ` [RFC PATCH v3 11/22] rust: file: add bindings for `struct file` Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 12/22] rust: file: Add support for reading files using their path Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 13/22] fs: puzzlefs: Implement the initial version of PuzzleFS Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 14/22] rust: kernel: add from_iter_fallible for Vec<T> Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 15/22] kernel: configs: add puzzlefs config fragment Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 16/22] scripts: add fs directory to rust-analyzer Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 17/22] fs: puzzlefs: add extended attributes support Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 18/22] rust: add improved version of `ForeignOwnable::borrow_mut` Ariel Miculas
2024-05-17  8:37   ` Alice Ryhl
2024-05-16 19:03 ` [RFC PATCH v3 19/22] Add borrow_mut implementation to a ForeignOwnable CString Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 20/22] rust: add support for file system parameters Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 21/22] fs: puzzlefs: add oci_root_dir and image_manifest mount parameters Ariel Miculas
2024-05-16 19:03 ` [RFC PATCH v3 22/22] fs: puzzlefs: implement statfs for puzzlefs Ariel Miculas

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=20240516190345.957477-11-amiculas@cisco.com \
    --to=amiculas@cisco.com \
    --cc=alex.gaynor@gmail.com \
    --cc=brauner@kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=shallyn@cisco.com \
    --cc=tycho@tycho.pizza \
    --cc=viro@zeniv.linux.org.uk \
    --cc=wedsonaf@gmail.com \
    /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 read-only IMAP folder(s) and NNTP newsgroup(s).