From nobody Mon Feb 9 15:09:59 2026 Received: from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) (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 1AA3C257448 for ; Thu, 1 Jan 2026 05:21:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767244916; cv=none; b=Gjf+EhJqGQpTn3+GGSLgH3Mkg2PcAixXURhvqhceEoYGjAd0kiVUO/KrJ3g5DT5dhlSTrarXrIcQfXltl8RUQ1dUjHObFnvPL/LUfpPWGyTajuYwufJ0DBu8I50883NEhj2+P0bdyDdJP90rOBq0wkqY07HF+s/ytwofaGVfMU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767244916; c=relaxed/simple; bh=7rhNZKoiKt69rXYOx/nPj8NyhjOaV5my4mHPW2W+MJo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=X8V+cj0cjeKOUoNSBu3f9A+KMM+F3pxcIulOEThIr67U9YhflbwDbkBB02SXRwkj/x50j7ejw5dTn8E8o++hw61PedZBn3/rCABSEfrZhhMEwurJWJE+mmemN7aFLCjTD5GyqyvJNgLdALOR7apWLG+69EbNljXACYzYXPt/Fog= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lr2pmb9f; arc=none smtp.client-ip=209.85.208.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lr2pmb9f" Received: by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-37b95f87d64so88017351fa.2 for ; Wed, 31 Dec 2025 21:21:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767244911; x=1767849711; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ZnWuhRewCBtlepNlYLvDYAkJsMsIyPpraMiTNGgUITs=; b=lr2pmb9fBA3ugs/QR3Y2DjR/7jhhFex3Bml0m8fWx3JIlEE/Naj4CCVxWlbFOY5qSf 4xsINTZRn4KBLoC6EWlnV/FJdu+6fNEbdvkPPpwPMYWa+LKygDQK2iWWV9FVWg+RQgtx 2bWp5goviPCxIL9+m2T6KC4zxzmvi6kIQGreyl3kD2kDWjHEjZr1+TBU6rjBaCmU4Zrk oFkxvaaooR7/DOjrZmPFHWEmow+5xJLqXjQT9NHsMWdAX34K8fiMfI2AO6n6yoWLVNsD DVMi360hK39YLVb8Oo88j+nlXyvZh3yeOlQtuUsmBFfd7ubmHBvukKn/QdrbVxT7VunQ 5fdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767244911; x=1767849711; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ZnWuhRewCBtlepNlYLvDYAkJsMsIyPpraMiTNGgUITs=; b=XPm2dKOEG5BJ5qGnraDeICucgSL6fwavjm9rBhTuP5spj1J4brKlthVdLnzQomfQj6 my3AsyFCI9+cpL/GvR0PV76NrR0RzvP3+nXGXsObGBJ0W1HQ9SjMQhy+YRpGCWxgko3m J/IziP1jwbOeRgIIsjtKX4UboY43dhZVB26b0jI7gCWWNG3DqfjdMLfFd/4HMmT2guyk HOJnHPZr/aUw6Ppz2HizINhMe74knytC4lZW+PEgS8s/h1TN1QQeVtHIDE6Hll5irht+ XjdyNfFnVnqgaoX4CiYosUutSOLEZNw9CHAod0+2JnBMQCBLrurqisXbg31mJW4cihLd ouxw== X-Forwarded-Encrypted: i=1; AJvYcCXW+tZmFMmTtQMuxXL2Y1h1ZHCE8VhoDVkf56zCL4Xxe0Oj3i+hf0u7Itgelo7+kplJcps9oF6L9RHy1Bk=@vger.kernel.org X-Gm-Message-State: AOJu0YxNNVCeG4jNNOkzPNlQ+NHZlfdrbyZq4OM7GNmfAl4m3cK57HX/ OTmRvZVIINu1UaCFlsDMllcHP3cGBSerRAWPrRMZN1EmsbjeLgyxM3Gf X-Gm-Gg: AY/fxX44iOe5QTITCO3nF2Hhd/T724pltIP+8Yk/ewn+kOj8pcn4dqo0jMvY/UCOubd SxUhbAuY2SQJFJz79LPdkKh6zkqFFs6PbVLMMWX990QEZ7+VWlURnXZSmhWITzlkTgehl6lq27K n3wfsQzWwhJjMBqw7vuk0zl7fFm1v9RyC3CnO8MYMgCjZ1fmI3fmPlZEBTKhntDZpXJfRiCIHRF 6ShQTT3EBdWe5dKVee7zSyki/t0Fk25eo5S1Q7Ewh9pv/wvCDPVueTBNemC7w3u9Mt9AWbNCGCp W7YmKsX5R2ItrtxoWFy8AWZXzxzQGHiJhGvZ6H01mKw1aHTnajYAQDT8wxeAjREqi+BRZ/UepqU Nzvu+HrfvkFt9H+TMUMsP7Bfj09/CXjQPkg7jG3OhGCgqPrJ2ElIwc5SUccvGrMjKMkhJ5umYr1 aJXVhmYRSwXkS/YF64Luas5rLBWef/cv0ZZRihmbg7MaAZYRQs5veRvG1Lkzs0URyvN3nJT3+rg W025C/y8qXlyeX1 X-Google-Smtp-Source: AGHT+IGWnxKTzBFDRvVhBJLkPNrg5zCvovKVt3Iq5ajcHW0NwDfpLyHHuTaAQOvw6Ai3P24W4z2g9Q== X-Received: by 2002:a05:651c:1443:b0:382:4d6b:993b with SMTP id 38308e7fff4ca-3824d6b9c18mr83313231fa.35.1767244910574; Wed, 31 Dec 2025 21:21:50 -0800 (PST) Received: from LT-5CG5341NQ4.nordic.imtech.com (84-253-216-54.bb.dnainternet.fi. [84.253.216.54]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-382861ef4ccsm37064921fa.23.2025.12.31.21.21.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Dec 2025 21:21:48 -0800 (PST) From: Kari Argillander Date: Thu, 01 Jan 2026 07:20:49 +0200 Subject: [PATCH RFC 5/6] rust: debugfs: WIP: Use owner for file_operations Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260101-this_module_fix-v1-5-46ae3e5605a0@gmail.com> References: <20260101-this_module_fix-v1-0-46ae3e5605a0@gmail.com> In-Reply-To: <20260101-this_module_fix-v1-0-46ae3e5605a0@gmail.com> To: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Alexandre Courbot Cc: Greg Kroah-Hartman , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen , Aaron Tomlin , Jens Axboe , Kari Argillander , Andreas Hindborg X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1767244881; l=16426; i=kari.argillander@gmail.com; s=20251219; h=from:subject:message-id; bh=7rhNZKoiKt69rXYOx/nPj8NyhjOaV5my4mHPW2W+MJo=; b=/FHxPndxLye7RpOlj19HW54w3416yImg7K+iPDUzBUCprQvFxJNDtczJD3uQwfT7CmWNxIUe6 6iglF8d4oCDCqSX4wSpusPl5a2PMwxaVFMFe5smUbzFzPC75Rg8FCPo X-Developer-Key: i=kari.argillander@gmail.com; a=ed25519; pk=RwSxyhTpE3z4sywdDbIkC3q33ZQLNyhYWxT44iTY6r4= --- rust/kernel/debugfs.rs | 79 ++++++++++++++++++++++---------------= ---- rust/kernel/debugfs/file_ops.rs | 50 +++++++++++++++++++------- samples/rust/rust_debugfs.rs | 6 ++-- 3 files changed, 83 insertions(+), 52 deletions(-) diff --git a/rust/kernel/debugfs.rs b/rust/kernel/debugfs.rs index facad81e8290..03e22b1cfa2b 100644 --- a/rust/kernel/debugfs.rs +++ b/rust/kernel/debugfs.rs @@ -6,7 +6,8 @@ //! C header: [`include/linux/debugfs.h`](srctree/include/linux/debugfs.h) =20 // When DebugFS is disabled, many parameters are dead. Linting for this is= n't helpful. -#![cfg_attr(not(CONFIG_DEBUG_FS), allow(unused_variables))] +// #![cfg_attr(not(CONFIG_DEBUG_FS), allow(unused_variables))] +#![allow(unused_variables)] =20 use crate::fmt; use crate::prelude::*; @@ -46,27 +47,31 @@ // able to refer to us. In this case, we need to silently fail. All future= child directories/files // will silently fail as well. #[derive(Clone)] -pub struct Dir(#[cfg(CONFIG_DEBUG_FS)] Option>>); +pub struct Dir( + #[cfg(CONFIG_DEBUG_FS)] Option>>, + PhantomData, +); =20 -impl Dir { +impl Dir { /// Create a new directory in DebugFS. If `parent` is [`None`], it wil= l be created at the root. - fn create(name: &CStr, parent: Option<&Dir>) -> Self { + fn create(name: &CStr, parent: Option<&Self>) -> Self { #[cfg(CONFIG_DEBUG_FS)] { let parent_entry =3D match parent { // If the parent couldn't be allocated, just early-return - Some(Dir(None)) =3D> return Self(None), - Some(Dir(Some(entry))) =3D> Some(entry.clone()), + Some(Self(None, _)) =3D> return Self(None, PhantomData), + Some(Self(Some(entry), _)) =3D> Some(entry.clone()), None =3D> None, }; Self( // If Arc creation fails, the `Entry` will be dropped, so = the directory will be // cleaned up. Arc::new(Entry::dynamic_dir(name, parent_entry), GFP_KERNE= L).ok(), + PhantomData, ) } #[cfg(not(CONFIG_DEBUG_FS))] - Self() + Self(PhantomData) } =20 /// Creates a DebugFS file which will own the data produced by the ini= tializer provided in @@ -107,7 +112,7 @@ fn create_file<'a, T, E: 'a>( /// let debugfs =3D Dir::new(c_str!("parent")); /// ``` pub fn new(name: &CStr) -> Self { - Dir::create(name, None) + Self::create(name, None) } =20 /// Creates a subdirectory within this directory. @@ -121,7 +126,7 @@ pub fn new(name: &CStr) -> Self { /// let child =3D parent.subdir(c_str!("child")); /// ``` pub fn subdir(&self, name: &CStr) -> Self { - Dir::create(name, Some(self)) + Self::create(name, Some(self)) } =20 /// Creates a read-only file in this directory. @@ -149,7 +154,7 @@ pub fn read_only_file<'a, T, E: 'a>( where T: Writer + Send + Sync + 'static, { - let file_ops =3D &>::FILE_OPS; + let file_ops =3D &>::FILE_OPS; self.create_file(name, data, file_ops) } =20 @@ -176,7 +181,7 @@ pub fn read_binary_file<'a, T, E: 'a>( where T: BinaryWriter + Send + Sync + 'static, { - self.create_file(name, data, &T::FILE_OPS) + self.create_file(name, data, &>::FILE_OP= S) } =20 /// Creates a read-only file in this directory, with contents from a c= allback. @@ -215,7 +220,7 @@ pub fn read_callback_file<'a, T, E: 'a, F>( T: Send + Sync + 'static, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, { - let file_ops =3D >::FILE_OPS.adapt(); + let file_ops =3D as ReadFile>>::FILE_OPS.adapt(); self.create_file(name, data, file_ops) } =20 @@ -231,7 +236,7 @@ pub fn read_write_file<'a, T, E: 'a>( where T: Writer + Reader + Send + Sync + 'static, { - let file_ops =3D &>::FILE_OPS; + let file_ops =3D &>::FILE_OPS; self.create_file(name, data, file_ops) } =20 @@ -247,7 +252,7 @@ pub fn read_write_binary_file<'a, T, E: 'a>( where T: BinaryWriter + BinaryReader + Send + Sync + 'static, { - let file_ops =3D &>::FILE_OPS; + let file_ops =3D &>::FILE_OPS; self.create_file(name, data, file_ops) } =20 @@ -270,7 +275,7 @@ pub fn read_write_callback_file<'a, T, E: 'a, F, W>( W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { let file_ops =3D - , W> as file_ops::ReadWrit= eFile<_>>::FILE_OPS + , W> as file_ops::ReadWrit= eFile>::FILE_OPS .adapt() .adapt(); self.create_file(name, data, file_ops) @@ -290,7 +295,7 @@ pub fn write_only_file<'a, T, E: 'a>( where T: Reader + Send + Sync + 'static, { - self.create_file(name, data, &T::FILE_OPS) + self.create_file(name, data, &>::FILE_OPS) } =20 /// Creates a write-only binary file in this directory. @@ -307,7 +312,7 @@ pub fn write_binary_file<'a, T, E: 'a>( where T: BinaryReader + Send + Sync + 'static, { - self.create_file(name, data, &T::FILE_OPS) + self.create_file(name, data, &>::FILE_O= PS) } =20 /// Creates a write-only file in this directory, with write logic from= a callback. @@ -324,7 +329,7 @@ pub fn write_callback_file<'a, T, E: 'a, W>( T: Send + Sync + 'static, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { - let file_ops =3D , W> as WriteFile<_>>= ::FILE_OPS + let file_ops =3D , W> as WriteFile>::FILE_OPS .adapt() .adapt(); self.create_file(name, data, file_ops) @@ -527,7 +532,7 @@ fn create_file(&self, name: &CStr, data: &'dat= a T, vtable: &'static Fil /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn read_only_file(&self, name: = &CStr, data: &'data T) { - self.create_file(name, data, &T::FILE_OPS) + // self.create_file(name, data, &>::FILE_OPS) } =20 /// Creates a read-only binary file in this directory. @@ -541,7 +546,7 @@ pub fn read_binary_file>::FILE_OPS) } =20 /// Creates a read-only file in this directory, with contents from a c= allback. @@ -560,8 +565,8 @@ pub fn read_callback_file(&self, name: &CStr, dat= a: &'data T, _f: &'static T: Send + Sync + 'static, F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, { - let vtable =3D as ReadFile<_>>::FILE_OPS.adap= t(); - self.create_file(name, data, vtable) + // let vtable =3D as ReadFile>::FILE_OP= S.adapt(); + // self.create_file(name, data, vtable) } =20 /// Creates a read-write file in this directory. @@ -577,8 +582,8 @@ pub fn read_write_file( name: &CStr, data: &'data T, ) { - let vtable =3D &>::FILE_OPS; - self.create_file(name, data, vtable) + // let vtable =3D &>::FILE_OPS; + // self.create_file(name, data, vtable) } =20 /// Creates a read-write binary file in this directory. @@ -593,8 +598,8 @@ pub fn read_write_binary_file>::FILE_OPS; - self.create_file(name, data, vtable) + // let vtable =3D &>::FILE_OPS; + // self.create_file(name, data, vtable) } =20 /// Creates a read-write file in this directory, with logic from callb= acks. @@ -618,10 +623,10 @@ pub fn read_write_callback_file( F: Fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result + Send + Sync, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { - let vtable =3D , W> as ReadWri= teFile<_>>::FILE_OPS - .adapt() - .adapt(); - self.create_file(name, data, vtable) + // let vtable =3D , W> as Read= WriteFile<_>>::FILE_OPS + // .adapt() + // .adapt(); + // self.create_file(name, data, vtable) } =20 /// Creates a write-only file in this directory. @@ -632,8 +637,8 @@ pub fn read_write_callback_file( /// file is removed when the [`Scope`] that this directory belongs /// to is dropped. pub fn write_only_file(&self, name:= &CStr, data: &'data T) { - let vtable =3D &>::FILE_OPS; - self.create_file(name, data, vtable) + // let vtable =3D &>::FILE_OPS; + // self.create_file(name, data, vtable) } =20 /// Creates a write-only binary file in this directory. @@ -647,7 +652,7 @@ pub fn write_binary_file( name: &CStr, data: &'data T, ) { - self.create_file(name, data, &T::FILE_OPS) + // self.create_file(name, data, &>::FILE_OPS) } =20 /// Creates a write-only file in this directory, with write logic from= a callback. @@ -665,10 +670,10 @@ pub fn write_only_callback_file(&self, name: &C= Str, data: &'data T, _w: &' T: Send + Sync + 'static, W: Fn(&T, &mut UserSliceReader) -> Result + Send + Sync, { - let vtable =3D &, W> as WriteFile<_>>:= :FILE_OPS - .adapt() - .adapt(); - self.create_file(name, data, vtable) + // let vtable =3D &, W> as WriteFile<_= >>::FILE_OPS + // .adapt() + // .adapt(); + // self.create_file(name, data, vtable) } =20 fn empty() -> Self { diff --git a/rust/kernel/debugfs/file_ops.rs b/rust/kernel/debugfs/file_ops= .rs index 8a0442d6dd7a..0e5059c044af 100644 --- a/rust/kernel/debugfs/file_ops.rs +++ b/rust/kernel/debugfs/file_ops.rs @@ -115,13 +115,14 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Res= ult { } =20 // Work around lack of generic const items. -pub(crate) trait ReadFile { +pub(crate) trait ReadFile { const FILE_OPS: FileOps; } =20 -impl ReadFile for T { +impl ReadFile for T { const FILE_OPS: FileOps =3D { let operations =3D bindings::file_operations { + owner: M::OWNER.as_ptr(), read: Some(bindings::seq_read), llseek: Some(bindings::seq_lseek), release: Some(bindings::single_release), @@ -167,13 +168,18 @@ fn read(data: &T, buf: *const c_cha= r, count: usize) -> isize { } =20 // A trait to get the file operations for a type. -pub(crate) trait ReadWriteFile { +pub(crate) trait ReadWriteFile { const FILE_OPS: FileOps; } =20 -impl ReadWriteFile for T { +impl ReadWriteFile for T +where + M: ThisModule, + T: Writer + Reader + Sync, +{ const FILE_OPS: FileOps =3D { let operations =3D bindings::file_operations { + owner: M::OWNER.as_ptr(), open: Some(writer_open::), read: Some(bindings::seq_read), write: Some(write::), @@ -225,13 +231,18 @@ impl ReadWriteFile for = T { read(data, buf, count) } =20 -pub(crate) trait WriteFile { +pub(crate) trait WriteFile { const FILE_OPS: FileOps; } =20 -impl WriteFile for T { +impl WriteFile for T +where + M: ThisModule, + T: Reader + Sync, +{ const FILE_OPS: FileOps =3D { let operations =3D bindings::file_operations { + owner: M::OWNER.as_ptr(), open: Some(write_only_open), write: Some(write_only_write::), llseek: Some(bindings::noop_llseek), @@ -278,13 +289,18 @@ extern "C" fn blob_read( } =20 /// Representation of [`FileOps`] for read only binary files. -pub(crate) trait BinaryReadFile { +pub(crate) trait BinaryReadFile { const FILE_OPS: FileOps; } =20 -impl BinaryReadFile for T { +impl BinaryReadFile for T +where + M: ThisModule, + T: BinaryWriter + Sync, +{ const FILE_OPS: FileOps =3D { let operations =3D bindings::file_operations { + owner: M::OWNER.as_ptr(), read: Some(blob_read::), llseek: Some(bindings::default_llseek), open: Some(bindings::simple_open), @@ -333,13 +349,18 @@ extern "C" fn blob_write( } =20 /// Representation of [`FileOps`] for write only binary files. -pub(crate) trait BinaryWriteFile { +pub(crate) trait BinaryWriteFile { const FILE_OPS: FileOps; } =20 -impl BinaryWriteFile for T { +impl BinaryWriteFile for T +where + M: ThisModule, + T: BinaryReader + Sync, +{ const FILE_OPS: FileOps =3D { let operations =3D bindings::file_operations { + owner: M::OWNER.as_ptr(), write: Some(blob_write::), llseek: Some(bindings::default_llseek), open: Some(bindings::simple_open), @@ -358,13 +379,18 @@ impl BinaryWriteFile for T= { } =20 /// Representation of [`FileOps`] for read/write binary files. -pub(crate) trait BinaryReadWriteFile { +pub(crate) trait BinaryReadWriteFile { const FILE_OPS: FileOps; } =20 -impl BinaryReadWriteFile for T { +impl BinaryReadWriteFile for T +where + M: ThisModule, + T: BinaryWriter + BinaryReader + Sync, +{ const FILE_OPS: FileOps =3D { let operations =3D bindings::file_operations { + owner: M::OWNER.as_ptr(), read: Some(blob_read::), write: Some(blob_write::), llseek: Some(bindings::default_llseek), diff --git a/samples/rust/rust_debugfs.rs b/samples/rust/rust_debugfs.rs index 025e8f9d12de..85c3f93159fd 100644 --- a/samples/rust/rust_debugfs.rs +++ b/samples/rust/rust_debugfs.rs @@ -54,7 +54,7 @@ struct RustDebugFs { pdev: ARef, // As we only hold these for drop effect (to remove the directory/file= s) we have a leading // underscore to indicate to the compiler that we don't expect to use = this field directly. - _debugfs: Dir, + _debugfs: Dir, #[pin] _compatible: File, #[pin] @@ -124,11 +124,11 @@ fn probe( } =20 impl RustDebugFs { - fn build_counter(dir: &Dir) -> impl PinInit>> + '_ { + fn build_counter(dir: &Dir) -> impl PinInit>> + '_ { dir.read_write_file(c_str!("counter"), Atomic::::new(0)) } =20 - fn build_inner(dir: &Dir) -> impl PinInit>> + '_ { + fn build_inner(dir: &Dir) -> impl PinInit>> + '_ { dir.read_write_file(c_str!("pair"), new_mutex!(Inner { x: 3, y: 10= })) } =20 --=20 2.43.0