Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp4696529rdh; Wed, 29 Nov 2023 08:14:29 -0800 (PST) X-Google-Smtp-Source: AGHT+IEJLaeUbFlmhGHaIApOJRIvGFYBVI3l5lxyk3u6YRsfg7pGu6S4iFhCKb4gXdaK6l7zESOl X-Received: by 2002:a17:902:e74d:b0:1cf:cc3e:c550 with SMTP id p13-20020a170902e74d00b001cfcc3ec550mr15720945plf.5.1701274469562; Wed, 29 Nov 2023 08:14:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701274469; cv=none; d=google.com; s=arc-20160816; b=fhGOvMK/bTnaCtJ2Z/x5Sf9WIs4LMXzCTEvhAe/Pe9xGSPGtWIO5Mtzdn38LBCUy40 j2HyBW7xYn6wzSPbF+NYIoyvr357U8qbZ6jFhu/jXMNT9V+Z7E26MK1EvIivGAigNoHo mjxmA1FNL8Y+zUiEm6iShFe7C6NPvajCETHnPHpZTn4AImy1NBLfP+Zjk5SgskTEWO25 IY2cXITrqVnHCfh6IvB6UfgDab7U2VlhL3D65Fwmm983d37dZA6jppvH/3UTE4ZeCE1f cCG9G0Qr8rOBvr8jKej50ufY7aF3yFZs27/7HS4D+JFrUKEaWglb4c+N4gVw7ZV+5AAZ HOPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=fFPFHlsCVo2au9yCfMamYKu4kg8e+6bGJuWbKml5z14=; fh=nEaMtykN3yen8T6sC08/oNzV0+ox843bdf8+ebojgNE=; b=b4qKaGkUmaJNb056FSDH8yIn6s971chFPWNbMPwZu99zurbuqGGiudwbBTiaqcMlfX lO6uh0ltzhHTY2pG0rH0EvpOPxh9nU69pcSEuvDKr4BPvjDmOeB9vhrLVozLrNQODWpe 2T5C4uJfsKHvSlKa0A7P5ELLgxRvGpBbU3cpepUun1yNW/iN9U7kxZlHtmoA/3cfcUHc YRAn8bafH+cXGdYai3U1T9n8OePjiLb7Q7mDPHe+wvUJ1VfRyPGn7BhHYcsA+pHLK3MD buAF+yvBap84blf4hgg0QsxC2r3W7O0trFitSyEKxokOxcw+r3J6jKrE9FQ+68t7slMq b2Dw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WhSCVNXG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id jo23-20020a170903055700b001cfa577f866si11848475plb.132.2023.11.29.08.14.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 08:14:29 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=WhSCVNXG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 0A723802FBB7; Wed, 29 Nov 2023 08:14:28 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229983AbjK2QOS (ORCPT + 99 others); Wed, 29 Nov 2023 11:14:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229513AbjK2QOR (ORCPT ); Wed, 29 Nov 2023 11:14:17 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1EA2BF for ; Wed, 29 Nov 2023 08:14:23 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7ED8FC433C8; Wed, 29 Nov 2023 16:14:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1701274463; bh=uvJU3eH/XxZmi3lj0tA86wCTtEJNJwwsP4sFPa3oUOk=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=WhSCVNXGfk+Gcu/2TcZA43P3knbqsOAUiyui6bornKk0YxSWSG4rUYcUvaON/TQJ7 Ryh6FIcINp/e/9AODJttOsGnqP43WiV7ioP/w0m9OwNEBUnrr/zCAtIDPQF1Tsx60s Zs/WRYlRItAyazwSoLQauC2onfOzqd3T3JlMjuLyMzwEDELNE+oUvE1NmkBapjA+bh XzBTiv/W7gj9TbM4c/XAdDMLsDkInVVKt6OR/kyTzE+gMt98My/0vmS3V2SbQSnRQq WnhDEgPflGwhxjk+PtuI510+uUe3zwTvpE2KZ/H22RFLJdyex+uTma+2RdoMqoMbRT BbNMB0zeOxD8g== Date: Wed, 29 Nov 2023 17:14:14 +0100 From: Christian Brauner To: Alice Ryhl Cc: Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?B?QmrDtnJu?= Roy Baron , Benno Lossin , Andreas Hindborg , Peter Zijlstra , Alexander Viro , Greg Kroah-Hartman , Arve =?utf-8?B?SGrDuG5uZXbDpWc=?= , Todd Kjos , Martijn Coenen , Joel Fernandes , Carlos Llamas , Suren Baghdasaryan , 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 Subject: Re: [PATCH 4/7] rust: file: add `FileDescriptorReservation` Message-ID: <20231129-zwiespalt-exakt-f1446d88a62a@brauner> References: <20231129-alice-file-v1-0-f81afe8c7261@google.com> <20231129-alice-file-v1-4-f81afe8c7261@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20231129-alice-file-v1-4-f81afe8c7261@google.com> X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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 X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Wed, 29 Nov 2023 08:14:28 -0800 (PST) On Wed, Nov 29, 2023 at 01:11:56PM +0000, Alice Ryhl wrote: > 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 { Can we follow the traditional file terminology, i.e., get_unused_fd_flags() and fd_install()? At least at the beginning this might be quite helpful instead of having to mentally map new() and commit() onto the C functions. > + 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 ()>, I don't fully understand this. Can you explain in a little more detail what you mean by this and how this works? > +} > + > +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 _, This is a cast to a u32? > + _not_send_sync: PhantomData, Can you please draft a quick example how that return value would be expected to be used by a caller? It's really not clear > + }) > + } > + > + /// 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()) }; Why file.0.get()? Where did that come from? > + > + // `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 >