Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp4564848rdh; Wed, 29 Nov 2023 05:12:24 -0800 (PST) X-Google-Smtp-Source: AGHT+IHVrXHg8VhsXAOi5a73XiGN32ltqyIRMJjXBsvZgJpp3IGPkt6JgxPNc2PNVFC/yG9vKWz9 X-Received: by 2002:a17:902:ce88:b0:1d0:220b:f24d with SMTP id f8-20020a170902ce8800b001d0220bf24dmr434396plg.31.1701263544276; Wed, 29 Nov 2023 05:12:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701263544; cv=none; d=google.com; s=arc-20160816; b=ztTTFk5pEP5d32SFTSzZt1XpLkqH3gjaaOVNJRWXYQjxjctjAI+fJJSB9zQSemzLCq U4CCXODT2KAdhEXC5PHnOv6KQouQ1xXCWyMnh557ZHjKpmt7gvZWzuoTJ+cDo+szO2qO JT/e1oNc6X6ERQcVAdNRwd80BGSKFTJpGMnJldS1CBED3muw0hXzcCP/vBdvz3dgJS1m gZM4mgYB7L31hJ0CGM05jw2AajkNnVjIfuJLXkSdx0accKTxOMQsi2eUUKZ9ZGsWrmsy VNG6pNg7trq3YzcI132Ft3SwJZDn83QfzBPl38CL6fUBcWRWweyR+DyX3lyDNA8ViRcY A0gQ== 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=esiXX39j7TBHYEJzpKp+/f8CbFmH8JGrCtrqMVnVTxs=; fh=6EEtf8+s6yyABtSDZ6Fe4igLduHvwiZU5fhW8T0ggOw=; b=REzskwraTydlcZlhxbkQ882FnTsIoqRBA7jndlPlwOJl7NhP3lEa8McT+As4gRoXNC YQHeC4hpW6xSg/zrZaqpzF59Mq1alWTHc9NnDAhrii5cBJ8JJETDOnub323anFLc1gKq kOlyfEBCSnn0X6hlS/dcrti3ax2wAgbEQPZ215teT/NIOUTnk8sZ623h/0X5S6PawkcD Woe2LBU6S95JLkO/b4Ql0OChU4AVhiAosBZiohPyNncDgvayaYMWa/AfIYAJ5ZWdnirp pA8crMcnYbGN9Jb20VcV5d6RZGI/gNKGBIFEMjyQTW2n1CNUjzDiUDpW2HMCUlMfWlcl CaLg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=ZPSHsaSF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 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 pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id u10-20020a17090282ca00b001cfa70f3a47si11294320plz.158.2023.11.29.05.12.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 05:12:24 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=ZPSHsaSF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 7CA468050036; Wed, 29 Nov 2023 05:12:21 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233816AbjK2NMC (ORCPT + 99 others); Wed, 29 Nov 2023 08:12:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59080 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233865AbjK2NMA (ORCPT ); Wed, 29 Nov 2023 08:12:00 -0500 Received: from mail-lj1-x249.google.com (mail-lj1-x249.google.com [IPv6:2a00:1450:4864:20::249]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BC361A8 for ; Wed, 29 Nov 2023 05:12:06 -0800 (PST) Received: by mail-lj1-x249.google.com with SMTP id 38308e7fff4ca-2c9b1bcd3f3so18430281fa.3 for ; Wed, 29 Nov 2023 05:12:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1701263524; x=1701868324; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=esiXX39j7TBHYEJzpKp+/f8CbFmH8JGrCtrqMVnVTxs=; b=ZPSHsaSFsodDALg4wMXiPT1b9FBJ7F87h0+ORAPJ8RwYh6FjbWH8okFnbR+EMypaUp 0zik3t8ZadLYLgDxVhdcfyb9vQ+x5IDXVhiovvvgb10YljIJP0DTbVlNwLbjJIpBkmS7 zxCiIaj7dIjPSscCe9TKhBfGbj2PcQ72l+D2EABofmVVfbNMe1CCcsm5ws0/uEtGrsGn SuTOVxD2gDziukuxCxp8w9Y8BhM4HB/OSVtjW+vCC2a+L/eW2MhotwuXQ3kDgkIubeq/ lsSoPOapIA9kN2Heg8nPpt4evQ+j2OgyJiCMsIz27ihE7/6OEUYtmFyJimvNzA043+A1 UpjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701263524; x=1701868324; 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=esiXX39j7TBHYEJzpKp+/f8CbFmH8JGrCtrqMVnVTxs=; b=QvdbPfNPBeMshurodkZKSZaz4BMCvlLBpPS+EYcMbtIJG2bGqc7aWaXO/BlkXhgyDZ P94ze5E1y65rywCFwisA94DyjqtmwUANKtboMvkj+IaTn8TgqGf3ZsQKiAhnyRJ7hwfq DsYyRIhSKaTWKnii/u6YLM2noFBvaHI53oRrMiPz9KSjF/hpc3kFQCFmNIikMntGB9Kd eHjRizP+BAfSOGff1g61VahCMuqf/6S6ozVnZpMNgmay9SnSImHIkrYCwVEJmcBvPUpp uUwGjYnHdS3AuMvrNdkTmUL7uaLmO03iZYHrBH4jXPH73LBRnuXvD3Z4EFUoXHNq9ykj ojuw== X-Gm-Message-State: AOJu0YxDFDIUOYZ08HeZL4KPesgZartaccXqTbBDJKosbmy6pxtuNrXg pyNoY2MuSg/rwa9X0REWoQqt/kixMGGv8ek= X-Received: from aliceryhl2.c.googlers.com ([fda3:e722:ac3:cc00:68:949d:c0a8:572]) (user=aliceryhl job=sendgmr) by 2002:a2e:9110:0:b0:2c9:bc04:c096 with SMTP id m16-20020a2e9110000000b002c9bc04c096mr38076ljg.8.1701263524554; Wed, 29 Nov 2023 05:12:04 -0800 (PST) Date: Wed, 29 Nov 2023 13:11:56 +0000 In-Reply-To: <20231129-alice-file-v1-0-f81afe8c7261@google.com> Mime-Version: 1.0 References: <20231129-alice-file-v1-0-f81afe8c7261@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=4281; i=aliceryhl@google.com; h=from:subject:message-id; bh=SUMv8jXGAij3l0jBYJ4Ms5z5jJZ9MMahswDWLeA0kW4=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBlZzMyLtWU3gmtQGN7swi+G8KMYaE/xHeadwZsb f4gruq0HDuJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZWczMgAKCRAEWL7uWMY5 RljxD/45lWUS95ldd319LMIbnsKDH8muiHzIgmCnI/Ux8ekOfs63WXOW6PMtpqlv2iZobLGYJv0 P9w0M1AKHI9s8ubw8ZFE+DOe6aa/2VTShlRKLi+Ka60afXjsTAEOY7l7vlDeDkU2qc5yMDNqErg hykmgusYIDJpSoOc8OaPMuR+V8jwxue/cP233vUY1HLlTf0TD3j0wOXn7cd+7zqH9iitsRnNyY4 Osu/48J1Wgic6eeI4i6+z478nY0uXs1fAWFBz8veBAwl9LCzi4avMG4SG/9Jv/CVB6Beq21tH5P GezShTMCYkKx08ZCrK0ckmIlfVaoVcMNInULaCznCgTrOv1iIZS63z8hlYkIOQskVbG17LXo9nF RfjdNRMH2YwYuxW3wdkNXJBc1oEGQCqWF7vqYchI3ryaNgpdFUcMJxupAe046aPUyBBOLJPuVIJ 3r84UtEGw+76Z+VbNDnAQdyHNFhKpvAvN6iX2nh5Am6ytp3eqYCNQiQ1RvXKbrMqR0+n8JhJoEt cL7Sv4Ias/SNUymafiEKQymxb4Af3F8BgKMANSHTU3Zm+Frzxm44c4xBp3X01IaPO335vmvao+a TEKWUG+9kx2sOIv7JKHksvoWevZD+SHwwAGCtGE7CCtoOoFg5iWOY51/afby0TdZEsmJeidtTsP je6av9Munk+4B6w== X-Mailer: git-send-email 2.43.0.rc1.413.gea7ed67945-goog Message-ID: <20231129-alice-file-v1-4-f81afe8c7261@google.com> Subject: [PATCH 4/7] rust: file: add `FileDescriptorReservation` From: Alice Ryhl To: Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Peter Zijlstra , Alexander Viro , Christian Brauner , Greg Kroah-Hartman , "=?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?=" , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan Cc: Alice Ryhl , Dan Williams , Kees Cook , Matthew Wilcox , Thomas Gleixner , Daniel Xu , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org Content-Type: text/plain; charset="utf-8" X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, 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 pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Wed, 29 Nov 2023 05:12:21 -0800 (PST) From: Wedson Almeida Filho Allow for 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). This is needed by Rust Binder when fds are sent from one process to another. It has to be a two-step process to properly handle the case where multiple fds are sent: The operation must fail or succeed atomically, which we achieve by first reserving the fds we need, and only installing the files once we have reserved enough fds to send the files. Fd reservations assume that the value of `current` does not change between the call to get_unused_fd_flags and the call to fd_install (or put_unused_fd). By not implementing the Send trait, this abstraction ensures that the `FileDescriptorReservation` cannot be moved into a different process. Signed-off-by: Wedson Almeida Filho Co-developed-by: Alice Ryhl Signed-off-by: Alice Ryhl --- rust/kernel/file.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index f1f71c3d97e2..2186a6ea3f2f 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 { @@ -180,6 +180,68 @@ 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). +/// +/// Dropping the reservation happens in the destructor of this type. +/// +/// # 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`. This method consumes the + /// [`FileDescriptorReservation`], so it will not be usable after this call. + 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.43.0.rc1.413.gea7ed67945-goog