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,
Ariel Miculas <amiculas@cisco.com>
Subject: [RFC PATCH v2 03/10] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount
Date: Wed, 26 Jul 2023 19:45:27 +0300 [thread overview]
Message-ID: <20230726164535.230515-4-amiculas@cisco.com> (raw)
In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com>
Signed-off-by: Ariel Miculas <amiculas@cisco.com>
---
rust/bindings/bindings_helper.h | 1 +
rust/kernel/lib.rs | 1 +
rust/kernel/mount.rs | 71 +++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
create mode 100644 rust/kernel/mount.rs
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index e5fc3b1d408d..205ef50dfd4c 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -18,6 +18,7 @@
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <linux/delay.h>
+#include <linux/namei.h>
/* `bindgen` gets confused at certain things. */
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 08f67833afcf..7dc07bdb5d55 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -46,6 +46,7 @@
pub mod ioctl;
pub mod iov_iter;
pub mod mm;
+pub mod mount;
pub mod pages;
pub mod prelude;
pub mod print;
diff --git a/rust/kernel/mount.rs b/rust/kernel/mount.rs
new file mode 100644
index 000000000000..d08830b27571
--- /dev/null
+++ b/rust/kernel/mount.rs
@@ -0,0 +1,71 @@
+//! 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() as *const 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
+ // SAFETY: we called from_err_ptr so it's safe to dereference this pointer
+ unsafe {
+ (*vfsmount).mnt_flags &=
+ !(bindings::MNT_NOATIME | bindings::MNT_NODIRATIME | bindings::MNT_RELATIME) as i32;
+ }
+ 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.41.0
next prev parent reply other threads:[~2023-07-26 16:48 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-26 16:45 [RFC PATCH v2 00/10] Rust PuzleFS filesystem driver Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 01/10] samples: puzzlefs: add initial puzzlefs sample, copied from rust_fs.rs Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 02/10] kernel: configs: enable rust samples in rust.config Ariel Miculas
2023-07-26 16:45 ` Ariel Miculas [this message]
2023-07-26 22:34 ` [RFC PATCH v2 03/10] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount Trevor Gross
2023-07-27 13:10 ` Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 04/10] rust: file: Add a new RegularFile newtype useful for reading files Ariel Miculas
2023-07-26 23:52 ` Trevor Gross
2023-07-27 13:18 ` Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 05/10] samples: puzzlefs: add basic deserializing support for the puzzlefs metadata Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 06/10] rust: file: pass the filesystem context to the open function Ariel Miculas
2023-07-27 13:32 ` Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 07/10] samples: puzzlefs: populate the directory entries with the inodes from the puzzlefs metadata file Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 08/10] rust: puzzlefs: read the puzzlefs image manifest instead of an individual metadata layer Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 09/10] rust: puzzlefs: add support for reading files Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 10/10] rust: puzzlefs: add oci_root_dir and image_manifest filesystem parameters Ariel Miculas
2023-07-26 21:08 ` Trevor Gross
2023-07-26 23:47 ` Wedson Almeida Filho
2023-07-27 0:02 ` Trevor Gross
2023-07-27 8:06 ` Wedson Almeida Filho
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=20230726164535.230515-4-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=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 NNTP newsgroup(s).