From patchwork Thu Sep 26 14:58:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13813443 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84D6E1534E6 for ; Thu, 26 Sep 2024 14:59:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727362781; cv=none; b=sNuw1hynOmHEylT+JQtzJG18w8wUOG8dCK6bxeL74qhRZTFPxG40J9ZoTaeiVFCt4ygo6AH2Pi0i7y7dKtnAVI4vXLhbRoD9nQK4Z85MhWkuwPzuX+kB3MbWvX9luAIf3qd1wjgCYKOWFi1n+7FqMV1UXDZb4cO0pKWylEV7pS8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727362781; c=relaxed/simple; bh=OmA5Fpc8q+VVliuvZsHkzpnnFxIk9+56osMv6UGZYI0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=G8VTKoZiv1Y8Q2PHQV3FWznjjee0IXNflR9tuyfRQ5K8AgOJKbjmKnlZz6vfs14tPXDu4B08Wji4dvtxUnwipb2SN+IZOMmooxG1HnBxUSMBplf0qxUh3g9Ozlt6jD6cVxhit6PkUfY5u3DTGfPdoxF9Z12c7NlxIxHCtSfiv6Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=nZjU4xIK; arc=none smtp.client-ip=209.85.221.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="nZjU4xIK" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-37ccc96d3e6so508021f8f.1 for ; Thu, 26 Sep 2024 07:59:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1727362778; x=1727967578; 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=I4ovaENvdzEIgnWtdOGCa2HlqqG1g+BvQV/UUS4KByA=; b=nZjU4xIKWg0tgbOhlJ6GAlAcuFAtzpDKS0BOn3hDhh+B4VJ0BlKmYuP/APEyPtOE55 8H0UCr3n5kO66mHXX9rUB13T38mXhWAvY9saRHoc1rx1OLYrevR+pa89bvh0zwRAzWkX EcrhVDJf33/FHgViIDmG70zjNih8aFuwJaMUCKEIkBZF0tOyNecTbUCj3+nMAHBBe47v 7ZQQ+8G5ArH/Om3+rkhdeMNhF+s99MRX5WPdbPDDd1gbsKHe6Ua49grDYgE/KoDcr3XR TsCO14QLTyjb2xb46z/wYZCyJ23jIAKC+x9gaGq6r62ENX/bM+fNm4DQK/m+4lt3JDbB jJWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727362778; x=1727967578; 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=I4ovaENvdzEIgnWtdOGCa2HlqqG1g+BvQV/UUS4KByA=; b=WL5c+xVUR8mGyz4odg/gAkSECwfhfc0EGMirWzBdenWfO9+xswwZ7VnlFxYM24AJUn nBedvFK95zGgM8LSrWfKCzZ6UpcmjSOpZSKTSNmJFoSaIbG8Tm/ptdADZno5yGVVTWO4 +OL2UU3IvEJubMib0PA/ImNjw2OwOAhipcqFKOJsaxqsSZncqoALjUc4+TyqUb8lEcI2 88/XmZAOUCG0S2OGD5dzG+jSILlRllrsKAHSaqg6JQgLDllWdMGo0lST7lIiSV0Ws4x4 +k+mk9zCEecW83Ci2zeDa4e2L1cOVS8fHpVwAvYE+fJ072VwdrcQAQx+xKNF3FIZTS+e DpjQ== X-Forwarded-Encrypted: i=1; AJvYcCURTNTnsGMJoIoZe1vYb6yksG/cNyF9EvGPIMrDT8rj2QRPeK8Gc7DBZ3qw4hDzZkqjKUC6jOooEroZyh7Y@vger.kernel.org X-Gm-Message-State: AOJu0YyJdHtNJ0GJpP7daMVh8loF8ri6nCkQAvmT6mnY0ovcV0ny3bwe 694sZI7eirKzVfCRS2RNiKwOkFMTLpvAQwdU8n6v5pGUy2qoKDC3Ye2e7k91kOn290iWdM8065I L/kZDGNfBzNb/mQ== X-Google-Smtp-Source: AGHT+IFKEbPPWgHrvBx3h62gH1uccNY84xCIpV8wPvnZRiFspAmH/JXjTSZnsxXOxNukoaeaW6QiOQdx2PwCrf0= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:35bd]) (user=aliceryhl job=sendgmr) by 2002:a5d:5d86:0:b0:37c:cd08:ae77 with SMTP id ffacd0b85a97d-37ccd08aea5mr2171f8f.5.1727362777240; Thu, 26 Sep 2024 07:59:37 -0700 (PDT) Date: Thu, 26 Sep 2024 14:58:55 +0000 In-Reply-To: <20240926-b4-miscdevice-v1-0-7349c2b2837a@google.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240926-b4-miscdevice-v1-0-7349c2b2837a@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=1611; i=aliceryhl@google.com; h=from:subject:message-id; bh=OmA5Fpc8q+VVliuvZsHkzpnnFxIk9+56osMv6UGZYI0=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBm9XbSQkqismR95jHztyc9oFt0R1RyL0v4MQoMg Ybr2gj5HH+JAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZvV20gAKCRAEWL7uWMY5 RgiQEACG+ngJ8Ks/GRo9WYo2LpeGTNA9gO//nSEXxJjeP0yNTMg8B4A2Z6/QTljOib63lFektQK 2dbJJzREq8Tw0n/wcsY00gwTbJbKLNq2fo1nRvqSEjGS1jOXUuGIfSGcrly6WcVRb40JvWmG0q/ 5TpqUYdL255WyX2jVzfXX0IStAImQ02hJilPi+UawWPgyCup76PcZpVbaAFKjaeIICGuIZbE/U4 axpSi2VgGnWUG0HdPz2/xbcMsPdkUCMaDSmLCpjraZkGtvkVchET0tV3eGfwaxAoHFvv8J2n3VT /AEk+jAYH8eYHetyof6y/VOZl5JoJV/uj8rJ7b/gQfs+c0M9WgxZuyFVmMm5spt4WDdInsSALVq 0FnKPgICKpjMeFWbQorKiQj24xDms0TEOlMWnWMILMeapra2XAxcqeIggXkXFvSb8n6Kf3Qt3ph Ohpo/UAoZOLymhitGXvvlqAa5JLnYto4hkzaJ9SdTDM7z8hes/a36e2L/wHM6pyZTtoGHH431nx jq4RUgtjOR0A5oEFRCYLTVNswpeeF55Uq5hyIHkfiFJsM7uAnuiXxl980kOhVYik7IdpCbrgRC6 3bcwCCwsx329WRLELYhYoURZbtvLENW3mTgqj5PWMq62MLzwUY6T4hOsg79nFyKH3yR8uuYpQWR rQqS160OiCK7K3Q== X-Mailer: b4 0.13.0 Message-ID: <20240926-b4-miscdevice-v1-1-7349c2b2837a@google.com> Subject: [PATCH 1/3] rust: types: add Opaque::try_ffi_init From: Alice Ryhl To: Greg Kroah-Hartman , Arnd Bergmann , Miguel Ojeda , Alexander Viro , Christian Brauner , Jan Kara Cc: Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Alice Ryhl This will be used by the miscdevice abstractions, as the C function `misc_register` is fallible. Signed-off-by: Alice Ryhl Reviewed-by: Fiona Behrens --- rust/kernel/types.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index 3238ffaab031..dd9c606c515c 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -299,6 +299,22 @@ pub fn ffi_init(init_func: impl FnOnce(*mut T)) -> impl PinInit { } } + /// Creates a fallible pin-initializer from the given initializer closure. + /// + /// The returned initializer calls the given closure with the pointer to the inner `T` of this + /// `Opaque`. Since this memory is uninitialized, the closure is not allowed to read from it. + /// + /// This function is safe, because the `T` inside of an `Opaque` is allowed to be + /// uninitialized. Additionally, access to the inner `T` requires `unsafe`, so the caller needs + /// to verify at that point that the inner value is valid. + pub fn try_ffi_init( + init_func: impl FnOnce(*mut T) -> Result<(), E>, + ) -> impl PinInit { + // SAFETY: We contain a `MaybeUninit`, so it is OK for the `init_func` to not fully + // initialize the `T`. + unsafe { init::pin_init_from_closure::<_, E>(move |slot| init_func(Self::raw_get(slot))) } + } + /// Returns a raw pointer to the opaque data. pub const fn get(&self) -> *mut T { UnsafeCell::get(&self.value).cast::() From patchwork Thu Sep 26 14:58:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13813444 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33A0D156228 for ; Thu, 26 Sep 2024 14:59:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727362783; cv=none; b=QZgpsNnPp3t4Xk7zdw9/FtllHkvQNcDjWi04YFF8JEiLkgciFVqqx5UailwhmRbBjOflgFsMUgwmAuwFfh8Jry20Z19O+2EEC7HyiwThP4+sf50F5b0CMAjx27TXnV1kvaqpuc6tgs9oKXXOfk7X2iyZ50G+P8Q++QMjn54UEOg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727362783; c=relaxed/simple; bh=Eg4ozalPfp9Dq+G3RNTBq09+vqD1HxtxrCxKQ7R9a6k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NHOO6z/y1Y5lhwwaIC10R6NYSSlfW9fyCSujXfjD08Cz2phb3uEXRTmg3iPr7wv75KDWU24zvhzj2+WEIY7iSs/1slU1RXyBvgrRrpu7/cI+WTtPBqtY7811ksxviMHSFbBm8JrOCR55S1wSikQDdwWADDEetMiJfFG4/mHaDiw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=OEXTgxq4; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="OEXTgxq4" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6d3e062dbeeso13622187b3.0 for ; Thu, 26 Sep 2024 07:59:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1727362780; x=1727967580; 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=NeV1KHW77gl2ixtTigXOOKfMDho4UiCgTf2SV63cy/Q=; b=OEXTgxq4sKMvvAy67Dh8YjizLVbOJ5k1gUFzDMBwx5RpDYP1FqjJaWKv36U5shCBUv 3JiETjDfPDsFX16kB6kUOUD4xdxOXHnyXyXMk/3friP6Ufr3QC1+idjlyqRaJit6UV2W jsaBfF0L+wfZcUuHRBe7M35hGgUAeqpnvTdW8A4tG7eSpfn+hvIn7AMTwPjS6gTVdzEO qi8pybyfCUeS7KWd1Iw2X+CEV6l/pJlvxIzsmc5+qKxBgibG3x14H6vmYTcb0+2+Bhxk MyNKd04/gVhxGvY7xggMbANzGtHwbVhqu1uTgDHUIz3Nzlw8QeqVA411lrkwAGJG15mu Q4pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727362780; x=1727967580; 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=NeV1KHW77gl2ixtTigXOOKfMDho4UiCgTf2SV63cy/Q=; b=dtEDWGW4tewvyyLgna072kAdjJRjavoLJcPAr5FK9uSuIps1ZOJQr7LIZo7inmD/0y sd5mNoBPGd0TMdHvPWOzWGDSgdQWl9NZwZOmKCPg/ZT/+y0pdmwcqxxKT+yu+2oV1V2H mRL03Q6nI+edHij76IkQJqvwwtDDlEL6ShREIAnZdzJYykU6AFxj+blr7/OhjEFH5Vqi zMWDbp0WFOZ8b1JkmFlN7I5296tS92vUTzt96/oABodkoaYfAtZ4f9HGZp/UYdcNNQs+ quDZCuoDzyY3VnSR+k1sK8UE+QTyMPoDftQkGlPWvI4YuA/AJYfKulGbY8XEb2AKJfcy e7Vg== X-Forwarded-Encrypted: i=1; AJvYcCVyEyGlcZ41+D0WvXCuIcreAiwxTAa2r1WnXkMjcPHmgsZPSGkFefFdzfxfWnAjs1thpeg6awlzi4mg0XAD@vger.kernel.org X-Gm-Message-State: AOJu0Ywt37gJZAD+E60YHT3Mx4plgttA90OB7Qihq1yDqslHDRzxEDku KELNr9wtjn55vIMQSd1zpXVCT9UenpbL/YMeeuUHDyx3hfdddWQTCKQpRAuvA7mJnZT4bXY5xno thYbdZshi4XVD8Q== X-Google-Smtp-Source: AGHT+IFXzXcQGkkg6miI4lRR5aDTs+z8nxuijS5MIlaFFi6hc9IleFgTZI1r0Pf/fM7aCAkUF4CI+a3V4yd3vaM= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:35bd]) (user=aliceryhl job=sendgmr) by 2002:a05:690c:3405:b0:6d9:d865:46c7 with SMTP id 00721157ae682-6e22eddb5d4mr290447b3.2.1727362780176; Thu, 26 Sep 2024 07:59:40 -0700 (PDT) Date: Thu, 26 Sep 2024 14:58:56 +0000 In-Reply-To: <20240926-b4-miscdevice-v1-0-7349c2b2837a@google.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240926-b4-miscdevice-v1-0-7349c2b2837a@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=1648; i=aliceryhl@google.com; h=from:subject:message-id; bh=Eg4ozalPfp9Dq+G3RNTBq09+vqD1HxtxrCxKQ7R9a6k=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBm9XbTowpCdvo26oRjUrDd2SCJfZSsqtQXyf1e6 aNmADjn0mqJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZvV20wAKCRAEWL7uWMY5 RrmiEACSG2C7yeB3qHx86arzRAzmg9UQ6670GsCB4hPpsLd5PJPnl8TwUULgOTX7eXcKEhOPuUp uThZFejvJD+T3SSZMsh9OwbIZEkBbGm/HOO6MCaEjmK+v4+d1Mn8NRT2rfwifU2juxsubMRN5H8 RBhCu+w9oPkFw9RRw5PKE9KQdO8h+zuOSf90pXOYDVHQ6jiwM3tdtrS7gjhD44eq0wwCVTzaVBL cS7c9owyotQ7SqY87HJQA5cp85DO+0ann56qTE+2PXZVc/SaQDuMdzwmKypdbBBHfbACD4ICP9L uuCq75U8+DlZr9Dx1xCatEybfz8Q2TWQBrflphbJtMs0NhHL1cWoYwDBXNgiWd8WBORQIeLZHdb wnVGRgbOAu2+OIt2FXjjmyMEse63ZGVyoYFOqm8oHQL1Dg0/sNw9cK1XCOn1iaJpyCcud9F67dV uMRCacwi/HN/Rs4CqTfSLamBTppC1MWSvkaXnDpY5jI5yNNiWpXrg1etF+AcPDg9Syh/czy+Aoq x0cP0IlNTyTn0dLbJybbXPUtVgMUOlNd0jj/B/sFlEPymXHCT0YdkBzPeDhFdTRXfrf8S0uZLO7 9A2JGCx3J0lAysqYfW36wJhlrZwLpi6jSzGXuiyPWmpofby1KBRRuR4DngYqVXhfsYrJdewTB4E ArpTcxpmLl4b9JA== X-Mailer: b4 0.13.0 Message-ID: <20240926-b4-miscdevice-v1-2-7349c2b2837a@google.com> Subject: [PATCH 2/3] rust: file: add f_pos and set_f_pos From: Alice Ryhl To: Greg Kroah-Hartman , Arnd Bergmann , Miguel Ojeda , Alexander Viro , Christian Brauner , Jan Kara Cc: Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Alice Ryhl Add accessors for the file position. Most of the time, you should not use these methods directly, and you should instead use a guard for the file position to prove that you hold the fpos lock. However, under limited circumstances, files are allowed to choose a different locking strategy for their file position. These accessors can be used to handle that case. For now, these accessors are the only way to access the file position within the llseek and read_iter callbacks. Signed-off-by: Alice Ryhl --- rust/kernel/fs/file.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs index e03dbe14d62a..c896a3b1d182 100644 --- a/rust/kernel/fs/file.rs +++ b/rust/kernel/fs/file.rs @@ -333,6 +333,26 @@ pub fn flags(&self) -> u32 { // FIXME(read_once): Replace with `read_once` when available on the Rust side. unsafe { core::ptr::addr_of!((*self.as_ptr()).f_flags).read_volatile() } } + + /// Read the file position. + /// + /// # Safety + /// + /// You must hold the fpos lock or otherwise ensure that no data race will happen. + #[inline] + pub unsafe fn f_pos(&self) -> i64 { + unsafe { (*self.as_ptr()).f_pos } + } + + /// Set the file position. + /// + /// # Safety + /// + /// You must hold the fpos lock or otherwise ensure that no data race will happen. + #[inline] + pub unsafe fn set_f_pos(&self, value: i64) { + unsafe { (*self.as_ptr()).f_pos = value }; + } } impl File { From patchwork Thu Sep 26 14:58:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alice Ryhl X-Patchwork-Id: 13813445 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4EB7156F23 for ; Thu, 26 Sep 2024 14:59:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727362785; cv=none; b=ecK4q8GmfDVFkBksKRnrZzjuLs44jfddH2wwJvnpgOPwGMguLOC1mrjkfaKcpQAiV3BC7wbFdTaa1ut2pG+lSONAdKfj96MGtLOILafbWAUm5wlpd99GUz0T/maLphpewH6hcwPf7yuQaklSWgIwJPkWSyEYHbpAHIaQli85ubg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727362785; c=relaxed/simple; bh=J6EBGaktQEIu0VpIbJIaFWXDXCR1uIR4hNwqEN2XYQ4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=aoYOIpNIpQnMkOAWsFdi+d4+AnEW4xWlZq0p6808bkNwk/m2dyilBZRdpmHkNB12q/wVLgI8URNP334OgR0ZHLNhh7Wc/FJr09zx8JhsRfH1Yiv/F6OBm5SEONMmdcCMkrIk9mXcIn5/xF3OgFtUAgIySij8JbiXAeSstDNvpQA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=XmwL22I1; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="XmwL22I1" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e02a4de4f4eso1892259276.1 for ; Thu, 26 Sep 2024 07:59:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1727362783; x=1727967583; 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=Z2HODxaqAHzELuUx1xsYuulIg8XkoDAyXEK+wa7uqt4=; b=XmwL22I1mJFkLG67JEuvnupFkmYajuENO0j/jiDBzAVJZvsxhE9xMEbHfN68R60MYP T6/f1BSjumfCfdclzFn0OHdUmfzX26vZjD/YaYEcW7auDhzn+n3LFNV9/5CaPftqew+L ZhDAERRFoGRSVPEh8C5FIhn6z664rJ7DNCeFqHj7Lyjea99AKhtmnIHJsbQn6yu5bIFE Kc1SGuYyN7/aoMVG9Ak42Jlk0QS0GM9u0x/RQc8MnUuQ47bWR5O94P6aXUjZDxilB+S3 NWFt9S2uVkm1yhPwzewzXiUXebLQFl9BULlpmwmlOCrgHKiy+ynZ7JcFEPAXrghHUpAX M2sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727362783; x=1727967583; 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=Z2HODxaqAHzELuUx1xsYuulIg8XkoDAyXEK+wa7uqt4=; b=qVVrSTtZvSI3hXdqGCr6NRu2Qft9Fam9SnJR/ryLlQJc2rJO3jj6mDNsP3HHQEz+96 iHXgG8uE8CQko5rYYebhgEZHN7YMQZ5RXs3zRVb7WYTFlKDqY+8T0SN8gXYc5k/JUY4h q9Zchk5WucuOhOx4N0JBtnaCiymOyRE/QQEfd8P/FWislgyEXZz0Dw9ZiAekKWL92gkU SvVeAjVmD2AnVuMPvimP4CHNzWU/LJDl1+LWexnTF35+hyQHjIop8A40j9t4LXPv4hZi PDUaU9/ylti6fYrZ3xxS998jqdlD9zb8xlsqx957677S++NuTWkOPfWlnXblam4JSlBp q/ZA== X-Forwarded-Encrypted: i=1; AJvYcCUb08hARPOZ04p5zSKnwSydFOWKLLZUqY73hm0fFuHykNS4MP1JMX5JWuqQpcOWQyNXplp/d8uJRhbt3yNi@vger.kernel.org X-Gm-Message-State: AOJu0Yx7W3PEBh0VfQpgktcsEsKsSWhj2F4rY4wvsJWMFWk54UULB6wL ZrvpuraJkMBdk2CjDMlBP5YE63lX1jU5oHuU6EXJA9YUJMUWxdn42uuYbDelaVu2yYXtBuXxB2Y DQiFXCmEALk/jeg== X-Google-Smtp-Source: AGHT+IEguqZ3KMFd8ePo88MXCzgONy3nQRtjG18qWhiIa6RhW90LDIg8vul7ERYQkvCgYgZUJSpHwfUb7nLAmd8= X-Received: from aliceryhl.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:35bd]) (user=aliceryhl job=sendgmr) by 2002:a25:d608:0:b0:e11:6a73:b0d with SMTP id 3f1490d57ef6-e24d9dc640bmr4525276.6.1727362782693; Thu, 26 Sep 2024 07:59:42 -0700 (PDT) Date: Thu, 26 Sep 2024 14:58:57 +0000 In-Reply-To: <20240926-b4-miscdevice-v1-0-7349c2b2837a@google.com> Precedence: bulk X-Mailing-List: linux-fsdevel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240926-b4-miscdevice-v1-0-7349c2b2837a@google.com> X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=15628; i=aliceryhl@google.com; h=from:subject:message-id; bh=J6EBGaktQEIu0VpIbJIaFWXDXCR1uIR4hNwqEN2XYQ4=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBm9XbTMB2KXt4UicQ0jDm5xwwbVCabQZr4BkEFY G+JfbmA8GCJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCZvV20wAKCRAEWL7uWMY5 RnILD/9UysiU1PquvE+YXTDIrG86uR5k55PO2MPQSYCrwvrjFIoFvx2f+sFshxNXOtdnA1XmkeT JlGw1ZthZ/FbTSJM0uOwW4fgCm7Gy7pN2ds1djZaFkD4Wt02JZMfmoM4ornCXKHgbMu062Ckgd1 S+lcFoxQ4CQqgsOu8B87HGWzShtQCQoaBDl60rer1zQzFDoRKsvrKTeuNGVQtWDl7cOkFhr81Qr e+KuGWjUkuIMaszHhUChEr1YJSlV3CEdfBhPoV3Tdv808Hhox56OpCSi5WKM7o/U89o+InwUwnY SnG2bDb40XJdVRLeotBMhO2vJOfXVl0clZ8TT83vtBXe7soImDsSsqHRCje3laAzEV4YgARZSKF pc7zrBBhYNJLs2GPOwyITfdGe9U8p1pE6vcoUEEKrMbYBN/jsYjF1Y0w4nVW03e9g0FkNUrpp6T qRKAsolW7XgMaQRXVMbdm4d442wxShcg0D6sPBsfK3YgEfmu/NlyIJCNLC6IkWouoPoC9ERWDmK zwm1F7D/EJKsSmyWLulT1H9St9fawTcPZaMiKekIXMp1ZyAAXXaAIlOhi1pNgzGVvGKXaT9AjHs aFgy0TfXjsC+VOroGrtRnL6Wrtv0rtbc+IFw93ccRFykS1qVSDXPELb+BjX0MnKyhxdBxmhDG19 vDWNemNzdD4kBwA== X-Mailer: b4 0.13.0 Message-ID: <20240926-b4-miscdevice-v1-3-7349c2b2837a@google.com> Subject: [PATCH 3/3] rust: miscdevice: add abstraction for defining miscdevices From: Alice Ryhl To: Greg Kroah-Hartman , Arnd Bergmann , Miguel Ojeda , Alexander Viro , Christian Brauner , Jan Kara Cc: Boqun Feng , Gary Guo , " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " , Benno Lossin , Andreas Hindborg , Trevor Gross , rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Alice Ryhl Provide a `MiscDevice` trait that lets you specify the file operations that you wish to provide for your misc device. Most operations are optional. In the future, the file operations in the `MiscDevice` can be moved to a general `FileOperations` trait so that it is useful for other file systems too. Signed-off-by: Alice Ryhl --- rust/bindings/bindings_helper.h | 1 + rust/kernel/lib.rs | 1 + rust/kernel/miscdevice.rs | 401 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 403 insertions(+) diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index ca13659ded4c..ec2e28ef6568 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 819126fc2d89..bf97817842c9 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -41,6 +41,7 @@ #[cfg(CONFIG_KUNIT)] pub mod kunit; pub mod list; +pub mod miscdevice; pub mod mm; #[cfg(CONFIG_NET)] pub mod net; diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs new file mode 100644 index 000000000000..6c4e33d77c58 --- /dev/null +++ b/rust/kernel/miscdevice.rs @@ -0,0 +1,401 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Copyright (C) 2024 Google LLC. + +//! Miscdevice support. +//! +//! C headers: [`include/linux/miscdevice.h`](srctree/include/linux/miscdevice.h). +//! +//! Reference: + +use crate::{ + bindings, + error::{to_result, Error, Result, VTABLE_DEFAULT_ERROR}, + fs::{File, LocalFile}, + mm::virt::VmArea, + prelude::*, + str::CStr, + types::{ForeignOwnable, Opaque}, +}; +use core::{ + ffi::{c_int, c_long, c_uint, c_ulong}, + marker::PhantomData, + mem::MaybeUninit, + pin::Pin, + ptr::NonNull, +}; + +/// The kernel `loff_t` type. +#[allow(non_camel_case_types)] +pub type loff_t = bindings::loff_t; + +/// Options for creating a misc device. +#[derive(Copy, Clone)] +pub struct MiscDeviceOptions { + /// The name of the miscdevice. + pub name: &'static CStr, +} + +impl MiscDeviceOptions { + /// Create a raw `struct miscdev` ready for registration. + pub const fn into_raw(self) -> bindings::miscdevice { + // SAFETY: All zeros is valid for this C type. + let mut result: bindings::miscdevice = unsafe { MaybeUninit::zeroed().assume_init() }; + result.minor = bindings::MISC_DYNAMIC_MINOR as _; + result.name = self.name.as_char_ptr(); + result.fops = create_vtable::(); + result + } +} + +/// A registration of a miscdevice. +/// +/// # Invariants +/// +/// `inner` is a registered misc device. +#[repr(transparent)] +#[pin_data(PinnedDrop)] +pub struct MiscDeviceRegistration { + #[pin] + inner: Opaque, + _t: PhantomData, +} + +unsafe impl Send for MiscDeviceRegistration {} +unsafe impl Sync for MiscDeviceRegistration {} + +impl MiscDeviceRegistration { + /// Register a misc device. + pub fn register(opts: MiscDeviceOptions) -> impl PinInit { + try_pin_init!(Self { + inner <- Opaque::try_ffi_init(move |slot: *mut bindings::miscdevice| { + // SAFETY: The initializer can write to the provided `slot`. + unsafe { slot.write(opts.into_raw::()) }; + + // SAFETY: We just wrote the misc device options to the slot. The miscdevice will + // get unregistered before `slot` is deallocated because the memory is pinned and + // the destructor of this type deallocates the memory. + // INVARIANT: If this returns `Ok(())`, then the `slot` will contain a registered + // misc device. + to_result(unsafe { bindings::misc_register(slot) }) + }), + _t: PhantomData, + }) + } + + /// Returns the private data associated with the provided file. + /// + /// Returns `None` if the file is not associated with this misc device. + pub fn try_get_private_data<'a>( + &self, + file: &'a LocalFile, + ) -> Option<::Borrowed<'a>> { + // SAFETY: `fops` of a miscdevice is immutable after initialization. + let fops_this = unsafe { (*self.as_raw()).fops }; + // SAFETY: `f_op` of a file is immutable after initialization. + let fops_file = unsafe { (*file.as_ptr()).f_op }; + + if core::ptr::eq(fops_this, fops_file) { + // SAFETY: We know that `file` is associated with a `MiscDeviceRegistration`, so + // `private_data` is immutable. + let private_data = unsafe { (*file.as_ptr()).private_data }; + // SAFETY: + // * The fops match, so the file's private date has the right type. + // * The returned borrow cannot outlive the file. + Some(unsafe { ::borrow(private_data) }) + } else { + None + } + } + + /// Returns a raw pointer to the misc device. + pub fn as_raw(&self) -> *mut bindings::miscdevice { + self.inner.get() + } +} + +#[pinned_drop] +impl PinnedDrop for MiscDeviceRegistration { + fn drop(self: Pin<&mut Self>) { + // SAFETY: We know that the device is registered by the type invariants. + unsafe { bindings::misc_deregister(self.inner.get()) }; + } +} + +/// Trait implemented by the private data of an open misc device. +#[vtable] +pub trait MiscDevice { + /// What kind of pointer should `Self` be wrapped in. + type Ptr: ForeignOwnable + Send + Sync; + + /// Called when the misc device is opened. + /// + /// The returned pointer will be stored as the private data for the file. + fn open(_file: &File) -> Result; + + /// Called when the misc device is released. + fn release(device: Self::Ptr, _file: &File) { + drop(device); + } + + /// Handle for mmap. + fn mmap( + _device: ::Borrowed<'_>, + _file: &File, + _vma: Pin<&mut VmArea>, + ) -> Result<()> { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } + + /// Seeks this miscdevice. + fn llseek( + _device: ::Borrowed<'_>, + _file: &LocalFile, + _offset: loff_t, + _whence: c_int, + ) -> Result { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } + + /// Read from this miscdevice. + fn read_iter(_kiocb: Kiocb<'_, Self::Ptr>, _iov: &mut IovIter) -> Result { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } + + /// Handler for ioctls + /// + /// The `cmd` argument is usually manipulated using the utilties in [`kernel::ioctl`]. + /// + /// [`kernel::ioctl`]: mod@crate::ioctl + fn ioctl( + _device: ::Borrowed<'_>, + _file: &File, + _cmd: u32, + _arg: usize, + ) -> Result { + kernel::build_error(VTABLE_DEFAULT_ERROR) + } + + /// Handler for ioctls + /// + /// Used for 32-bit userspace on 64-bit platforms. + #[cfg(CONFIG_COMPAT)] + fn compat_ioctl( + device: ::Borrowed<'_>, + file: &File, + cmd: u32, + arg: usize, + ) -> Result { + Self::ioctl(device, file, cmd, arg) + } +} + +/// Wrapper for the kernel's `struct kiocb`. +/// +/// The type `T` represents the private data of the file. +pub struct Kiocb<'a, T> { + inner: NonNull, + _phantom: PhantomData<&'a T>, +} + +impl<'a, T: ForeignOwnable> Kiocb<'a, T> { + /// Get the private data in this kiocb. + pub fn private_data(&self) -> ::Borrowed<'a> { + // SAFETY: The `kiocb` lets us access the private data. + let private = unsafe { (*(*self.inner.as_ptr()).ki_filp).private_data }; + // SAFETY: The kiocb has shared access to the private data. + unsafe { ::borrow(private) } + } + + /// Gets the current value of `ki_pos`. + pub fn ki_pos(&self) -> loff_t { + // SAFETY: The `kiocb` can access `ki_pos`. + unsafe { (*self.inner.as_ptr()).ki_pos } + } + + /// Gets a mutable reference to the `ki_pos` field. + pub fn ki_pos_mut(&mut self) -> &mut loff_t { + // SAFETY: The `kiocb` can access `ki_pos`. + unsafe { &mut (*self.inner.as_ptr()).ki_pos } + } +} + +/// Wrapper for the kernel's `struct iov_iter`. +pub struct IovIter { + inner: Opaque, +} + +impl IovIter { + /// Gets a raw pointer to the contents. + pub fn as_raw(&self) -> *mut bindings::iov_iter { + self.inner.get() + } +} + +const fn create_vtable() -> &'static bindings::file_operations { + const fn maybe_fn(check: bool, func: T) -> Option { + if check { + Some(func) + } else { + None + } + } + + struct VtableHelper { + _t: PhantomData, + } + impl VtableHelper { + const VTABLE: bindings::file_operations = bindings::file_operations { + open: Some(fops_open::), + release: Some(fops_release::), + mmap: maybe_fn(T::HAS_MMAP, fops_mmap::), + llseek: maybe_fn(T::HAS_LLSEEK, fops_llseek::), + read_iter: maybe_fn(T::HAS_READ_ITER, fops_read_iter::), + unlocked_ioctl: maybe_fn(T::HAS_IOCTL, fops_ioctl::), + #[cfg(CONFIG_COMPAT)] + compat_ioctl: maybe_fn(T::HAS_IOCTL || T::HAS_COMPAT_IOCTL, fops_compat_ioctl::), + ..unsafe { MaybeUninit::zeroed().assume_init() } + }; + } + + &VtableHelper::::VTABLE +} + +unsafe extern "C" fn fops_open( + inode: *mut bindings::inode, + file: *mut bindings::file, +) -> c_int { + // SAFETY: The pointers are valid and for a file being opened. + let ret = unsafe { bindings::generic_file_open(inode, file) }; + if ret != 0 { + return ret; + } + + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let ptr = match T::open(unsafe { File::from_raw_file(file) }) { + Ok(ptr) => ptr, + Err(err) => return err.to_errno(), + }; + + // SAFETY: The open call of a file owns the private data. + unsafe { (*file).private_data = ptr.into_foreign().cast_mut() }; + + 0 +} + +unsafe extern "C" fn fops_release( + _inode: *mut bindings::inode, + file: *mut bindings::file, +) -> c_int { + // SAFETY: The release call of a file owns the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: We are taking ownership of the private data, so we can drop it. + let ptr = unsafe { ::from_foreign(private) }; + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + T::release(ptr, unsafe { File::from_raw_file(file) }); + + 0 +} + +unsafe extern "C" fn fops_mmap( + file: *mut bindings::file, + vma: *mut bindings::vm_area_struct, +) -> c_int { + // SAFETY: The release call of a file owns the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Ioctl calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let file = unsafe { File::from_raw_file(file) }; + // SAFETY: The caller ensures that the vma is valid. + let area = unsafe { kernel::mm::virt::VmArea::from_raw_mut(vma) }; + + match T::mmap(device, file, area) { + Ok(()) => 0, + Err(err) => err.to_errno() as c_int, + } +} + +unsafe extern "C" fn fops_llseek( + file: *mut bindings::file, + offset: loff_t, + whence: c_int, +) -> loff_t { + // SAFETY: The release call of a file owns the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Ioctl calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + // SAFETY: + // * The file is valid for the duration of this call. + // * We are inside an fdget_pos region, so there cannot be any active fdget_pos regions on + // other threads. + let file = unsafe { LocalFile::from_raw_file(file) }; + + match T::llseek(device, file, offset, whence) { + Ok(res) => res as loff_t, + Err(err) => err.to_errno() as loff_t, + } +} + +unsafe extern "C" fn fops_read_iter( + kiocb: *mut bindings::kiocb, + iter: *mut bindings::iov_iter, +) -> isize { + let kiocb = Kiocb { + inner: unsafe { NonNull::new_unchecked(kiocb) }, + _phantom: PhantomData, + }; + let iov = unsafe { &mut *iter.cast::() }; + + match T::read_iter(kiocb, iov) { + Ok(res) => res as isize, + Err(err) => err.to_errno() as isize, + } +} + +unsafe extern "C" fn fops_ioctl( + file: *mut bindings::file, + cmd: c_uint, + arg: c_ulong, +) -> c_long { + // SAFETY: The release call of a file owns the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Ioctl calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let file = unsafe { File::from_raw_file(file) }; + + match T::ioctl(device, file, cmd as u32, arg as usize) { + Ok(ret) => ret, + Err(err) => err.to_errno() as c_long, + } +} + +#[cfg(CONFIG_COMPAT)] +unsafe extern "C" fn fops_compat_ioctl( + file: *mut bindings::file, + cmd: c_uint, + arg: c_ulong, +) -> c_long { + // SAFETY: The release call of a file owns the private data. + let private = unsafe { (*file).private_data }; + // SAFETY: Ioctl calls can borrow the private data of the file. + let device = unsafe { ::borrow(private) }; + // SAFETY: + // * The file is valid for the duration of this call. + // * There is no active fdget_pos region on the file on this thread. + let file = unsafe { File::from_raw_file(file) }; + + match T::compat_ioctl(device, file, cmd as u32, arg as usize) { + Ok(ret) => ret, + Err(err) => err.to_errno() as c_long, + } +}