From patchwork Wed Jul 26 16:45:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 126500 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a985:0:b0:3e4:2afc:c1 with SMTP id t5csp540660vqo; Wed, 26 Jul 2023 10:07:18 -0700 (PDT) X-Google-Smtp-Source: APBJJlExo0jSzE3QwRt9QFzJsaelB65I3KUGxJdIfTOsgvjz6j7zKZ6CmfihIkOlYOJHTFAYYsGm X-Received: by 2002:a05:6a00:234c:b0:686:c7be:5259 with SMTP id j12-20020a056a00234c00b00686c7be5259mr3256769pfj.32.1690391237694; Wed, 26 Jul 2023 10:07:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690391237; cv=none; d=google.com; s=arc-20160816; b=xyoqS2+9kdsCHOAVPDYXGXHqCQBOmWt6q6DHTyDpWSscCnzaVTcmwhoH5b+htHPcKR d3BD30s/fZ3Ermwp4PrYBQxtmrFc6pVKJsi48sSv9wj5P0/PYFbdH+UER1PKeWnOJP7+ AYfM4yiGpN15XL5PK9yBpGdPYhfikUlcFf+V38b8lPLPme92BoGttZ233yOcVjFLmvgi zh21cCD/Sgsna43JWDoTLFwlOfs/G5goPF2LJGMT5qqwWouk+DDjAY8LP5qLKq60c1ih VO0r34XduzQ4A1D1BPzIE0CuSVV6NsXZE2rAnhBgH/UhHm7ODQoPnrKuqkdxJudTFgd7 T+MA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=iv3YZBfga3JH355n1cRCF++JvEQlZspeVLh3cTjncEU=; fh=Jpn3R4JmmVOUsuPzBxq53h+Q0nrbpuajN1OLJbY8QB4=; b=QyhTa5RoZzGWSoFOh3tXh0dWKZ68aSAkrNH18tq+USxxXtHeyo8pVvoijD+MqSr+W5 Xl+uurN6TaiqC27i5mMReVLMsBNX/O9MIyVYC2wNdvH8lZubRwx6096gVwbjMkHuh6Oe LZzmZvxVP2QfoazDQ3gl3WjJoAHQL9L19RM+uIQaHNa+2f/7jpZZi2Ct3TWobDs/+d9j wgo11T6VwMUk9oeCvQZLfmFj0T7Ev9RY3KYDefqnjIZ7hmptxfPvDCR3I301ovibLL+9 BcRAz+HfQ/aOo+f/B3tTuxKm/U3l56Y6aaeruAGruryO+Zu9ssXGwYIjUHoVlXttnGoS gCog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cisco.com header.s=iport header.b=RUK4J7Ud; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=cisco.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g2-20020a056a000b8200b006862e207c34si13674562pfj.66.2023.07.26.10.07.03; Wed, 26 Jul 2023 10:07:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@cisco.com header.s=iport header.b=RUK4J7Ud; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=cisco.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231640AbjGZQtx (ORCPT + 99 others); Wed, 26 Jul 2023 12:49:53 -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 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 X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIMWL_WL_MED,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, SPF_HELO_PASS,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772503682405288606 X-GMAIL-MSGID: 1772503682405288606 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_helper.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 /* `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); + +/// 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 { + 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) }; + } +}