From nobody Fri Dec 19 02:56:04 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 481F6C001B0 for ; Wed, 26 Jul 2023 16:49:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231728AbjGZQty (ORCPT ); Wed, 26 Jul 2023 12:49:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231477AbjGZQtw (ORCPT ); Wed, 26 Jul 2023 12:49:52 -0400 Received: from aer-iport-1.cisco.com (aer-iport-1.cisco.com [173.38.203.51]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D8C5EC0 for ; Wed, 26 Jul 2023 09:49:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=3780; q=dns/txt; s=iport; t=1690390191; x=1691599791; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oseE7dVa4mchfbI4MxCXhpXz3QIa6pI8ihSwsEe0lxw=; b=RUK4J7Ud9RusefK/jB58eUckp1w4HBevAfIKlqySCzaI1vJtJoj3Vbhq +SkjMvzkhQDT3b2a/mwaGlYPmkq9n43eu4VTIDa87Il0IiwCq+b2FnByP 0gzpIXVhXFFGN6tbWljP9/R4+XQqJyctl6DNKwoYQjPqCW2zb2Y7RLf3j E=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="8452801" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-1.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:12 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTt022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:12 GMT From: Ariel Miculas 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 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 Message-ID: <20230726164535.230515-4-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Signed-off-by: Ariel Miculas --- 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_helpe= r.h index e5fc3b1d408d..205ef50dfd4c 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -18,6 +18,7 @@ #include #include #include +#include =20 /* `bindgen` gets confused at certain things. */ const gfp_t BINDINGS_GFP_KERNEL =3D 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); + +/// 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 transfe= r Vfsmount to another thread +unsafe impl Send for Vfsmount {} +// SAFETY: It's OK to access `Vfsmount` through references from other thre= ads 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 { + let path: Path =3D Path(Opaque::uninit()); + // SAFETY: path_name is a &CStr, so it's a valid string pointer; p= ath is an uninitialized + // struct stored on the stack and it's ok because kern_path expect= s an out parameter + let err =3D unsafe { + bindings::kern_path( + path_name.as_ptr() as *const i8, + bindings::LOOKUP_FOLLOW | bindings::LOOKUP_DIRECTORY, + path.0.get(), + ) + }; + if err !=3D 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 initial= ized because the call to + // kern_path succeeded + let vfsmount =3D unsafe { from_err_ptr(bindings::clone_private_mou= nt(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 &=3D + !(bindings::MNT_NOATIME | bindings::MNT_NODIRATIME | bindi= ngs::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) }; + } +} --=20 2.41.0