Received: by 2002:a05:6358:7058:b0:131:369:b2a3 with SMTP id 24csp9723883rwp; Thu, 20 Jul 2023 08:50:15 -0700 (PDT) X-Google-Smtp-Source: APBJJlFHNcgjefGJWK4b5TtDJCGhAnuV1OvuVJuocdRufqrGbMw7O//TPoQIhVqXyfJ4WZa/iGoG X-Received: by 2002:a17:906:51d5:b0:99b:4525:e06c with SMTP id v21-20020a17090651d500b0099b4525e06cmr3835039ejk.55.1689868215349; Thu, 20 Jul 2023 08:50:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689868215; cv=none; d=google.com; s=arc-20160816; b=OOjECbd3tqll6AlbAD+JIAUgS1nQGFUFlZP9Jf86k9TStZWBJm0XBSMpZ5tTg5DF5l OujmGdhdmluhcYck7uXHWLT6rXo3DgWyQ0BGFvUbvGp9BuwtWfwqf+InDqNCCuZeVtIT 2y2aHkmE7zGjk0uptAHDZiYX6GLumaJkZSw+zEqhIMUOAFY3wPxxg2Ty2x5/BnRuvoc/ 9vCLSoB1I2u+a+3kDzUd6kYBGI48M56qX4ZB1SCpR50Mxg+fXEloHGT02Y5pJ0mTBfan 0scebFeXKuVQdei1WA3bvODERtDb4oamLwjMigpSEKSSOm7lv4B+yN8HtfymdsFRo2zg c20Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:dkim-signature; bh=EyZV70aSLRGUBSW3Idz74sX+TofVqWIQD1mh1640q38=; fh=ZYQR/+QQsWt7zde90+eOYsbHRzRn99OqhKFN5RgQnoI=; b=uPKGzMN+eWnQ6PBq4EdRcDYADNw2H+W+4PVdZVeZPNn9e4IKA+GxiPNFe5buDhdXY2 MtmzEAn7eTwoKdbFuCDJGfQDRGKDlp+StPlmV8EJEIJKHebaVAmEZcjctTRQX+W7E+Ds SCrbU8zXGz+A4gBuB+ex25njY4dIMwHTzceXKhqVV60t6vThmH2nq8hitXjRTzCk8lD1 ZaeONw8PYcGQqQQWT0Uqnvqzwh3kq1siksnPFeoHvowF1dJMtKygC50RCgm20hF0tZgq J0o2P3V8vCPsl4pz3nLxWISdvhO2DuBh+4SZxxTN5O6OFS+BAE7sIMZTTB+LQkLy98qf te7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=RqS707yH; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b19-20020a170906039300b0098ddf0dcf02si966562eja.157.2023.07.20.08.49.51; Thu, 20 Jul 2023 08:50:15 -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=@google.com header.s=20221208 header.b=RqS707yH; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232008AbjGTP3O (ORCPT + 99 others); Thu, 20 Jul 2023 11:29:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231293AbjGTP3D (ORCPT ); Thu, 20 Jul 2023 11:29:03 -0400 Received: from mail-ej1-x649.google.com (mail-ej1-x649.google.com [IPv6:2a00:1450:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F1FE1B9 for ; Thu, 20 Jul 2023 08:28:52 -0700 (PDT) Received: by mail-ej1-x649.google.com with SMTP id a640c23a62f3a-993eeb3a950so70923766b.2 for ; Thu, 20 Jul 2023 08:28:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1689866931; x=1690471731; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=EyZV70aSLRGUBSW3Idz74sX+TofVqWIQD1mh1640q38=; b=RqS707yH9iuG7p6GJXSLRTbTgG0a3UfXdNmkgzKXyq+LZAk/vDmF962f9cun/ZxZCg 7d44NcEuve934uCnCmHBq7kvmoXcMgE8vYD2El840R8evkmUt6iB4SguESYzPUmKs136 pcRKzjfCHFo51fe3uLQ8VtOzzYCmY7RUStmHPVdkrUlC+8ku7Pp6CEefLRS5aIo53e8p OY9bAVtCRHmJh/24zpIY+BvIeuDWITw0KryIPXViTV+QktgVYIYQbQaYHISUNt6cyX5Z KJiJ81aEPRXETKLR/BgpiqXSvxeDfS6e4nf+/0XDdPzyofbowKZ44ErJDP1tOrhygDtm fGDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689866931; x=1690471731; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EyZV70aSLRGUBSW3Idz74sX+TofVqWIQD1mh1640q38=; b=AO122V3k4okxv5KC+rdr4ofZOm3F67ME+hZNWpdlIM8DD51EvxgOP9bCPKXYc6wVIt NLY2AnaKoyJMx6uLTBUV3lCRrin4pVhVTDb798dmq+zz20We7d0ttc8oh+WbhEs5oG5z Ldxh35F6sNZOhfHRqrG4HXukLcBwtMC7N9jzGfX/ZVYFR5DdtyuM3Cmm0g+ZbCWkTI4j t89nztX9hzJHfAMPTzXKixSktxrITGhqee7haPjf8+Ux8a6DFNwPzDYvhPu4Kz1aGhTk YzA/c1bAbWpJRrYwKzZR4udrE9/abf3ljs1HMiLxejvHSQIz2yohd9TN2hBKOKcu4DKJ EmMg== X-Gm-Message-State: ABy/qLYJSLr/YafcS1qAm01PYT1ItZpwF/pjRaFv1TSBS8S6Ca2TAIg9 KUVKjut8R9AU6x8oVHpns+PtwPlZLtIpoSA= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:31:98fb:c0a8:6c8]) (user=aliceryhl job=sendgmr) by 2002:a17:907:2bd7:b0:98e:1a1b:9c21 with SMTP id gv23-20020a1709072bd700b0098e1a1b9c21mr15466ejc.5.1689866930843; Thu, 20 Jul 2023 08:28:50 -0700 (PDT) Date: Thu, 20 Jul 2023 15:28:18 +0000 In-Reply-To: <20230720152820.3566078-1-aliceryhl@google.com> Mime-Version: 1.0 References: <20230720152820.3566078-1-aliceryhl@google.com> X-Mailer: git-send-email 2.41.0.255.g8b1d071c50-goog Message-ID: <20230720152820.3566078-4-aliceryhl@google.com> Subject: [RFC PATCH v1 3/5] rust: file: add `FileDescriptorReservation` From: Alice Ryhl To: rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org, Miguel Ojeda , Alexander Viro , Christian Brauner Cc: Wedson Almeida Filho , Alex Gaynor , Boqun Feng , Gary Guo , "=?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?=" , Benno Lossin , Alice Ryhl , linux-kernel@vger.kernel.org, patches@lists.linux.dev, Wedson Almeida Filho Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=ham 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 From: Wedson Almeida Filho This allows the creation of a file descriptor in two steps: first, we reserve a slot for it, then we commit or drop the reservation. The first step may fail (e.g., the current process ran out of available slots), but commit and drop never fail (and are mutually exclusive). Co-Developed-by: Alice Ryhl Signed-off-by: Wedson Almeida Filho Signed-off-by: Alice Ryhl --- rust/kernel/file.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index d379ae2906d9..8ddf8f04ae0f 100644 --- a/rust/kernel/file.rs +++ b/rust/kernel/file.rs @@ -11,7 +11,7 @@ error::{code::*, Error, Result}, types::{ARef, AlwaysRefCounted, Opaque}, }; -use core::ptr; +use core::{marker::PhantomData, ptr}; /// Flags associated with a [`File`]. pub mod flags { @@ -179,6 +179,65 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +/// A file descriptor reservation. +/// +/// This allows the creation of a file descriptor in two steps: first, we reserve a slot for it, +/// then we commit or drop the reservation. The first step may fail (e.g., the current process ran +/// out of available slots), but commit and drop never fail (and are mutually exclusive). +/// +/// # Invariants +/// +/// The fd stored in this struct must correspond to a reserved file descriptor of the current task. +pub struct FileDescriptorReservation { + fd: u32, + /// Prevent values of this type from being moved to a different task. + /// + /// This is necessary because the C FFI calls assume that `current` is set to the task that + /// owns the fd in question. + _not_send_sync: PhantomData<*mut ()>, +} + +impl FileDescriptorReservation { + /// Creates a new file descriptor reservation. + pub fn new(flags: u32) -> Result { + // SAFETY: FFI call, there are no safety requirements on `flags`. + let fd: i32 = unsafe { bindings::get_unused_fd_flags(flags) }; + if fd < 0 { + return Err(Error::from_errno(fd)); + } + Ok(Self { + fd: fd as _, + _not_send_sync: PhantomData, + }) + } + + /// Returns the file descriptor number that was reserved. + pub fn reserved_fd(&self) -> u32 { + self.fd + } + + /// Commits the reservation. + /// + /// The previously reserved file descriptor is bound to `file`. + pub fn commit(self, file: ARef) { + // SAFETY: `self.fd` was previously returned by `get_unused_fd_flags`, and `file.ptr` is + // guaranteed to have an owned ref count by its type invariants. + unsafe { bindings::fd_install(self.fd, file.0.get()) }; + + // `fd_install` consumes both the file descriptor and the file reference, so we cannot run + // the destructors. + core::mem::forget(self); + core::mem::forget(file); + } +} + +impl Drop for FileDescriptorReservation { + fn drop(&mut self) { + // SAFETY: `self.fd` was returned by a previous call to `get_unused_fd_flags`. + unsafe { bindings::put_unused_fd(self.fd) }; + } +} + /// Represents the EBADF error code. /// /// Used for methods that can only fail with EBADF. -- 2.41.0.255.g8b1d071c50-goog