From patchwork Wed Jul 26 16:45:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328371 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B65EEC001DC for ; Wed, 26 Jul 2023 16:47:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231656AbjGZQrn (ORCPT ); Wed, 26 Jul 2023 12:47:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231364AbjGZQrj (ORCPT ); Wed, 26 Jul 2023 12:47:39 -0400 Received: from aer-iport-5.cisco.com (aer-iport-5.cisco.com [173.38.203.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CBE12712 for ; Wed, 26 Jul 2023 09:47:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=4965; q=dns/txt; s=iport; t=1690390032; x=1691599632; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=i/lTVDEDYHsEdChSzawXjVr0aEd2CSBfkYp/e9QDjEg=; b=mUQ/xUq4eVO3OvopZC66mU5sZHKkxUHRKKjv5JlWWQ9H6L6KkngM/uog 0t1eDl1B4WOZL2vwlHWYZiI5zfoAF5jqqL6cKdiox5WBdhSFSJNlk1JBE QBwV0REeVyoSm3EP8C+li6OnZg00hVNpQH8bllawuACDte3GgfPzvmqcZ w=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="5874456" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-5.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:04 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTr022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:04 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 01/10] samples: puzzlefs: add initial puzzlefs sample, copied from rust_fs.rs Date: Wed, 26 Jul 2023 19:45:25 +0300 Message-ID: <20230726164535.230515-2-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Signed-off-by: Ariel Miculas --- samples/rust/Kconfig | 10 ++++ samples/rust/Makefile | 1 + samples/rust/puzzlefs.rs | 105 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 samples/rust/puzzlefs.rs diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index 2bd736f99189..05ca21fbba06 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -40,6 +40,16 @@ config SAMPLE_RUST_FS If unsure, say N. +config SAMPLE_PUZZLEFS + tristate "Puzzlefs file system" + help + This option builds the Rust puzzlefs file system sample. + + To compile this as a module, choose M here: + the module will be called puzzlefs. + + If unsure, say N. + config SAMPLE_RUST_HOSTPROGS bool "Host programs" help diff --git a/samples/rust/Makefile b/samples/rust/Makefile index e5941037e673..364a38dbf90b 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -3,5 +3,6 @@ obj-$(CONFIG_SAMPLE_RUST_MINIMAL) += rust_minimal.o obj-$(CONFIG_SAMPLE_RUST_PRINT) += rust_print.o obj-$(CONFIG_SAMPLE_RUST_FS) += rust_fs.o +obj-$(CONFIG_SAMPLE_PUZZLEFS) += puzzlefs.o subdir-$(CONFIG_SAMPLE_RUST_HOSTPROGS) += hostprogs diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs new file mode 100644 index 000000000000..0cf42762e81a --- /dev/null +++ b/samples/rust/puzzlefs.rs @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust file system sample. + +use kernel::module_fs; +use kernel::prelude::*; +use kernel::{c_str, file, fs, io_buffer::IoBufferWriter}; + +module_fs! { + type: PuzzleFsModule, + name: "puzzlefs", + author: "Ariel Miculas", + license: "GPL", +} + +struct PuzzleFsModule; + +#[vtable] +impl fs::Context for PuzzleFsModule { + type Data = (); + + kernel::define_fs_params! {(), + {flag, "flag", |_, v| { pr_info!("flag passed-in: {v}\n"); Ok(()) } }, + {flag_no, "flagno", |_, v| { pr_info!("flagno passed-in: {v}\n"); Ok(()) } }, + {bool, "bool", |_, v| { pr_info!("bool passed-in: {v}\n"); Ok(()) } }, + {u32, "u32", |_, v| { pr_info!("u32 passed-in: {v}\n"); Ok(()) } }, + {u32oct, "u32oct", |_, v| { pr_info!("u32oct passed-in: {v}\n"); Ok(()) } }, + {u32hex, "u32hex", |_, v| { pr_info!("u32hex passed-in: {v}\n"); Ok(()) } }, + {s32, "s32", |_, v| { pr_info!("s32 passed-in: {v}\n"); Ok(()) } }, + {u64, "u64", |_, v| { pr_info!("u64 passed-in: {v}\n"); Ok(()) } }, + {string, "string", |_, v| { pr_info!("string passed-in: {v}\n"); Ok(()) } }, + {enum, "enum", [("first", 10), ("second", 20)], |_, v| { + pr_info!("enum passed-in: {v}\n"); Ok(()) } + }, + } + + fn try_new() -> Result { + Ok(()) + } +} + +impl fs::Type for PuzzleFsModule { + type Context = Self; + type INodeData = &'static [u8]; + const SUPER_TYPE: fs::Super = fs::Super::Independent; + const NAME: &'static CStr = c_str!("puzzlefs"); + const FLAGS: i32 = fs::flags::USERNS_MOUNT; + const DCACHE_BASED: bool = true; + + fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock> { + let sb = sb.init( + (), + &fs::SuperParams { + magic: 0x72757374, + ..fs::SuperParams::DEFAULT + }, + )?; + let root = sb.try_new_populated_root_dentry( + &[], + kernel::fs_entries![ + file("test1", 0o600, "abc\n".as_bytes(), FsFile), + file("test2", 0o600, "def\n".as_bytes(), FsFile), + char("test3", 0o600, [].as_slice(), (10, 125)), + sock("test4", 0o755, [].as_slice()), + fifo("test5", 0o755, [].as_slice()), + block("test6", 0o755, [].as_slice(), (1, 1)), + dir( + "dir1", + 0o755, + [].as_slice(), + [ + file("test1", 0o600, "abc\n".as_bytes(), FsFile), + file("test2", 0o600, "def\n".as_bytes(), FsFile), + ] + ), + ], + )?; + let sb = sb.init_root(root)?; + Ok(sb) + } +} + +struct FsFile; + +#[vtable] +impl file::Operations for FsFile { + type OpenData = &'static [u8]; + + fn open(_context: &Self::OpenData, _file: &file::File) -> Result { + Ok(()) + } + + fn read( + _data: (), + file: &file::File, + writer: &mut impl IoBufferWriter, + offset: u64, + ) -> Result { + file::read_from_slice( + file.inode::().ok_or(EINVAL)?.fs_data(), + writer, + offset, + ) + } +} From patchwork Wed Jul 26 16:45:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328372 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26F1DC001B0 for ; Wed, 26 Jul 2023 16:47:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231512AbjGZQrq (ORCPT ); Wed, 26 Jul 2023 12:47:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231172AbjGZQrp (ORCPT ); Wed, 26 Jul 2023 12:47:45 -0400 Received: from aer-iport-6.cisco.com (aer-iport-6.cisco.com [173.38.203.68]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92CA8270B for ; Wed, 26 Jul 2023 09:47:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=576; q=dns/txt; s=iport; t=1690390036; x=1691599636; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UnLNYfFO6tQLV/Mk+1rvunpJiCcagHvFt3GyP/A8BGs=; b=cdaKo1kajLAMXci1HocfMc1X5g7exk5+UWekseQBiTRQGipbEdTAHUpg u9QM806Z1Y3QwIln6+spUexZ88Rvk7EVWEHeNE3LIojbXMgWXGeAr2hCm rjhhyK3MVd8eGKTc+E1nRzj6mPRhwi2EK9nIZc2RvlIMcgV0eRYm/JyIA g=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="6049462" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-6.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:11 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTs022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:10 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 02/10] kernel: configs: enable rust samples in rust.config Date: Wed, 26 Jul 2023 19:45:26 +0300 Message-ID: <20230726164535.230515-3-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Signed-off-by: Ariel Miculas --- kernel/configs/rust.config | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/kernel/configs/rust.config b/kernel/configs/rust.config index 38a7c5362c9c..63798ae5f3a5 100644 --- a/kernel/configs/rust.config +++ b/kernel/configs/rust.config @@ -1 +1,11 @@ CONFIG_RUST=y + +CONFIG_MODULES=y +CONFIG_SAMPLES=y +CONFIG_SAMPLES_RUST=y +CONFIG_SAMPLE_RUST_MINIMAL=m +CONFIG_SAMPLE_RUST_PRINT=m +CONFIG_SAMPLE_RUST_FS=m +CONFIG_SAMPLE_PUZZLEFS=y +CONFIG_SAMPLE_RUST_HOSTPROGS=y + From patchwork Wed Jul 26 16:45:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328373 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E6E2C001B0 for ; Wed, 26 Jul 2023 16:48:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230464AbjGZQsK (ORCPT ); Wed, 26 Jul 2023 12:48:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231172AbjGZQrq (ORCPT ); Wed, 26 Jul 2023 12:47:46 -0400 Received: from aer-iport-1.cisco.com (aer-iport-1.cisco.com [173.38.203.51]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B5C9D2721 for ; Wed, 26 Jul 2023 09:47:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=3780; q=dns/txt; s=iport; t=1690390037; x=1691599637; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oseE7dVa4mchfbI4MxCXhpXz3QIa6pI8ihSwsEe0lxw=; b=c1w61NdN6uS5MvvQ8fuARJ5FYk1DVc8uldv4MbIMTDXXsldufY90gmTx rShY56YGD7nSfraqNSiys6fNtV9uPqHaIaLmuhkJXHuUsd3sNqVhDETDG py8tXlOAilIN8VtbsuN4um/JcDxRXRM+9gPjNNe0OwMuaIt6b3Gfy1gPu g=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="8452801" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-1.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:12 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTt022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:12 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 03/10] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount Date: Wed, 26 Jul 2023 19:45:27 +0300 Message-ID: <20230726164535.230515-4-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Signed-off-by: Ariel Miculas --- rust/bindings/bindings_helper.h | 1 + rust/kernel/lib.rs | 1 + rust/kernel/mount.rs | 71 +++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 rust/kernel/mount.rs diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h index e5fc3b1d408d..205ef50dfd4c 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -18,6 +18,7 @@ #include #include #include +#include /* `bindgen` gets confused at certain things. */ const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL; diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 08f67833afcf..7dc07bdb5d55 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -46,6 +46,7 @@ pub mod ioctl; pub mod iov_iter; pub mod mm; +pub mod mount; pub mod pages; pub mod prelude; pub mod print; diff --git a/rust/kernel/mount.rs b/rust/kernel/mount.rs new file mode 100644 index 000000000000..d08830b27571 --- /dev/null +++ b/rust/kernel/mount.rs @@ -0,0 +1,71 @@ +//! Mount interface +//! +//! C headers: [`include/linux/mount.h`](../../../../include/linux/mount.h) + +use kernel::bindings; +use kernel::error::from_err_ptr; +use kernel::pr_err; +use kernel::prelude::*; +use kernel::str::CStr; +use kernel::types::Opaque; + +/// Wraps the kernel's `struct path`. +#[repr(transparent)] +pub struct Path(pub(crate) Opaque); + +/// Wraps the kernel's `struct vfsmount`. +#[repr(transparent)] +#[derive(Debug)] +pub struct Vfsmount { + vfsmount: *mut bindings::vfsmount, +} + +// SAFETY: No one besides us has the raw pointer, so we can safely transfer Vfsmount to another thread +unsafe impl Send for Vfsmount {} +// SAFETY: It's OK to access `Vfsmount` through references from other threads because we're not +// accessing any properties from the underlying raw pointer +unsafe impl Sync for Vfsmount {} + +impl Vfsmount { + /// Create a new private mount clone based on a path name + pub fn new_private_mount(path_name: &CStr) -> Result { + let path: Path = Path(Opaque::uninit()); + // SAFETY: path_name is a &CStr, so it's a valid string pointer; path is an uninitialized + // struct stored on the stack and it's ok because kern_path expects an out parameter + let err = unsafe { + bindings::kern_path( + path_name.as_ptr() as *const i8, + bindings::LOOKUP_FOLLOW | bindings::LOOKUP_DIRECTORY, + path.0.get(), + ) + }; + if err != 0 { + pr_err!("failed to resolve '{}': {}\n", path_name, err); + return Err(EINVAL); + } + + // SAFETY: path is a struct stored on the stack and it is initialized because the call to + // kern_path succeeded + let vfsmount = unsafe { from_err_ptr(bindings::clone_private_mount(path.0.get()))? }; + + // Don't inherit atime flags + // SAFETY: we called from_err_ptr so it's safe to dereference this pointer + unsafe { + (*vfsmount).mnt_flags &= + !(bindings::MNT_NOATIME | bindings::MNT_NODIRATIME | bindings::MNT_RELATIME) as i32; + } + Ok(Self { vfsmount }) + } + + /// Returns a raw pointer to vfsmount + pub fn get(&self) -> *mut bindings::vfsmount { + self.vfsmount + } +} + +impl Drop for Vfsmount { + fn drop(&mut self) { + // SAFETY new_private_mount makes sure to return a valid pointer + unsafe { bindings::kern_unmount(self.vfsmount) }; + } +} From patchwork Wed Jul 26 16:45:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328374 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6BBD6C001DF for ; Wed, 26 Jul 2023 16:48:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229548AbjGZQsL (ORCPT ); Wed, 26 Jul 2023 12:48:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231685AbjGZQrx (ORCPT ); Wed, 26 Jul 2023 12:47:53 -0400 Received: from aer-iport-8.cisco.com (aer-iport-8.cisco.com [173.38.203.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C573F2703 for ; Wed, 26 Jul 2023 09:47:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=7763; q=dns/txt; s=iport; t=1690390038; x=1691599638; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KpPr0Hy4pGpqEy0mTBFyST7zmNlk6KLH8UX7VvAwlLA=; b=HFhS/J0Htc/sn61h3X+U+gm8NDal+s/ng2smrA6WZooMUAPfuLI6wxUV mMHM5J1RQuiuk7JrZGnYwWbYhL3q169NFOg2QZkRgI/kS7pRyDtGuWisw OBdVW8TeoQBXwMlK9Nw2NrhrC8ZJ63yaO3khfCoddhH6V0yYtubznks1n c=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="5816071" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-8.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:13 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTu022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:13 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 04/10] rust: file: Add a new RegularFile newtype useful for reading files Date: Wed, 26 Jul 2023 19:45:28 +0300 Message-ID: <20230726164535.230515-5-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Implement from_path, from_path_in_root_mnt, read_with_offset, read_to_end and get_file_size methods for a RegularFile newtype. Signed-off-by: Ariel Miculas --- rust/helpers.c | 6 ++ rust/kernel/error.rs | 4 +- rust/kernel/file.rs | 129 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 135 insertions(+), 4 deletions(-) diff --git a/rust/helpers.c b/rust/helpers.c index eed8ace52fb5..9e860a554cda 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -213,6 +213,12 @@ void *rust_helper_alloc_inode_sb(struct super_block *sb, } EXPORT_SYMBOL_GPL(rust_helper_alloc_inode_sb); +loff_t rust_helper_i_size_read(const struct inode *inode) +{ + return i_size_read(inode); +} +EXPORT_SYMBOL_GPL(rust_helper_i_size_read); + /* * We use `bindgen`'s `--size_t-is-usize` option to bind the C `size_t` type * as the Rust `usize` type, so we can use it in contexts where Rust diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index 05fcab6abfe6..e061c83f806a 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -273,9 +273,7 @@ pub fn to_result(err: core::ffi::c_int) -> Result { /// } /// } /// ``` -// TODO: Remove `dead_code` marker once an in-kernel client is available. -#[allow(dead_code)] -pub(crate) fn from_err_ptr(ptr: *mut T) -> Result<*mut T> { +pub fn from_err_ptr(ptr: *mut T) -> Result<*mut T> { // CAST: Casting a pointer to `*const core::ffi::c_void` is always valid. let const_ptr: *const core::ffi::c_void = ptr.cast(); // SAFETY: The FFI function does not deref the pointer. diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index 494939ba74df..a3002c416dbb 100644 --- a/rust/kernel/file.rs +++ b/rust/kernel/file.rs @@ -8,11 +8,13 @@ use crate::{ bindings, cred::Credential, - error::{code::*, from_result, Error, Result}, + error::{code::*, from_err_ptr, from_result, Error, Result}, fs, io_buffer::{IoBufferReader, IoBufferWriter}, iov_iter::IovIter, mm, + mount::Vfsmount, + str::CStr, sync::CondVar, types::ARef, types::AlwaysRefCounted, @@ -20,6 +22,7 @@ types::Opaque, user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter}, }; +use alloc::vec::Vec; use core::convert::{TryFrom, TryInto}; use core::{marker, mem, ptr}; use macros::vtable; @@ -201,6 +204,130 @@ unsafe fn dec_ref(obj: ptr::NonNull) { } } +/// A newtype over file, specific to regular files +pub struct RegularFile(ARef); +impl RegularFile { + /// Creates a new instance of Self if the file is a regular file + /// + /// # Safety + /// + /// The caller must ensure file_ptr.f_inode is initialized to a valid pointer (e.g. file_ptr is + /// a pointer returned by path_openat); It must also ensure that file_ptr's reference count was + /// incremented at least once + fn create_if_regular(file_ptr: ptr::NonNull) -> Result { + // SAFETY: file_ptr is a NonNull pointer + let inode = unsafe { core::ptr::addr_of!((*file_ptr.as_ptr()).f_inode).read() }; + // SAFETY: the caller must ensure f_inode is initialized to a valid pointer + unsafe { + if bindings::S_IFMT & ((*inode).i_mode) as u32 != bindings::S_IFREG { + return Err(EINVAL); + } + } + // SAFETY: the safety requirements state that file_ptr's reference count was incremented at + // least once + Ok(RegularFile(unsafe { ARef::from_raw(file_ptr.cast()) })) + } + /// Constructs a new [`struct file`] wrapper from a path. + pub fn from_path(filename: &CStr, flags: i32, mode: u16) -> Result { + let file_ptr = unsafe { + // SAFETY: filename is a reference, so it's a valid pointer + from_err_ptr(bindings::filp_open( + filename.as_ptr() as *const i8, + flags, + mode, + ))? + }; + let file_ptr = ptr::NonNull::new(file_ptr).ok_or(ENOENT)?; + + // SAFETY: `filp_open` initializes the refcount with 1 + Self::create_if_regular(file_ptr) + } + + /// Constructs a new [`struct file`] wrapper from a path and a vfsmount. + pub fn from_path_in_root_mnt( + mount: &Vfsmount, + filename: &CStr, + flags: i32, + mode: u16, + ) -> Result { + let file_ptr = { + let mnt = mount.get(); + // construct a path from vfsmount, see file_open_root_mnt + let raw_path = bindings::path { + mnt, + // SAFETY: Vfsmount structure stores a valid vfsmount object + dentry: unsafe { (*mnt).mnt_root }, + }; + unsafe { + // SAFETY: raw_path and filename are both references + from_err_ptr(bindings::file_open_root( + &raw_path, + filename.as_ptr() as *const i8, + flags, + mode, + ))? + } + }; + let file_ptr = ptr::NonNull::new(file_ptr).ok_or(ENOENT)?; + + // SAFETY: `file_open_root` initializes the refcount with 1 + Self::create_if_regular(file_ptr) + } + + /// Read from the file into the specified buffer + pub fn read_with_offset(&self, buf: &mut [u8], offset: u64) -> Result { + Ok({ + // kernel_read_file expects a pointer to a "void *" buffer + let mut ptr_to_buf = buf.as_mut_ptr() as *mut core::ffi::c_void; + // Unless we give a non-null pointer to the file size: + // 1. we cannot give a non-zero value for the offset + // 2. we cannot have offset 0 and buffer_size > file_size + let mut file_size = 0; + + // SAFETY: 'file' is valid because it's taken from Self, 'buf' and 'file_size` are + // references to the stack variables 'ptr_to_buf' and 'file_size'; ptr_to_buf is also + // a pointer to a valid buffer that was obtained from a reference + let result = unsafe { + bindings::kernel_read_file( + self.0 .0.get(), + offset.try_into()?, + &mut ptr_to_buf, + buf.len(), + &mut file_size, + bindings::kernel_read_file_id_READING_UNKNOWN, + ) + }; + + // kernel_read_file returns the number of bytes read on success or negative on error. + if result < 0 { + return Err(Error::from_errno(result.try_into()?)); + } + + result.try_into()? + }) + } + + /// Allocate and return a vector containing the contents of the entire file + pub fn read_to_end(&self) -> Result> { + let file_size = self.get_file_size()?; + let mut buffer = Vec::try_with_capacity(file_size)?; + buffer.try_resize(file_size, 0)?; + self.read_with_offset(&mut buffer, 0)?; + Ok(buffer) + } + + fn get_file_size(&self) -> Result { + // SAFETY: 'file' is valid because it's taken from Self + let file_size = unsafe { bindings::i_size_read((*self.0 .0.get()).f_inode) }; + + if file_size < 0 { + return Err(EINVAL); + } + + Ok(file_size.try_into()?) + } +} + /// A file descriptor reservation. /// /// This allows the creation of a file descriptor in two steps: first, we reserve a slot for it, From patchwork Wed Jul 26 16:45:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328378 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 809B6C001B0 for ; Wed, 26 Jul 2023 16:48:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231364AbjGZQsN (ORCPT ); Wed, 26 Jul 2023 12:48:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34732 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231865AbjGZQry (ORCPT ); Wed, 26 Jul 2023 12:47:54 -0400 Received: from aer-iport-5.cisco.com (aer-iport-5.cisco.com [173.38.203.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7028A26BC for ; Wed, 26 Jul 2023 09:47:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=238319; q=dns/txt; s=iport; t=1690390040; x=1691599640; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pFuOAESAfN43fwj6WZNfdzqL/BfA1Hwzuk0CPiGbHU4=; b=epSiQN1fwYwJEKAmjky1sQWsICDVkSsWzI16G2A8+NqtRCF1HjhNMLa3 bt+t+sArRca8n0EBpTGCHkmToSNYeS2cpEB/b4Fx3bHeag8EhG9ziwjGc D+fNJ4oKC3lPQzoa8bJdXVLfJjJB43eR03bBstt9qagnBz4Ry6qAMRl+4 Y=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="5874461" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-5.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:16 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTv022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:15 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 05/10] samples: puzzlefs: add basic deserializing support for the puzzlefs metadata Date: Wed, 26 Jul 2023 19:45:29 +0300 Message-ID: <20230726164535.230515-6-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Puzzlefs uses capnproto for storing the filesystem metadata, defined in manifest.capnp and metadata.capnp. The files manifest_capnp.rs and metadata_capnp.rs were generated with (Cap'n Proto version 0.10.4): ``` capnp compile -orust manifest.capnp capnp compile -orust metadata.capnp ``` , formatted with rustfmt and I have also added the following lines: ``` ``` to avoid warnings. Ideally, manifest_capnp.rs and metadata_capnp.rs should be automatically generated at build time. However, this means the capnp binary becomes a dependency for the build and I didn't want this. Besides, the metadata schemas are not expected to change frequently, so it's acceptable to manually regenerate the two rust files when this happens. The code is adapted from the puzzlefs FUSE driver [1]. The data structures required for the filesystem metadata are defined in types.rs. Each structure has a `from_capnp` method used to convert between the capnp memory layout and the native Rust structures. This leaves room for improvement [2]. The deserializing code also uses `NoAllocBufferSegments` which is not yet merged in capnproto-rust upstream [3]. When a new release is published, then we'll be able to use capnproto-rust in the kernel with only a few patches to it. inode.rs implements the PuzzleFS structure which contains a list of metadata layers. Link: https://github.com/project-machine/puzzlefs [1] Link: https://lore.kernel.org/rust-for-linux/ZI3ZnFk2uELYFX0R@moria.home.lan/ [2] Link: https://github.com/capnproto/capnproto-rust/pull/423 [3] Signed-off-by: Ariel Miculas --- rust/kernel/error.rs | 2 +- samples/rust/puzzle.rs | 4 + samples/rust/puzzle/error.rs | 106 + samples/rust/puzzle/inode.rs | 36 + samples/rust/puzzle/types.rs | 340 ++ samples/rust/puzzle/types/manifest.capnp | 15 + samples/rust/puzzle/types/manifest_capnp.rs | 773 ++++ samples/rust/puzzle/types/metadata.capnp | 69 + samples/rust/puzzle/types/metadata_capnp.rs | 4458 +++++++++++++++++++ samples/rust/puzzlefs.rs | 4 + 10 files changed, 5806 insertions(+), 1 deletion(-) create mode 100644 samples/rust/puzzle.rs create mode 100644 samples/rust/puzzle/error.rs create mode 100644 samples/rust/puzzle/inode.rs create mode 100644 samples/rust/puzzle/types.rs create mode 100644 samples/rust/puzzle/types/manifest.capnp create mode 100644 samples/rust/puzzle/types/manifest_capnp.rs create mode 100644 samples/rust/puzzle/types/metadata.capnp create mode 100644 samples/rust/puzzle/types/metadata_capnp.rs diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs index e061c83f806a..7d25046a61b8 100644 --- a/rust/kernel/error.rs +++ b/rust/kernel/error.rs @@ -99,7 +99,7 @@ impl Error { /// /// It is a bug to pass an out-of-range `errno`. `EINVAL` would /// be returned in such a case. - pub(crate) fn from_errno(errno: core::ffi::c_int) -> Error { + pub fn from_errno(errno: core::ffi::c_int) -> Error { if errno < -(bindings::MAX_ERRNO as i32) || errno >= 0 { // TODO: Make it a `WARN_ONCE` once available. crate::pr_warn!( diff --git a/samples/rust/puzzle.rs b/samples/rust/puzzle.rs new file mode 100644 index 000000000000..a809cddfb817 --- /dev/null +++ b/samples/rust/puzzle.rs @@ -0,0 +1,4 @@ +pub(crate) mod error; +pub(crate) mod types; +pub(crate) use types::{manifest_capnp, metadata_capnp}; +pub(crate) mod inode; diff --git a/samples/rust/puzzle/error.rs b/samples/rust/puzzle/error.rs new file mode 100644 index 000000000000..d0a8112776aa --- /dev/null +++ b/samples/rust/puzzle/error.rs @@ -0,0 +1,106 @@ +use alloc::collections::TryReserveError; +use core::ffi::c_int; +use core::fmt::{self, Display}; +use kernel::prelude::EINVAL; + +pub(crate) enum WireFormatError { + InvalidSerializedData, + KernelError(kernel::error::Error), + TryReserveError(TryReserveError), + CapnpError(capnp::Error), + FromIntError(core::num::TryFromIntError), + FromSliceError(core::array::TryFromSliceError), + HexError(hex::FromHexError), +} + +impl WireFormatError { + pub(crate) fn to_errno(&self) -> c_int { + match self { + WireFormatError::InvalidSerializedData => kernel::error::Error::to_errno(EINVAL), + WireFormatError::KernelError(e) => kernel::error::Error::to_errno(*e), + WireFormatError::TryReserveError(_) => kernel::error::Error::to_errno(EINVAL), + WireFormatError::CapnpError(_) => kernel::error::Error::to_errno(EINVAL), + WireFormatError::FromIntError(_) => kernel::error::Error::to_errno(EINVAL), + WireFormatError::FromSliceError(_) => kernel::error::Error::to_errno(EINVAL), + WireFormatError::HexError(_) => kernel::error::Error::to_errno(EINVAL), + } + } + + pub(crate) fn from_errno(errno: kernel::error::Error) -> Self { + Self::KernelError(errno) + } +} + +impl Display for WireFormatError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + WireFormatError::InvalidSerializedData => f.write_str("invalid serialized data"), + WireFormatError::KernelError(e) => { + f.write_fmt(format_args!("Kernel error {}", e.to_errno())) + } + WireFormatError::TryReserveError(_) => f.write_str("TryReserveError"), + WireFormatError::CapnpError(_) => f.write_str("Capnp error"), + WireFormatError::FromIntError(_) => f.write_str("TryFromIntError"), + WireFormatError::FromSliceError(_) => f.write_str("TryFromSliceError"), + WireFormatError::HexError(_) => f.write_str("HexError"), + } + } +} + +pub(crate) type Result = kernel::error::Result; + +// TODO figure out how to use thiserror +#[allow(unused_qualifications)] +impl core::convert::From for WireFormatError { + #[allow(deprecated)] + fn from(source: kernel::error::Error) -> Self { + WireFormatError::KernelError(source) + } +} + +#[allow(unused_qualifications)] +impl core::convert::From for WireFormatError { + #[allow(deprecated)] + fn from(source: TryReserveError) -> Self { + WireFormatError::TryReserveError(source) + } +} + +#[allow(unused_qualifications)] +impl core::convert::From for WireFormatError { + #[allow(deprecated)] + fn from(source: capnp::Error) -> Self { + WireFormatError::CapnpError(source) + } +} + +#[allow(unused_qualifications)] +impl core::convert::From for WireFormatError { + #[allow(deprecated)] + fn from(source: core::array::TryFromSliceError) -> Self { + WireFormatError::FromSliceError(source) + } +} + +#[allow(unused_qualifications)] +impl core::convert::From for WireFormatError { + #[allow(deprecated)] + fn from(source: core::num::TryFromIntError) -> Self { + WireFormatError::FromIntError(source) + } +} + +impl core::convert::From for WireFormatError { + #[allow(deprecated)] + fn from(source: hex::FromHexError) -> Self { + WireFormatError::HexError(source) + } +} + +#[allow(unused_qualifications)] +impl core::convert::From for kernel::error::Error { + #[allow(deprecated)] + fn from(source: WireFormatError) -> Self { + kernel::error::Error::from_errno(source.to_errno()) + } +} diff --git a/samples/rust/puzzle/inode.rs b/samples/rust/puzzle/inode.rs new file mode 100644 index 000000000000..d792f661aa00 --- /dev/null +++ b/samples/rust/puzzle/inode.rs @@ -0,0 +1,36 @@ +// This contents of this file is taken from puzzlefs.rs (the userspace implementation) +// It is named inode.rs instead puzzlefs.rs since the root of this kernel module already has that name + +use crate::puzzle::error::Result; +use crate::puzzle::error::WireFormatError; +use crate::puzzle::types as format; +use crate::puzzle::types::{Inode, InodeMode, MetadataBlob}; +use alloc::vec::Vec; +use kernel::prelude::ENOENT; + +pub(crate) struct PuzzleFS { + layers: Vec, +} + +impl PuzzleFS { + pub(crate) fn new(md: MetadataBlob) -> Result { + let mut v = Vec::new(); + v.try_push(md)?; + Ok(PuzzleFS { layers: v }) + } + + pub(crate) fn find_inode(&self, ino: u64) -> Result { + for layer in self.layers.iter() { + if let Some(inode) = layer.find_inode(ino)? { + let inode = Inode::from_capnp(inode)?; + if let InodeMode::Wht = inode.mode { + // TODO: seems like this should really be an Option. + return Err(WireFormatError::from_errno(ENOENT)); + } + return Ok(inode); + } + } + + Err(WireFormatError::from_errno(ENOENT)) + } +} diff --git a/samples/rust/puzzle/types.rs b/samples/rust/puzzle/types.rs new file mode 100644 index 000000000000..559be491bf78 --- /dev/null +++ b/samples/rust/puzzle/types.rs @@ -0,0 +1,340 @@ +use crate::puzzle::error::Result; +use crate::puzzle::error::WireFormatError; +use alloc::vec::Vec; +use capnp::{message, serialize}; +use core::fmt; +use hex::{encode_hex_iter, FromHexError}; +use kernel::file; +use kernel::str::CStr; + +pub(crate) mod manifest_capnp; +pub(crate) mod metadata_capnp; + +pub(crate) const SHA256_BLOCK_SIZE: usize = 32; + +#[derive(Debug)] +pub(crate) struct Rootfs { + pub(crate) metadatas: Vec, + #[allow(dead_code)] + pub(crate) manifest_version: u64, +} + +impl Rootfs { + pub(crate) fn open(file: file::RegularFile) -> Result { + let manifest_buffer = file.read_to_end()?; + let message_reader = serialize::read_message_from_flat_slice_no_alloc( + &mut &manifest_buffer[..], + ::capnp::message::ReaderOptions::new(), + )?; + let rootfs = message_reader.get_root::>()?; + Self::from_capnp(rootfs) + } + + pub(crate) fn from_capnp(reader: crate::manifest_capnp::rootfs::Reader<'_>) -> Result { + let metadatas = reader.get_metadatas()?; + + let mut metadata_vec = Vec::new(); + for blobref in metadatas.iter() { + metadata_vec.try_push(BlobRef::from_capnp(blobref)?)?; + } + + Ok(Rootfs { + metadatas: metadata_vec, + manifest_version: reader.get_manifest_version(), + }) + } +} + +// TODO: should this be an ociv1 digest and include size and media type? +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct BlobRef { + pub(crate) digest: [u8; SHA256_BLOCK_SIZE], + pub(crate) offset: u64, + pub(crate) compressed: bool, +} + +impl BlobRef { + pub(crate) fn from_capnp(reader: metadata_capnp::blob_ref::Reader<'_>) -> Result { + let digest = reader.get_digest()?; + Ok(BlobRef { + digest: digest.try_into()?, + offset: reader.get_offset(), + compressed: reader.get_compressed(), + }) + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct DirEnt { + pub(crate) ino: Ino, + pub(crate) name: Vec, +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct DirList { + // TODO: flags instead? + pub(crate) look_below: bool, + pub(crate) entries: Vec, +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct FileChunk { + pub(crate) blob: BlobRef, + pub(crate) len: u64, +} + +pub(crate) type Ino = u64; + +impl FileChunk { + pub(crate) fn from_capnp(reader: metadata_capnp::file_chunk::Reader<'_>) -> Result { + let len = reader.get_len(); + let blob = BlobRef::from_capnp(reader.get_blob()?)?; + + Ok(FileChunk { blob, len }) + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct Inode { + pub(crate) ino: Ino, + pub(crate) mode: InodeMode, + pub(crate) uid: u32, + pub(crate) gid: u32, + pub(crate) permissions: u16, + pub(crate) additional: Option, +} + +impl Inode { + pub(crate) fn from_capnp(reader: metadata_capnp::inode::Reader<'_>) -> Result { + Ok(Inode { + ino: reader.get_ino(), + mode: InodeMode::from_capnp(reader.get_mode())?, + uid: reader.get_uid(), + gid: reader.get_gid(), + permissions: reader.get_permissions(), + additional: InodeAdditional::from_capnp(reader.get_additional()?)?, + }) + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum InodeMode { + Unknown, + Fifo, + Chr { major: u64, minor: u64 }, + Dir { dir_list: DirList }, + Blk { major: u64, minor: u64 }, + File { chunks: Vec }, + Lnk, + Sock, + Wht, +} + +impl InodeMode { + fn from_capnp(reader: metadata_capnp::inode::mode::Reader<'_>) -> Result { + match reader.which() { + Ok(metadata_capnp::inode::mode::Unknown(())) => Ok(InodeMode::Unknown), + Ok(metadata_capnp::inode::mode::Fifo(())) => Ok(InodeMode::Fifo), + Ok(metadata_capnp::inode::mode::Lnk(())) => Ok(InodeMode::Lnk), + Ok(metadata_capnp::inode::mode::Sock(())) => Ok(InodeMode::Sock), + Ok(metadata_capnp::inode::mode::Wht(())) => Ok(InodeMode::Wht), + Ok(metadata_capnp::inode::mode::Chr(reader)) => { + let r = reader?; + Ok(InodeMode::Chr { + major: r.get_major(), + minor: r.get_minor(), + }) + } + Ok(metadata_capnp::inode::mode::Blk(reader)) => { + let r = reader?; + Ok(InodeMode::Blk { + major: r.get_major(), + minor: r.get_minor(), + }) + } + Ok(metadata_capnp::inode::mode::File(reader)) => { + let r = reader?; + let mut chunks = Vec::new(); + for chunk in r.get_chunks()?.iter() { + chunks.try_push(FileChunk::from_capnp(chunk)?)?; + } + + Ok(InodeMode::File { chunks }) + } + Ok(metadata_capnp::inode::mode::Dir(reader)) => { + let r = reader?; + let mut entries = Vec::new(); + for entry in r.get_entries()?.iter() { + let ino = entry.get_ino(); + let dir_entry = Vec::from_iter_fallible(entry.get_name()?.iter().cloned())?; + entries.try_push(DirEnt { + ino, + name: dir_entry, + })?; + } + let look_below = r.get_look_below(); + Ok(InodeMode::Dir { + dir_list: DirList { + look_below, + entries, + }, + }) + } + Err(::capnp::NotInSchema(_e)) => Err(WireFormatError::InvalidSerializedData), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct InodeAdditional { + pub(crate) xattrs: Vec, + pub(crate) symlink_target: Option>, +} + +impl InodeAdditional { + pub(crate) fn from_capnp( + reader: metadata_capnp::inode_additional::Reader<'_>, + ) -> Result> { + if !(reader.has_xattrs() || reader.has_symlink_target()) { + return Ok(None); + } + + let mut xattrs = Vec::new(); + if reader.has_xattrs() { + for capnp_xattr in reader.get_xattrs()? { + let xattr = Xattr::from_capnp(capnp_xattr)?; + xattrs.try_push(xattr)?; + } + } + + let symlink_target = if reader.has_symlink_target() { + Some(Vec::from_iter_fallible( + reader.get_symlink_target()?.iter().cloned(), + )?) + } else { + None + }; + + Ok(Some(InodeAdditional { + xattrs, + symlink_target, + })) + } +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct Xattr { + pub(crate) key: Vec, + pub(crate) val: Vec, +} + +impl Xattr { + pub(crate) fn from_capnp(reader: metadata_capnp::xattr::Reader<'_>) -> Result { + let key = Vec::from_iter_fallible(reader.get_key()?.iter().cloned())?; + let val = Vec::from_iter_fallible(reader.get_val()?.iter().cloned())?; + Ok(Xattr { key, val }) + } +} + +pub(crate) struct MetadataBlob { + reader: message::TypedReader< + ::capnp::serialize::NoAllocBufferSegments>, + metadata_capnp::inode_vector::Owned, + >, +} + +impl MetadataBlob { + pub(crate) fn new(f: file::RegularFile) -> Result { + // We know the loaded message is safe, so we're allowing unlimited reads. + let unlimited_reads = message::ReaderOptions { + traversal_limit_in_words: None, + nesting_limit: 64, + }; + let metadata_buffer = f.read_to_end()?; + let segments = + ::capnp::serialize::NoAllocBufferSegments::try_new(metadata_buffer, unlimited_reads)?; + let reader = message::Reader::new(segments, unlimited_reads).into_typed(); + + Ok(MetadataBlob { reader }) + } + + pub(crate) fn get_inode_vector( + &self, + ) -> ::capnp::Result<::capnp::struct_list::Reader<'_, metadata_capnp::inode::Owned>> { + self.reader.get()?.get_inodes() + } + + pub(crate) fn find_inode(&self, ino: Ino) -> Result>> { + let mut left = 0; + let inodes = self.get_inode_vector()?; + let mut right = inodes.len() - 1; + + while left <= right { + let mid = left + (right - left) / 2; + let i = inodes.get(mid); + + if i.get_ino() == ino { + return Ok(Some(i)); + } + + if i.get_ino() < ino { + left = mid + 1; + } else { + // don't underflow... + if mid == 0 { + break; + } + right = mid - 1; + }; + } + + Ok(None) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct Digest([u8; SHA256_BLOCK_SIZE]); + +impl Digest { + pub(crate) fn underlying(&self) -> [u8; SHA256_BLOCK_SIZE] { + let mut dest = [0_u8; SHA256_BLOCK_SIZE]; + dest.copy_from_slice(&self.0); + dest + } +} + +impl fmt::Display for Digest { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut hex_string = + Vec::from_iter_fallible(encode_hex_iter(&self.underlying())).map_err(|_| fmt::Error)?; + // append NUL character + hex_string.try_push(0).map_err(|_| fmt::Error)?; + let hex_string = CStr::from_bytes_with_nul(&hex_string).map_err(|_| fmt::Error)?; + write!(f, "{}", hex_string) + } +} + +impl TryFrom<&CStr> for Digest { + type Error = FromHexError; + fn try_from(s: &CStr) -> kernel::error::Result { + let digest = hex::decode(s)?; + let digest: [u8; SHA256_BLOCK_SIZE] = digest + .try_into() + .map_err(|_| FromHexError::InvalidStringLength)?; + Ok(Digest(digest)) + } +} + +impl TryFrom for Digest { + type Error = WireFormatError; + fn try_from(v: BlobRef) -> kernel::error::Result { + Ok(Digest(v.digest)) + } +} + +impl TryFrom<&BlobRef> for Digest { + type Error = WireFormatError; + fn try_from(v: &BlobRef) -> kernel::error::Result { + Ok(Digest(v.digest)) + } +} diff --git a/samples/rust/puzzle/types/manifest.capnp b/samples/rust/puzzle/types/manifest.capnp new file mode 100644 index 000000000000..24d8a6f1fe19 --- /dev/null +++ b/samples/rust/puzzle/types/manifest.capnp @@ -0,0 +1,15 @@ +@0xe0b6d460b1f22bb5; + +using Metadata = import "metadata.capnp"; + +struct VerityData { + digest@0: Data; + verity@1: Data; +} + +struct Rootfs { + metadatas@0: List(Metadata.BlobRef); + fsVerityData@1: List(VerityData); + manifestVersion@2: UInt64; +} + diff --git a/samples/rust/puzzle/types/manifest_capnp.rs b/samples/rust/puzzle/types/manifest_capnp.rs new file mode 100644 index 000000000000..9ea37abfadae --- /dev/null +++ b/samples/rust/puzzle/types/manifest_capnp.rs @@ -0,0 +1,773 @@ +// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler. +// DO NOT EDIT. +// source: manifest.capnp +#![allow(unreachable_pub)] +#![allow(dead_code)] +pub mod verity_data { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_digest(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_digest(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_verity(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_verity(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 0, + pointers: 2, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_digest(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_digest(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_data(value); + } + #[inline] + pub fn init_digest(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(0).init_data(size) + } + #[inline] + pub fn has_digest(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_verity(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_verity(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(1).set_data(value); + } + #[inline] + pub fn init_verity(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(1).init_data(size) + } + #[inline] + pub fn has_verity(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 48] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(255, 223, 52, 143, 102, 148, 140, 205), + ::capnp::word(15, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(181, 43, 242, 177, 96, 212, 182, 224), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 210, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 97, 110, 105, 102, 101, 115, 116), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 86), + ::capnp::word(101, 114, 105, 116, 121, 68, 97, 116), + ::capnp::word(97, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(100, 105, 103, 101, 115, 116, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 101, 114, 105, 116, 121, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xcd8c_9466_8f34_dfff; + } +} + +pub mod rootfs { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_metadatas( + self, + ) -> ::capnp::Result<::capnp::struct_list::Reader<'a, crate::metadata_capnp::blob_ref::Owned>> + { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_metadatas(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_fs_verity_data( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Reader<'a, crate::manifest_capnp::verity_data::Owned>, + > { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_fs_verity_data(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + #[inline] + pub fn get_manifest_version(self) -> u64 { + self.reader.get_data_field::(0) + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 1, + pointers: 2, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_metadatas( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Builder<'a, crate::metadata_capnp::blob_ref::Owned>, + > { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_metadatas( + &mut self, + value: ::capnp::struct_list::Reader<'a, crate::metadata_capnp::blob_ref::Owned>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_metadatas( + self, + size: u32, + ) -> ::capnp::struct_list::Builder<'a, crate::metadata_capnp::blob_ref::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + size, + ) + } + #[inline] + pub fn has_metadatas(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_fs_verity_data( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Builder<'a, crate::manifest_capnp::verity_data::Owned>, + > { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_fs_verity_data( + &mut self, + value: ::capnp::struct_list::Reader<'a, crate::manifest_capnp::verity_data::Owned>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(1), + value, + false, + ) + } + #[inline] + pub fn init_fs_verity_data( + self, + size: u32, + ) -> ::capnp::struct_list::Builder<'a, crate::manifest_capnp::verity_data::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(1), + size, + ) + } + #[inline] + pub fn has_fs_verity_data(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + #[inline] + pub fn get_manifest_version(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_manifest_version(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 73] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(216, 230, 154, 208, 49, 166, 59, 237), + ::capnp::word(15, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(181, 43, 242, 177, 96, 212, 182, 224), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 178, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 175, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 97, 110, 105, 102, 101, 115, 116), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 82), + ::capnp::word(111, 111, 116, 102, 115, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(12, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(69, 0, 0, 0, 82, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(68, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(96, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(93, 0, 0, 0, 106, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(92, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(120, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(117, 0, 0, 0, 130, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(116, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(128, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(115, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(70, 64, 38, 97, 160, 43, 222, 175), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(102, 115, 86, 101, 114, 105, 116, 121), + ::capnp::word(68, 97, 116, 97, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(255, 223, 52, 143, 102, 148, 140, 205), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 97, 110, 105, 102, 101, 115, 116), + ::capnp::word(86, 101, 114, 115, 105, 111, 110, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 2 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1, 2]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xed3b_a631_d09a_e6d8; + } +} diff --git a/samples/rust/puzzle/types/metadata.capnp b/samples/rust/puzzle/types/metadata.capnp new file mode 100644 index 000000000000..a37bae703c72 --- /dev/null +++ b/samples/rust/puzzle/types/metadata.capnp @@ -0,0 +1,69 @@ +@0x84ae5e6e88b7cbb7; + +struct Chr { + major@0: UInt64; + minor@1: UInt64; +} + +struct DirEntry { + ino@0: UInt64; + name@1: Data; +} + +struct Dir { + entries@0: List(DirEntry); + lookBelow@1: Bool; +} + +struct Blk { + major@0: UInt64; + minor@1: UInt64; +} + +struct FileChunk { + blob@0: BlobRef; + len@1: UInt64; +} + +struct File { + chunks@0: List(FileChunk); +} + +struct BlobRef { + digest@0: Data; + offset@1: UInt64; + compressed@2: Bool; +} + +struct Xattr { + key@0: Data; + val@1: Data; +} + +struct InodeAdditional { + xattrs@0: List(Xattr); + symlinkTarget@1: Data; +} + +struct Inode { + ino@0: UInt64; + mode: union { + unknown@1: Void; + fifo@2: Void; + chr@3: Chr; + dir@4: Dir; + blk@5: Blk; + file@6: File; + lnk@7: Void; + sock@8: Void; + wht@9: Void; + } + uid@10: UInt32; + gid@11: UInt32; + permissions@12: UInt16; + additional@13: InodeAdditional; +} + +struct InodeVector { + inodes@0: List(Inode); +} diff --git a/samples/rust/puzzle/types/metadata_capnp.rs b/samples/rust/puzzle/types/metadata_capnp.rs new file mode 100644 index 000000000000..a56254cbafd8 --- /dev/null +++ b/samples/rust/puzzle/types/metadata_capnp.rs @@ -0,0 +1,4458 @@ +// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler. +// DO NOT EDIT. +// source: metadata.capnp +#![allow(unreachable_pub)] +#![allow(dead_code)] +pub mod chr { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_major(self) -> u64 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_minor(self) -> u64 { + self.reader.get_data_field::(1) + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 2, + pointers: 0, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_major(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_major(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_minor(self) -> u64 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_minor(&mut self, value: u64) { + self.builder.set_data_field::(1, value); + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 47] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(112, 90, 179, 204, 206, 228, 254, 162), + ::capnp::word(15, 0, 0, 0, 1, 0, 2, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(0, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 154, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 67), + ::capnp::word(104, 114, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(109, 97, 106, 111, 114, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 105, 110, 111, 114, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xa2fe_e4ce_ccb3_5a70; + } +} + +pub mod dir_entry { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_ino(self) -> u64 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 1, + pointers: 1, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_ino(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_ino(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_name(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_name(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_data(value); + } + #[inline] + pub fn init_name(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(0).init_data(size) + } + #[inline] + pub fn has_name(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 47] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(229, 236, 93, 69, 176, 175, 227, 153), + ::capnp::word(15, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 194, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 68), + ::capnp::word(105, 114, 69, 110, 116, 114, 121, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(105, 110, 111, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(110, 97, 109, 101, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0x99e3_afb0_455d_ece5; + } +} + +pub mod dir { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_entries( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Reader<'a, crate::metadata_capnp::dir_entry::Owned>, + > { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_entries(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_look_below(self) -> bool { + self.reader.get_bool_field(0) + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 1, + pointers: 1, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_entries( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Builder<'a, crate::metadata_capnp::dir_entry::Owned>, + > { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_entries( + &mut self, + value: ::capnp::struct_list::Reader<'a, crate::metadata_capnp::dir_entry::Owned>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_entries( + self, + size: u32, + ) -> ::capnp::struct_list::Builder<'a, crate::metadata_capnp::dir_entry::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + size, + ) + } + #[inline] + pub fn has_entries(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_look_below(self) -> bool { + self.builder.get_bool_field(0) + } + #[inline] + pub fn set_look_below(&mut self, value: bool) { + self.builder.set_bool_field(0, value); + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 52] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(4, 150, 39, 131, 249, 197, 58, 163), + ::capnp::word(15, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 154, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 68), + ::capnp::word(105, 114, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 66, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(64, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(61, 0, 0, 0, 82, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(60, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(72, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(101, 110, 116, 114, 105, 101, 115, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(229, 236, 93, 69, 176, 175, 227, 153), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(108, 111, 111, 107, 66, 101, 108, 111), + ::capnp::word(119, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xa33a_c5f9_8327_9604; + } +} + +pub mod blk { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_major(self) -> u64 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_minor(self) -> u64 { + self.reader.get_data_field::(1) + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 2, + pointers: 0, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_major(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_major(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_minor(self) -> u64 { + self.builder.get_data_field::(1) + } + #[inline] + pub fn set_minor(&mut self, value: u64) { + self.builder.set_data_field::(1, value); + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 47] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(105, 137, 149, 129, 43, 27, 209, 242), + ::capnp::word(15, 0, 0, 0, 1, 0, 2, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(0, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 154, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 66), + ::capnp::word(108, 107, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 50, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(109, 97, 106, 111, 114, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 105, 110, 111, 114, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xf2d1_1b2b_8195_8969; + } +} + +pub mod file_chunk { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_blob(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_blob(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_len(self) -> u64 { + self.reader.get_data_field::(0) + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 1, + pointers: 1, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_blob(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_blob( + &mut self, + value: crate::metadata_capnp::blob_ref::Reader<'_>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_blob(self) -> crate::metadata_capnp::blob_ref::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0) + } + #[inline] + pub fn has_blob(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_len(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_len(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline { + pub fn get_blob(&self) -> crate::metadata_capnp::blob_ref::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0)) + } + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 48] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(210, 21, 210, 230, 255, 156, 237, 140), + ::capnp::word(15, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 202, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 70), + ::capnp::word(105, 108, 101, 67, 104, 117, 110, 107), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(98, 108, 111, 98, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(70, 64, 38, 97, 160, 43, 222, 175), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(108, 101, 110, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0x8ced_9cff_e6d2_15d2; + } +} + +pub mod file { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_chunks( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Reader<'a, crate::metadata_capnp::file_chunk::Owned>, + > { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_chunks(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 0, + pointers: 1, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_chunks( + self, + ) -> ::capnp::Result< + ::capnp::struct_list::Builder<'a, crate::metadata_capnp::file_chunk::Owned>, + > { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_chunks( + &mut self, + value: ::capnp::struct_list::Reader<'a, crate::metadata_capnp::file_chunk::Owned>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_chunks( + self, + size: u32, + ) -> ::capnp::struct_list::Builder<'a, crate::metadata_capnp::file_chunk::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + size, + ) + } + #[inline] + pub fn has_chunks(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 36] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(212, 62, 195, 177, 129, 127, 161, 252), + ::capnp::word(15, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 162, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 63, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 70), + ::capnp::word(105, 108, 101, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(36, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(99, 104, 117, 110, 107, 115, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(210, 21, 210, 230, 255, 156, 237, 140), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xfca1_7f81_b1c3_3ed4; + } +} + +pub mod blob_ref { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_digest(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_digest(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_offset(self) -> u64 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_compressed(self) -> bool { + self.reader.get_bool_field(64) + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 2, + pointers: 1, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_digest(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_digest(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_data(value); + } + #[inline] + pub fn init_digest(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(0).init_data(size) + } + #[inline] + pub fn has_digest(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_offset(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_offset(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_compressed(self) -> bool { + self.builder.get_bool_field(64) + } + #[inline] + pub fn set_compressed(&mut self, value: bool) { + self.builder.set_bool_field(64, value); + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 63] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(70, 64, 38, 97, 160, 43, 222, 175), + ::capnp::word(15, 0, 0, 0, 1, 0, 2, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 186, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 175, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 66), + ::capnp::word(108, 111, 98, 82, 101, 102, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(12, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(69, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(64, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(76, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(73, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(68, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(80, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 0, 0, 64, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(77, 0, 0, 0, 90, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(76, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(88, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(100, 105, 103, 101, 115, 116, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(111, 102, 102, 115, 101, 116, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(99, 111, 109, 112, 114, 101, 115, 115), + ::capnp::word(101, 100, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => ::introspect(), + 2 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1, 2]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xafde_2ba0_6126_4046; + } +} + +pub mod xattr { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_key(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_key(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_val(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_val(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 0, + pointers: 2, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_key(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_key(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(0).set_data(value); + } + #[inline] + pub fn init_key(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(0).init_data(size) + } + #[inline] + pub fn has_key(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_val(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_val(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(1).set_data(value); + } + #[inline] + pub fn init_val(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(1).init_data(size) + } + #[inline] + pub fn has_val(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 47] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(64, 205, 159, 7, 194, 75, 43, 217), + ::capnp::word(15, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 170, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 88), + ::capnp::word(97, 116, 116, 114, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(48, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(45, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(40, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(52, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(107, 101, 121, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(118, 97, 108, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xd92b_4bc2_079f_cd40; + } +} + +pub mod inode_additional { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_xattrs( + self, + ) -> ::capnp::Result<::capnp::struct_list::Reader<'a, crate::metadata_capnp::xattr::Owned>> + { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_xattrs(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_symlink_target(self) -> ::capnp::Result<::capnp::data::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_symlink_target(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 0, + pointers: 2, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_xattrs( + self, + ) -> ::capnp::Result<::capnp::struct_list::Builder<'a, crate::metadata_capnp::xattr::Owned>> + { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_xattrs( + &mut self, + value: ::capnp::struct_list::Reader<'a, crate::metadata_capnp::xattr::Owned>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_xattrs( + self, + size: u32, + ) -> ::capnp::struct_list::Builder<'a, crate::metadata_capnp::xattr::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + size, + ) + } + #[inline] + pub fn has_xattrs(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn get_symlink_target(self) -> ::capnp::Result<::capnp::data::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_symlink_target(&mut self, value: ::capnp::data::Reader<'_>) { + self.builder.reborrow().get_pointer_field(1).set_data(value); + } + #[inline] + pub fn init_symlink_target(self, size: u32) -> ::capnp::data::Builder<'a> { + self.builder.get_pointer_field(1).init_data(size) + } + #[inline] + pub fn has_symlink_target(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 53] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(211, 144, 125, 86, 42, 166, 175, 153), + ::capnp::word(15, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 250, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 119, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 73), + ::capnp::word(110, 111, 100, 101, 65, 100, 100, 105), + ::capnp::word(116, 105, 111, 110, 97, 108, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(41, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(64, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(61, 0, 0, 0, 114, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(60, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(72, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(120, 97, 116, 116, 114, 115, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(64, 205, 159, 7, 194, 75, 43, 217), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 121, 109, 108, 105, 110, 107, 84), + ::capnp::word(97, 114, 103, 101, 116, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + 1 => <::capnp::data::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0x99af_a62a_567d_90d3; + } +} + +pub mod inode { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_ino(self) -> u64 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_mode(self) -> crate::metadata_capnp::inode::mode::Reader<'a> { + self.reader.into() + } + #[inline] + pub fn get_uid(self) -> u32 { + self.reader.get_data_field::(3) + } + #[inline] + pub fn get_gid(self) -> u32 { + self.reader.get_data_field::(4) + } + #[inline] + pub fn get_permissions(self) -> u16 { + self.reader.get_data_field::(5) + } + #[inline] + pub fn get_additional( + self, + ) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_additional(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 3, + pointers: 2, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_ino(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_ino(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_mode(self) -> crate::metadata_capnp::inode::mode::Builder<'a> { + self.builder.into() + } + #[inline] + pub fn init_mode(mut self) -> crate::metadata_capnp::inode::mode::Builder<'a> { + self.builder.set_data_field::(4, 0); + self.builder.reborrow().get_pointer_field(0).clear(); + self.builder.into() + } + #[inline] + pub fn get_uid(self) -> u32 { + self.builder.get_data_field::(3) + } + #[inline] + pub fn set_uid(&mut self, value: u32) { + self.builder.set_data_field::(3, value); + } + #[inline] + pub fn get_gid(self) -> u32 { + self.builder.get_data_field::(4) + } + #[inline] + pub fn set_gid(&mut self, value: u32) { + self.builder.set_data_field::(4, value); + } + #[inline] + pub fn get_permissions(self) -> u16 { + self.builder.get_data_field::(5) + } + #[inline] + pub fn set_permissions(&mut self, value: u16) { + self.builder.set_data_field::(5, value); + } + #[inline] + pub fn get_additional( + self, + ) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(1), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_additional( + &mut self, + value: crate::metadata_capnp::inode_additional::Reader<'_>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(1), + value, + false, + ) + } + #[inline] + pub fn init_additional(self) -> crate::metadata_capnp::inode_additional::Builder<'a> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(1), 0) + } + #[inline] + pub fn has_additional(&self) -> bool { + !self.builder.is_pointer_field_null(1) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline { + pub fn get_mode(&self) -> crate::metadata_capnp::inode::mode::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.noop()) + } + pub fn get_additional(&self) -> crate::metadata_capnp::inode_additional::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(1)) + } + } + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 102] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(161, 114, 128, 2, 173, 206, 117, 185), + ::capnp::word(15, 0, 0, 0, 1, 0, 3, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(2, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 170, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 87, 1, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 73), + ::capnp::word(110, 111, 100, 101, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(24, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(153, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(148, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(160, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(54, 46, 90, 92, 135, 239, 140, 194), + ::capnp::word(157, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(2, 0, 0, 0, 3, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 10, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(133, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(128, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(140, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(3, 0, 0, 0, 4, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 11, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(137, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(132, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(144, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 5, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 12, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(141, 0, 0, 0, 98, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(140, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(152, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(5, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 13, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(149, 0, 0, 0, 90, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(148, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(160, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(105, 110, 111, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 111, 100, 101, 0, 0, 0, 0), + ::capnp::word(117, 105, 100, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(103, 105, 100, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(112, 101, 114, 109, 105, 115, 115, 105), + ::capnp::word(111, 110, 115, 0, 0, 0, 0, 0), + ::capnp::word(7, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(7, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(97, 100, 100, 105, 116, 105, 111, 110), + ::capnp::word(97, 108, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(211, 144, 125, 86, 42, 166, 175, 153), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => ::introspect(), + 1 => ::introspect(), + 2 => ::introspect(), + 3 => ::introspect(), + 4 => ::introspect(), + 5 => ::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0, 1, 2, 3, 4, 5]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xb975_cead_0280_72a1; + } + + pub mod mode { + pub use self::Which::{Blk, Chr, Dir, Fifo, File, Lnk, Sock, Unknown, Wht}; + + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct( + ::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }, + ) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new( + ::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }, + ), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn has_chr(&self) -> bool { + if self.reader.get_data_field::(4) != 2 { + return false; + } + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn has_dir(&self) -> bool { + if self.reader.get_data_field::(4) != 3 { + return false; + } + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn has_blk(&self) -> bool { + if self.reader.get_data_field::(4) != 4 { + return false; + } + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn has_file(&self) -> bool { + if self.reader.get_data_field::(4) != 5 { + return false; + } + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn which(self) -> ::core::result::Result, ::capnp::NotInSchema> { + match self.reader.get_data_field::(4) { + 0 => ::core::result::Result::Ok(Unknown(())), + 1 => ::core::result::Result::Ok(Fifo(())), + 2 => ::core::result::Result::Ok(Chr( + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 3 => ::core::result::Result::Ok(Dir( + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 4 => ::core::result::Result::Ok(Blk( + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 5 => ::core::result::Result::Ok(File( + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 6 => ::core::result::Result::Ok(Lnk(())), + 7 => ::core::result::Result::Ok(Sock(())), + 8 => ::core::result::Result::Ok(Wht(())), + x => ::core::result::Result::Err(::capnp::NotInSchema(x)), + } + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 3, + pointers: 2, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new( + ::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }, + ), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + _size: u32, + ) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn set_unknown(&mut self, _value: ()) { + self.builder.set_data_field::(4, 0); + } + #[inline] + pub fn set_fifo(&mut self, _value: ()) { + self.builder.set_data_field::(4, 1); + } + #[inline] + pub fn set_chr( + &mut self, + value: crate::metadata_capnp::chr::Reader<'_>, + ) -> ::capnp::Result<()> { + self.builder.set_data_field::(4, 2); + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_chr(self) -> crate::metadata_capnp::chr::Builder<'a> { + self.builder.set_data_field::(4, 2); + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + 0, + ) + } + #[inline] + pub fn has_chr(&self) -> bool { + if self.builder.get_data_field::(4) != 2 { + return false; + } + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn set_dir( + &mut self, + value: crate::metadata_capnp::dir::Reader<'_>, + ) -> ::capnp::Result<()> { + self.builder.set_data_field::(4, 3); + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_dir(self) -> crate::metadata_capnp::dir::Builder<'a> { + self.builder.set_data_field::(4, 3); + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + 0, + ) + } + #[inline] + pub fn has_dir(&self) -> bool { + if self.builder.get_data_field::(4) != 3 { + return false; + } + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn set_blk( + &mut self, + value: crate::metadata_capnp::blk::Reader<'_>, + ) -> ::capnp::Result<()> { + self.builder.set_data_field::(4, 4); + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_blk(self) -> crate::metadata_capnp::blk::Builder<'a> { + self.builder.set_data_field::(4, 4); + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + 0, + ) + } + #[inline] + pub fn has_blk(&self) -> bool { + if self.builder.get_data_field::(4) != 4 { + return false; + } + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn set_file( + &mut self, + value: crate::metadata_capnp::file::Reader<'_>, + ) -> ::capnp::Result<()> { + self.builder.set_data_field::(4, 5); + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_file(self) -> crate::metadata_capnp::file::Builder<'a> { + self.builder.set_data_field::(4, 5); + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + 0, + ) + } + #[inline] + pub fn has_file(&self) -> bool { + if self.builder.get_data_field::(4) != 5 { + return false; + } + !self.builder.is_pointer_field_null(0) + } + #[inline] + pub fn set_lnk(&mut self, _value: ()) { + self.builder.set_data_field::(4, 6); + } + #[inline] + pub fn set_sock(&mut self, _value: ()) { + self.builder.set_data_field::(4, 7); + } + #[inline] + pub fn set_wht(&mut self, _value: ()) { + self.builder.set_data_field::(4, 8); + } + #[inline] + pub fn which(self) -> ::core::result::Result, ::capnp::NotInSchema> { + match self.builder.get_data_field::(4) { + 0 => ::core::result::Result::Ok(Unknown(())), + 1 => ::core::result::Result::Ok(Fifo(())), + 2 => ::core::result::Result::Ok(Chr( + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 3 => ::core::result::Result::Ok(Dir( + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 4 => ::core::result::Result::Ok(Blk( + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 5 => ::core::result::Result::Ok(File( + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ), + )), + 6 => ::core::result::Result::Ok(Lnk(())), + 7 => ::core::result::Result::Ok(Sock(())), + 8 => ::core::result::Result::Ok(Wht(())), + x => ::core::result::Result::Err(::capnp::NotInSchema(x)), + } + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 152] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(54, 46, 90, 92, 135, 239, 140, 194), + ::capnp::word(21, 0, 0, 0, 1, 0, 3, 0), + ::capnp::word(161, 114, 128, 2, 173, 206, 117, 185), + ::capnp::word(2, 0, 7, 0, 1, 0, 9, 0), + ::capnp::word(4, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 210, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(25, 0, 0, 0, 255, 1, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 73), + ::capnp::word(110, 111, 100, 101, 46, 109, 111, 100), + ::capnp::word(101, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(36, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 255, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 1, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(237, 0, 0, 0, 66, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(232, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(244, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(1, 0, 254, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 2, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(241, 0, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(236, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(248, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(2, 0, 253, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 3, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(245, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(240, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(252, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(3, 0, 252, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 4, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(249, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(244, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(0, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(4, 0, 251, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 5, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(253, 0, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(248, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(4, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(5, 0, 250, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 6, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(1, 1, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(252, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(8, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(6, 0, 249, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(5, 1, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 1, 0, 0, 3, 0, 1, 0), + ::capnp::word(12, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(7, 0, 248, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 8, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(9, 1, 0, 0, 42, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(4, 1, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(8, 0, 247, 255, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 9, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 1, 0, 0, 34, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 1, 0, 0, 3, 0, 1, 0), + ::capnp::word(20, 1, 0, 0, 2, 0, 1, 0), + ::capnp::word(117, 110, 107, 110, 111, 119, 110, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(102, 105, 102, 111, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(99, 104, 114, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(112, 90, 179, 204, 206, 228, 254, 162), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(100, 105, 114, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(4, 150, 39, 131, 249, 197, 58, 163), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(98, 108, 107, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(105, 137, 149, 129, 43, 27, 209, 242), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(102, 105, 108, 101, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(212, 62, 195, 177, 129, 127, 161, 252), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(108, 110, 107, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(115, 111, 99, 107, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(119, 104, 116, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <() as ::capnp::introspect::Introspect>::introspect(), + 1 => <() as ::capnp::introspect::Introspect>::introspect(), + 2 => ::introspect(), + 3 => ::introspect(), + 4 => ::introspect(), + 5 => ::introspect(), + 6 => <() as ::capnp::introspect::Introspect>::introspect(), + 7 => <() as ::capnp::introspect::Introspect>::introspect(), + 8 => <() as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; + pub const TYPE_ID: u64 = 0xc28c_ef87_5c5a_2e36; + } + pub enum Which { + Unknown(()), + Fifo(()), + Chr(A0), + Dir(A1), + Blk(A2), + File(A3), + Lnk(()), + Sock(()), + Wht(()), + } + pub type WhichReader<'a> = Which< + ::capnp::Result>, + ::capnp::Result>, + ::capnp::Result>, + ::capnp::Result>, + >; + pub type WhichBuilder<'a> = Which< + ::capnp::Result>, + ::capnp::Result>, + ::capnp::Result>, + ::capnp::Result>, + >; + } +} + +pub mod inode_vector { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl ::capnp::introspect::Introspect for Owned { + fn introspect() -> ::capnp::introspect::Type { + ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }) + .into() + } + } + impl ::capnp::traits::Owned for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + impl ::capnp::traits::OwnedStruct for Owned { + type Reader<'a> = Reader<'a>; + type Builder<'a> = Builder<'a>; + } + #[cfg(feature = "alloc")] + impl ::capnp::traits::Pipelined for Owned { + type Pipeline = Pipeline; + } + + pub struct Reader<'a> { + reader: ::capnp::private::layout::StructReader<'a>, + } + impl<'a> ::core::marker::Copy for Reader<'a> {} + impl<'a> ::core::clone::Clone for Reader<'a> { + fn clone(&self) -> Self { + *self + } + } + + impl<'a> ::capnp::traits::HasTypeId for Reader<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> { + fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self { + Self { reader } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Reader<'a> { + fn from(reader: Reader<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Reader::new( + reader.reader, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::fmt::Debug for Reader<'a> { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::result::Result<(), ::core::fmt::Error> { + core::fmt::Debug::fmt( + &::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), + f, + ) + } + } + + impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> { + fn get_from_pointer( + reader: &::capnp::private::layout::PointerReader<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok(reader.get_struct(default)?.into()) + } + } + + impl<'a> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::Imbue<'a> for Reader<'a> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader + .imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl<'a> Reader<'a> { + pub fn reborrow(&self) -> Reader<'_> { + Self { ..*self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_inodes( + self, + ) -> ::capnp::Result<::capnp::struct_list::Reader<'a, crate::metadata_capnp::inode::Owned>> + { + ::capnp::traits::FromPointerReader::get_from_pointer( + &self.reader.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn has_inodes(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { + builder: ::capnp::private::layout::StructBuilder<'a>, + } + impl<'a> ::capnp::traits::HasStructSize for Builder<'a> { + const STRUCT_SIZE: ::capnp::private::layout::StructSize = + ::capnp::private::layout::StructSize { + data: 0, + pointers: 1, + }; + } + impl<'a> ::capnp::traits::HasTypeId for Builder<'a> { + const TYPE_ID: u64 = _private::TYPE_ID; + } + impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> { + fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self { + Self { builder } + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::core::convert::From> for ::capnp::dynamic_value::Builder<'a> { + fn from(builder: Builder<'a>) -> Self { + Self::Struct(::capnp::dynamic_struct::Builder::new( + builder.builder, + ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { + generic: &_private::RAW_SCHEMA, + field_types: _private::get_field_types, + annotation_types: _private::get_annotation_types, + }), + )) + } + } + + #[cfg(feature = "alloc")] + impl<'a> ::capnp::traits::ImbueMut<'a> for Builder<'a> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder + .imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl<'a> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self { + builder + .init_struct(::STRUCT_SIZE) + .into() + } + fn get_from_pointer( + builder: ::capnp::private::layout::PointerBuilder<'a>, + default: ::core::option::Option<&'a [::capnp::Word]>, + ) -> ::capnp::Result { + ::core::result::Result::Ok( + builder + .get_struct( + ::STRUCT_SIZE, + default, + )? + .into(), + ) + } + } + + impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> { + fn set_pointer_builder( + mut pointer: ::capnp::private::layout::PointerBuilder<'_>, + value: Self, + canonicalize: bool, + ) -> ::capnp::Result<()> { + pointer.set_struct(&value.reader, canonicalize) + } + } + + impl<'a> Builder<'a> { + pub fn into_reader(self) -> Reader<'a> { + self.builder.into_reader().into() + } + pub fn reborrow(&mut self) -> Builder<'_> { + Builder { + builder: self.builder.reborrow(), + } + } + pub fn reborrow_as_reader(&self) -> Reader<'_> { + self.builder.as_reader().into() + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.as_reader().total_size() + } + #[inline] + pub fn get_inodes( + self, + ) -> ::capnp::Result<::capnp::struct_list::Builder<'a, crate::metadata_capnp::inode::Owned>> + { + ::capnp::traits::FromPointerBuilder::get_from_pointer( + self.builder.get_pointer_field(0), + ::core::option::Option::None, + ) + } + #[inline] + pub fn set_inodes( + &mut self, + value: ::capnp::struct_list::Reader<'a, crate::metadata_capnp::inode::Owned>, + ) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder( + self.builder.reborrow().get_pointer_field(0), + value, + false, + ) + } + #[inline] + pub fn init_inodes( + self, + size: u32, + ) -> ::capnp::struct_list::Builder<'a, crate::metadata_capnp::inode::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer( + self.builder.get_pointer_field(0), + size, + ) + } + #[inline] + pub fn has_inodes(&self) -> bool { + !self.builder.is_pointer_field_null(0) + } + } + + #[cfg(feature = "alloc")] + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + } + #[cfg(feature = "alloc")] + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self { + Self { + _typeless: typeless, + } + } + } + #[cfg(feature = "alloc")] + impl Pipeline {} + mod _private { + pub static ENCODED_NODE: [::capnp::Word; 37] = [ + ::capnp::word(0, 0, 0, 0, 5, 0, 6, 0), + ::capnp::word(35, 20, 59, 240, 58, 227, 99, 162), + ::capnp::word(15, 0, 0, 0, 1, 0, 0, 0), + ::capnp::word(183, 203, 183, 136, 110, 94, 174, 132), + ::capnp::word(1, 0, 7, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(21, 0, 0, 0, 218, 0, 0, 0), + ::capnp::word(33, 0, 0, 0, 7, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(29, 0, 0, 0, 63, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(109, 101, 116, 97, 100, 97, 116, 97), + ::capnp::word(46, 99, 97, 112, 110, 112, 58, 73), + ::capnp::word(110, 111, 100, 101, 86, 101, 99, 116), + ::capnp::word(111, 114, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 1, 0, 1, 0), + ::capnp::word(4, 0, 0, 0, 3, 0, 4, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 1, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(13, 0, 0, 0, 58, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(8, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(36, 0, 0, 0, 2, 0, 1, 0), + ::capnp::word(105, 110, 111, 100, 101, 115, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 3, 0, 1, 0), + ::capnp::word(16, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(161, 114, 128, 2, 173, 206, 117, 185), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(14, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ::capnp::word(0, 0, 0, 0, 0, 0, 0, 0), + ]; + pub fn get_field_types(index: u16) -> ::capnp::introspect::Type { + match index { + 0 => <::capnp::struct_list::Owned as ::capnp::introspect::Introspect>::introspect(), + _ => panic!("invalid field index {}", index), + } + } + pub fn get_annotation_types( + child_index: Option, + index: u32, + ) -> ::capnp::introspect::Type { + panic!("invalid annotation indices ({:?}, {}) ", child_index, index) + } + pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = + ::capnp::introspect::RawStructSchema { + encoded_node: &ENCODED_NODE, + nonunion_members: NONUNION_MEMBERS, + members_by_discriminant: MEMBERS_BY_DISCRIMINANT, + }; + pub static NONUNION_MEMBERS: &[u16] = &[0]; + pub static MEMBERS_BY_DISCRIMINANT: &[u16] = &[]; + pub const TYPE_ID: u64 = 0xa263_e33a_f03b_1423; + } +} diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs index 0cf42762e81a..9afd82745b64 100644 --- a/samples/rust/puzzlefs.rs +++ b/samples/rust/puzzlefs.rs @@ -6,6 +6,10 @@ use kernel::prelude::*; use kernel::{c_str, file, fs, io_buffer::IoBufferWriter}; +mod puzzle; +// Required by the autogenerated '_capnp.rs' files +use puzzle::{manifest_capnp, metadata_capnp}; + module_fs! { type: PuzzleFsModule, name: "puzzlefs", From patchwork Wed Jul 26 16:45:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328376 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89F37C001DC for ; Wed, 26 Jul 2023 16:48:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231561AbjGZQsO (ORCPT ); Wed, 26 Jul 2023 12:48:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231840AbjGZQry (ORCPT ); Wed, 26 Jul 2023 12:47:54 -0400 Received: from aer-iport-4.cisco.com (aer-iport-4.cisco.com [173.38.203.54]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DCB526AC for ; Wed, 26 Jul 2023 09:47:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=5818; q=dns/txt; s=iport; t=1690390047; x=1691599647; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=UiFHWKZZEisCHqVroCxAGB1BlMOgs6ZoyHjOZIT/iNs=; b=k4AjeOYNfCWf5n5guEk9YI65FW4wQFjMV1GPMv0G2hoNzOvPpTe8P+u5 qhz2kNxDIetBitZAUj1Nw1SUj12cYxKyPbqfbqrn54QUd2QwroNy8sHj1 lbzdjs5kO1G0PX6MpAaw6wK9HGRK6BLwrfsEtz+Z5wFNzq3YVCyHW/ecf E=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="8416073" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-4.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:21 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTw022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:21 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 06/10] rust: file: pass the filesystem context to the open function Date: Wed, 26 Jul 2023 19:45:30 +0300 Message-ID: <20230726164535.230515-7-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This allows us to create a Vfsmount structure and pass it to the read callback. Signed-off-by: Ariel Miculas --- rust/kernel/file.rs | 17 +++++++++++++++-- samples/rust/puzzlefs.rs | 40 +++++++++++++++++++++++++++++++++++----- samples/rust/rust_fs.rs | 3 ++- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/rust/kernel/file.rs b/rust/kernel/file.rs index a3002c416dbb..af1eb1ee9267 100644 --- a/rust/kernel/file.rs +++ b/rust/kernel/file.rs @@ -457,9 +457,15 @@ impl, T: Operations> OperationsVtable { // `fileref` never outlives this function, so it is guaranteed to be // valid. let fileref = unsafe { File::from_ptr(file) }; + + // SAFETY: into_foreign was called in fs::NewSuperBlock<..., NeedsInit>::init and + // it is valid until from_foreign will be called in fs::Tables::free_callback + let fs_info = + unsafe { ::Data::borrow((*(*inode).i_sb).s_fs_info) }; + // SAFETY: `arg` was previously returned by `A::convert` and must // be a valid non-null pointer. - let ptr = T::open(unsafe { &*arg }, fileref)?.into_foreign(); + let ptr = T::open(fs_info, unsafe { &*arg }, fileref)?.into_foreign(); // SAFETY: The C contract guarantees that `private_data` is available // for implementers of the file operations (no other C code accesses // it), so we know that there are no concurrent threads/CPUs accessing @@ -930,10 +936,17 @@ pub trait Operations { /// The type of the context data passed to [`Operations::open`]. type OpenData: Sync = (); + /// Data associated with each file system instance. + type Filesystem: fs::Type; + /// Creates a new instance of this file. /// /// Corresponds to the `open` function pointer in `struct file_operations`. - fn open(context: &Self::OpenData, file: &File) -> Result; + fn open( + fs_info: <::Data as ForeignOwnable>::Borrowed<'_>, + context: &Self::OpenData, + file: &File, + ) -> Result; /// Cleans up after the last reference to the file goes away. /// diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs index 9afd82745b64..8a64e0bd437d 100644 --- a/samples/rust/puzzlefs.rs +++ b/samples/rust/puzzlefs.rs @@ -3,8 +3,14 @@ //! Rust file system sample. use kernel::module_fs; +use kernel::mount::Vfsmount; use kernel::prelude::*; -use kernel::{c_str, file, fs, io_buffer::IoBufferWriter}; +use kernel::{ + c_str, file, fmt, fs, + io_buffer::IoBufferWriter, + str::CString, + sync::{Arc, ArcBorrow}, +}; mod puzzle; // Required by the autogenerated '_capnp.rs' files @@ -19,6 +25,12 @@ struct PuzzleFsModule; +#[derive(Debug)] +struct PuzzlefsInfo { + base_path: CString, + vfs_mount: Arc, +} + #[vtable] impl fs::Context for PuzzleFsModule { type Data = (); @@ -46,14 +58,23 @@ fn try_new() -> Result { impl fs::Type for PuzzleFsModule { type Context = Self; type INodeData = &'static [u8]; + type Data = Box; const SUPER_TYPE: fs::Super = fs::Super::Independent; const NAME: &'static CStr = c_str!("puzzlefs"); const FLAGS: i32 = fs::flags::USERNS_MOUNT; const DCACHE_BASED: bool = true; fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock> { + let base_path = CString::try_from_fmt(fmt!("hello world"))?; + pr_info!("base_path {:?}\n", base_path); + let vfs_mount = Vfsmount::new_private_mount(c_str!("/home/puzzlefs_oci"))?; + pr_info!("vfs_mount {:?}\n", vfs_mount); + let sb = sb.init( - (), + Box::try_new(PuzzlefsInfo { + base_path, + vfs_mount: Arc::try_new(vfs_mount)?, + })?, &fs::SuperParams { magic: 0x72757374, ..fs::SuperParams::DEFAULT @@ -88,14 +109,23 @@ fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBl #[vtable] impl file::Operations for FsFile { + // must be the same as INodeData type OpenData = &'static [u8]; + type Filesystem = PuzzleFsModule; + // this is an Arc because Data must be ForeignOwnable and the only implementors of it are Box, + // Arc and (); we cannot pass a reference to read, so we share Vfsmount using and Arc + type Data = Arc; - fn open(_context: &Self::OpenData, _file: &file::File) -> Result { - Ok(()) + fn open( + fs_info: &PuzzlefsInfo, + _context: &Self::OpenData, + _file: &file::File, + ) -> Result { + Ok(fs_info.vfs_mount.clone()) } fn read( - _data: (), + data: ArcBorrow<'_, Vfsmount>, file: &file::File, writer: &mut impl IoBufferWriter, offset: u64, diff --git a/samples/rust/rust_fs.rs b/samples/rust/rust_fs.rs index 7527681ee024..c58ed1560e06 100644 --- a/samples/rust/rust_fs.rs +++ b/samples/rust/rust_fs.rs @@ -85,8 +85,9 @@ fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBl #[vtable] impl file::Operations for FsFile { type OpenData = &'static [u8]; + type Filesystem = RustFs; - fn open(_context: &Self::OpenData, _file: &file::File) -> Result { + fn open(_fs_info: (), _context: &Self::OpenData, _file: &file::File) -> Result { Ok(()) } From patchwork Wed Jul 26 16:45:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328392 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0A6D5C001DC for ; Wed, 26 Jul 2023 17:11:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232010AbjGZRLt (ORCPT ); Wed, 26 Jul 2023 13:11:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232138AbjGZRLq (ORCPT ); Wed, 26 Jul 2023 13:11:46 -0400 Received: from aer-iport-5.cisco.com (aer-iport-5.cisco.com [173.38.203.67]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25E161FC4 for ; Wed, 26 Jul 2023 10:11:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=10089; q=dns/txt; s=iport; t=1690391504; x=1691601104; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=TRWzNxjh1uYFqrfsbY1Jt0vK+xcFRJ/MMfLVEQAsNfg=; b=Ho0IwL7goILvth3HdWw6/zGK/r0mIKB0YgIhpTEQbSiqGL4CXrlByISt jEGR1nBxL1aq4ELKDB7OcQaXnF2if5s1cR+09YAZ8OyuX03q7+7JqfqKs 0sZ1Hen48J2dq0sLNZOEUPMQWXLsC0GzZGE7vetFv79U+eijXJn6h74zY 0=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="5874462" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-5.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:23 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqTx022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:22 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 07/10] samples: puzzlefs: populate the directory entries with the inodes from the puzzlefs metadata file Date: Wed, 26 Jul 2023 19:45:31 +0300 Message-ID: <20230726164535.230515-8-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org I've used the same strategy as in try_new_populated_root_dentry from rust/kernel/fs.rs, that is, recursively traverse the filesystem starting from the root and create the necessary dentries. This is not ideal because it creates all the dentries up front, but there are no rust filesystem abstractions for implementing lookups yet. Signed-off-by: Ariel Miculas --- rust/alloc/vec/mod.rs | 17 +++++ rust/kernel/fs.rs | 4 +- samples/rust/puzzlefs.rs | 141 +++++++++++++++++++++++++++++---------- 3 files changed, 127 insertions(+), 35 deletions(-) diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs index e8344c77939e..b755cf0b936c 100644 --- a/rust/alloc/vec/mod.rs +++ b/rust/alloc/vec/mod.rs @@ -2499,6 +2499,15 @@ unsafe fn split_at_spare_mut_with_len( } } +impl Vec { + /// Try to clone the vector using the global allocator + #[inline] + #[stable(feature = "kernel", since = "1.0.0")] + pub fn try_clone(&self) -> Result { + self.try_clone_in(Global) + } +} + impl Vec { /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. /// @@ -2623,6 +2632,14 @@ pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), TryReserveErr self.try_spec_extend(other.iter()) } + /// Tries to clone the vector using the given allocator + #[stable(feature = "kernel", since = "1.0.0")] + pub fn try_clone_in(&self, allocator: A) -> Result { + let mut new_vec = Vec::try_with_capacity_in(self.len(), allocator)?; + new_vec.try_extend_from_slice(&self)?; + Ok(new_vec) + } + /// Copies elements from `src` range to the end of the vector. /// /// # Panics diff --git a/rust/kernel/fs.rs b/rust/kernel/fs.rs index 10f90f78fc54..709b79fa0030 100644 --- a/rust/kernel/fs.rs +++ b/rust/kernel/fs.rs @@ -781,7 +781,9 @@ impl SuperParams { /// /// The superblock is a newly-created one and this is the only active pointer to it. pub struct NewSuperBlock<'a, T: Type + ?Sized, S = NeedsInit> { - sb: &'a mut SuperBlock, + /// Pointer to the superblock; this fields is public so puzzlefs can call + /// try_new_dcache_dir_inode when populating the directory hierarchy + pub sb: &'a mut SuperBlock, // This also forces `'a` to be invariant. _p: PhantomData<&'a mut &'a S>, diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs index 8a64e0bd437d..1f0073716d91 100644 --- a/samples/rust/puzzlefs.rs +++ b/samples/rust/puzzlefs.rs @@ -6,16 +6,19 @@ use kernel::mount::Vfsmount; use kernel::prelude::*; use kernel::{ - c_str, file, fmt, fs, + c_str, file, fs, io_buffer::IoBufferWriter, - str::CString, sync::{Arc, ArcBorrow}, }; mod puzzle; // Required by the autogenerated '_capnp.rs' files +use puzzle::inode::PuzzleFS; +use puzzle::types::{Inode, InodeMode, MetadataBlob}; use puzzle::{manifest_capnp, metadata_capnp}; +use kernel::fs::{DEntry, INodeParams, NeedsRoot, NewSuperBlock, RootDEntry}; + module_fs! { type: PuzzleFsModule, name: "puzzlefs", @@ -27,7 +30,6 @@ #[derive(Debug)] struct PuzzlefsInfo { - base_path: CString, vfs_mount: Arc, } @@ -55,9 +57,81 @@ fn try_new() -> Result { } } +fn puzzlefs_populate_dir( + sb: &NewSuperBlock<'_, PuzzleFsModule, NeedsRoot>, + pfs: &PuzzleFS, + parent: &DEntry, + ino: u64, + name: &CStr, + recursion: usize, +) -> Result { + if recursion == 0 { + return Err(E2BIG); + } + + let inode = Arc::try_new(pfs.find_inode(ino).map_err(|_| EINVAL)?)?; + match &inode.mode { + InodeMode::File { chunks: _ } => { + let params = INodeParams { + mode: inode.permissions, + ino: inode.ino, + value: inode.clone(), + }; + let creator = fs::file_creator::<_, FsFile>(); + let inode = creator(sb, params)?; + sb.try_new_dentry(inode, parent, name)?; + } + InodeMode::Dir { dir_list } => { + let params = INodeParams { + mode: inode.permissions, + ino: inode.ino, + value: inode.clone(), + }; + + let new_dentry; + let new_parent = if name.as_bytes() != c_str!("").as_bytes() { + let dcache_inode = sb.sb.try_new_dcache_dir_inode(params)?; + new_dentry = sb.try_new_dentry(dcache_inode, parent, name)?; + &new_dentry + } else { + parent + }; + + for entry in &dir_list.entries { + let mut name = entry.name.try_clone()?; + // append NUL terminator + name.try_push(0)?; + let name = CStr::from_bytes_with_nul(&name)?; + puzzlefs_populate_dir(sb, pfs, new_parent, entry.ino, name, recursion - 1)?; + } + } + _ => todo!(), + } + + Ok(()) +} + +/// Creates a new root dentry populated with the given entries. +fn try_new_populated_root_puzzlefs_dentry( + sb: &NewSuperBlock<'_, PuzzleFsModule, NeedsRoot>, + pfs: &PuzzleFS, + root_value: ::INodeData, +) -> Result> { + let root_inode = sb.sb.try_new_dcache_dir_inode(INodeParams { + mode: 0o755, + ino: root_value.ino, + value: root_value, + })?; + let root = sb.try_new_root_dentry(root_inode)?; + let ino = 1u64; + puzzlefs_populate_dir(sb, pfs, &root, ino, c_str!(""), 10)?; + Ok(root) +} + impl fs::Type for PuzzleFsModule { type Context = Self; - type INodeData = &'static [u8]; + // this is Arc so it can be cloned in puzzlefs_populate_dir + type INodeData = Arc; type Data = Box; const SUPER_TYPE: fs::Super = fs::Super::Independent; const NAME: &'static CStr = c_str!("puzzlefs"); @@ -65,41 +139,35 @@ impl fs::Type for PuzzleFsModule { const DCACHE_BASED: bool = true; fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock> { - let base_path = CString::try_from_fmt(fmt!("hello world"))?; - pr_info!("base_path {:?}\n", base_path); let vfs_mount = Vfsmount::new_private_mount(c_str!("/home/puzzlefs_oci"))?; pr_info!("vfs_mount {:?}\n", vfs_mount); + let arc_vfs_mount = Arc::try_new(vfs_mount)?; + let sb = sb.init( Box::try_new(PuzzlefsInfo { - base_path, - vfs_mount: Arc::try_new(vfs_mount)?, + vfs_mount: arc_vfs_mount.clone(), })?, &fs::SuperParams { magic: 0x72757374, ..fs::SuperParams::DEFAULT }, )?; - let root = sb.try_new_populated_root_dentry( - &[], - kernel::fs_entries![ - file("test1", 0o600, "abc\n".as_bytes(), FsFile), - file("test2", 0o600, "def\n".as_bytes(), FsFile), - char("test3", 0o600, [].as_slice(), (10, 125)), - sock("test4", 0o755, [].as_slice()), - fifo("test5", 0o755, [].as_slice()), - block("test6", 0o755, [].as_slice(), (1, 1)), - dir( - "dir1", - 0o755, - [].as_slice(), - [ - file("test1", 0o600, "abc\n".as_bytes(), FsFile), - file("test2", 0o600, "def\n".as_bytes(), FsFile), - ] - ), - ], + + let file = file::RegularFile::from_path_in_root_mnt( + &arc_vfs_mount, + c_str!("997eed138af30d187e87d682dd2ae9f240fae78f668907a0519460b397c82467"), + file::flags::O_RDONLY.try_into().unwrap(), + 0, )?; + + // TODO: figure out how to go from WireFormatError to kernel::error::Error + let metadata = MetadataBlob::new(file).map_err(|_| EINVAL)?; + + let mut puzzlefs = PuzzleFS::new(metadata).map_err(|_| EINVAL)?; + let root_inode = Arc::try_new(puzzlefs.find_inode(1).map_err(|_| EINVAL)?)?; + + let root = try_new_populated_root_puzzlefs_dentry(&sb, &mut puzzlefs, root_inode)?; let sb = sb.init_root(root)?; Ok(sb) } @@ -110,7 +178,7 @@ fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBl #[vtable] impl file::Operations for FsFile { // must be the same as INodeData - type OpenData = &'static [u8]; + type OpenData = Arc; type Filesystem = PuzzleFsModule; // this is an Arc because Data must be ForeignOwnable and the only implementors of it are Box, // Arc and (); we cannot pass a reference to read, so we share Vfsmount using and Arc @@ -126,14 +194,19 @@ fn open( fn read( data: ArcBorrow<'_, Vfsmount>, - file: &file::File, + _file: &file::File, writer: &mut impl IoBufferWriter, offset: u64, ) -> Result { - file::read_from_slice( - file.inode::().ok_or(EINVAL)?.fs_data(), - writer, - offset, - ) + let mut buf = Vec::try_with_capacity(writer.len())?; + buf.try_resize(writer.len(), 0)?; + let file = file::RegularFile::from_path_in_root_mnt( + &data, + c_str!("data"), + file::flags::O_RDONLY.try_into().unwrap(), + 0, + )?; + let nr_bytes_read = file.read_with_offset(&mut buf[..], offset)?; + file::read_from_slice(&buf[..nr_bytes_read], writer, 0) } } From patchwork Wed Jul 26 16:45:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328386 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43CA6C001DF for ; Wed, 26 Jul 2023 16:58:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232266AbjGZQ57 (ORCPT ); Wed, 26 Jul 2023 12:57:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232185AbjGZQ54 (ORCPT ); Wed, 26 Jul 2023 12:57:56 -0400 Received: from aer-iport-4.cisco.com (aer-iport-4.cisco.com [173.38.203.54]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F08F1E42 for ; Wed, 26 Jul 2023 09:57:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=6458; q=dns/txt; s=iport; t=1690390675; x=1691600275; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cIBpQFptALxQEDeNXQIlMjNYdYD99mepAG1JGqIXFp8=; b=SYq4YXMnDGrU7gRPKHuCkwF1z4E7FIIL0QUkDGIAqg2Pp5Q0xqdDTM+O J3ZJbD7aD3mOiAitwibKZFrqkJ57jutSAmFuGCPlAkxKnop4JvF3OXjwS VaPekMmpFKRntVfv7LdovDZ7KV0OrQwlblOrWpcVTkfDiiYKjMgw1DVTe E=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="8416074" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-4.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:24 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqU0022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:24 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 08/10] rust: puzzlefs: read the puzzlefs image manifest instead of an individual metadata layer Date: Wed, 26 Jul 2023 19:45:32 +0300 Message-ID: <20230726164535.230515-9-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org The puzzlefs image manifest is the file referenced by index.json and it contains the array of metadata layers that describe the puzzlefs image. This file represents the root of the puzzlefs filesystem since we can't parse json files. When this filesystem is mounted, usermode will need to read the tag from index.json, find the corresponding puzzlefs image manifest and pass it to the kernel module. Due to the lack of BTreeMap in the kernel, only image manifests without fs verity information are supported for now. Signed-off-by: Ariel Miculas --- samples/rust/puzzle.rs | 1 + samples/rust/puzzle/inode.rs | 22 ++++++++++++---- samples/rust/puzzle/oci.rs | 51 ++++++++++++++++++++++++++++++++++++ samples/rust/puzzlefs.rs | 23 ++++++++-------- 4 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 samples/rust/puzzle/oci.rs diff --git a/samples/rust/puzzle.rs b/samples/rust/puzzle.rs index a809cddfb817..e74a248c39ff 100644 --- a/samples/rust/puzzle.rs +++ b/samples/rust/puzzle.rs @@ -2,3 +2,4 @@ pub(crate) mod types; pub(crate) use types::{manifest_capnp, metadata_capnp}; pub(crate) mod inode; +pub(crate) mod oci; diff --git a/samples/rust/puzzle/inode.rs b/samples/rust/puzzle/inode.rs index d792f661aa00..f63cdbc1eac4 100644 --- a/samples/rust/puzzle/inode.rs +++ b/samples/rust/puzzle/inode.rs @@ -3,20 +3,32 @@ use crate::puzzle::error::Result; use crate::puzzle::error::WireFormatError; +use crate::puzzle::oci::Image; use crate::puzzle::types as format; -use crate::puzzle::types::{Inode, InodeMode, MetadataBlob}; +use crate::puzzle::types::{Digest, Inode, InodeMode}; use alloc::vec::Vec; +use kernel::mount::Vfsmount; use kernel::prelude::ENOENT; +use kernel::str::CStr; +use kernel::sync::Arc; pub(crate) struct PuzzleFS { + pub(crate) oci: Image, layers: Vec, } impl PuzzleFS { - pub(crate) fn new(md: MetadataBlob) -> Result { - let mut v = Vec::new(); - v.try_push(md)?; - Ok(PuzzleFS { layers: v }) + pub(crate) fn open(vfsmount: Arc, rootfs_path: &CStr) -> Result { + let oci = Image::open(vfsmount)?; + let rootfs = oci.open_rootfs_blob(rootfs_path)?; + + let mut layers = Vec::new(); + for md in rootfs.metadatas.iter() { + let digest = Digest::try_from(md)?; + layers.try_push(oci.open_metadata_blob(&digest)?)?; + } + + Ok(PuzzleFS { oci, layers }) } pub(crate) fn find_inode(&self, ino: u64) -> Result { diff --git a/samples/rust/puzzle/oci.rs b/samples/rust/puzzle/oci.rs new file mode 100644 index 000000000000..becb2b868450 --- /dev/null +++ b/samples/rust/puzzle/oci.rs @@ -0,0 +1,51 @@ +use crate::puzzle::error::Result; +use crate::puzzle::types::{Digest, MetadataBlob, Rootfs}; +use kernel::c_str; +use kernel::file; +use kernel::file::RegularFile; +use kernel::mount::Vfsmount; +use kernel::pr_info; +use kernel::str::{CStr, CString}; +use kernel::sync::Arc; + +pub(crate) struct Image { + vfs_mount: Arc, +} + +impl Image { + pub(crate) fn open(vfsmount: Arc) -> Result { + Ok(Image { + vfs_mount: vfsmount, + }) + } + + pub(crate) fn blob_path_relative(&self) -> &CStr { + c_str!("blobs/sha256") + } + + fn open_raw_blob(&self, digest: &Digest) -> Result { + let filename = + CString::try_from_fmt(format_args!("{}/{digest}", self.blob_path_relative()))?; + pr_info!("trying to open {:?}\n", &filename); + + let file = RegularFile::from_path_in_root_mnt( + &self.vfs_mount, + &filename, + file::flags::O_RDONLY.try_into().unwrap(), + 0, + )?; + + Ok(file) + } + + pub(crate) fn open_metadata_blob(&self, digest: &Digest) -> Result { + let f = self.open_raw_blob(digest)?; + MetadataBlob::new(f) + } + + pub(crate) fn open_rootfs_blob(&self, path: &CStr) -> Result { + let digest = Digest::try_from(path)?; + let rootfs = Rootfs::open(self.open_raw_blob(&digest)?)?; + Ok(rootfs) + } +} diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs index 1f0073716d91..76dc59403db3 100644 --- a/samples/rust/puzzlefs.rs +++ b/samples/rust/puzzlefs.rs @@ -14,7 +14,7 @@ mod puzzle; // Required by the autogenerated '_capnp.rs' files use puzzle::inode::PuzzleFS; -use puzzle::types::{Inode, InodeMode, MetadataBlob}; +use puzzle::types::{Inode, InodeMode}; use puzzle::{manifest_capnp, metadata_capnp}; use kernel::fs::{DEntry, INodeParams, NeedsRoot, NewSuperBlock, RootDEntry}; @@ -69,7 +69,7 @@ fn puzzlefs_populate_dir( return Err(E2BIG); } - let inode = Arc::try_new(pfs.find_inode(ino).map_err(|_| EINVAL)?)?; + let inode = Arc::try_new(pfs.find_inode(ino)?)?; match &inode.mode { InodeMode::File { chunks: _ } => { let params = INodeParams { @@ -154,18 +154,17 @@ fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBl }, )?; - let file = file::RegularFile::from_path_in_root_mnt( - &arc_vfs_mount, - c_str!("997eed138af30d187e87d682dd2ae9f240fae78f668907a0519460b397c82467"), - file::flags::O_RDONLY.try_into().unwrap(), - 0, - )?; + let puzzlefs = PuzzleFS::open( + arc_vfs_mount, + c_str!("2d6602d678140540dc7e96de652a76a8b16e8aca190bae141297bcffdcae901b"), + ); - // TODO: figure out how to go from WireFormatError to kernel::error::Error - let metadata = MetadataBlob::new(file).map_err(|_| EINVAL)?; + if let Err(ref e) = puzzlefs { + pr_info!("error opening puzzlefs {e}\n"); + } - let mut puzzlefs = PuzzleFS::new(metadata).map_err(|_| EINVAL)?; - let root_inode = Arc::try_new(puzzlefs.find_inode(1).map_err(|_| EINVAL)?)?; + let mut puzzlefs = puzzlefs?; + let root_inode = Arc::try_new(puzzlefs.find_inode(1)?)?; let root = try_new_populated_root_puzzlefs_dentry(&sb, &mut puzzlefs, root_inode)?; let sb = sb.init_root(root)?; From patchwork Wed Jul 26 16:45:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 247BCC001DF for ; Wed, 26 Jul 2023 16:48:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231721AbjGZQsP (ORCPT ); Wed, 26 Jul 2023 12:48:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231862AbjGZQry (ORCPT ); Wed, 26 Jul 2023 12:47:54 -0400 Received: from aer-iport-3.cisco.com (aer-iport-3.cisco.com [173.38.203.53]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A100926B9 for ; Wed, 26 Jul 2023 09:47:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=9636; q=dns/txt; s=iport; t=1690390051; x=1691599651; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PFmcSAyq0q+twl25ouvozy9tQ/05/gbjPTooN2X1b1Q=; b=f7NgAZ7SBIH/RmXrzQ8+vH2vQp2rGh8F+jy0TefklB9OVutpD4e+yZ50 GKmyO3Qx9+I+EdDqCYdTxeW6+zbeInmK6U/DdZJF5F4Q40sL4U2fSL1qb s8bXINmNblkX9YQXTlOynDxJcG7JbKx2hiGGKdv8AQK46BqRMXo1e2B4k w=; X-CSE-ConnectionGUID: N5IyJgQqSHigT8C597hZ2g== X-CSE-MsgGUID: V0qXxUGWTayV3mKfou9ceA== X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="8394938" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-3.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:26 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqU1022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:25 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 09/10] rust: puzzlefs: add support for reading files Date: Wed, 26 Jul 2023 19:45:33 +0300 Message-ID: <20230726164535.230515-10-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Each file has an associated list of file chunks, which are identified using a content addressable blob and an offset. These were generated by the `puzzlefs build` command, which uses FastCDC to split a filesystem into chunks. Signed-off-by: Ariel Miculas --- samples/rust/puzzle/inode.rs | 61 +++++++++++++++++++++++++++++++++--- samples/rust/puzzle/oci.rs | 32 +++++++++++++++---- samples/rust/puzzlefs.rs | 54 +++++++++++++------------------ 3 files changed, 105 insertions(+), 42 deletions(-) diff --git a/samples/rust/puzzle/inode.rs b/samples/rust/puzzle/inode.rs index f63cdbc1eac4..03c9f6bee75f 100644 --- a/samples/rust/puzzle/inode.rs +++ b/samples/rust/puzzle/inode.rs @@ -7,10 +7,10 @@ use crate::puzzle::types as format; use crate::puzzle::types::{Digest, Inode, InodeMode}; use alloc::vec::Vec; +use core::cmp::min; use kernel::mount::Vfsmount; -use kernel::prelude::ENOENT; +use kernel::prelude::{ENOENT, ENOTDIR}; use kernel::str::CStr; -use kernel::sync::Arc; pub(crate) struct PuzzleFS { pub(crate) oci: Image, @@ -18,8 +18,9 @@ pub(crate) struct PuzzleFS { } impl PuzzleFS { - pub(crate) fn open(vfsmount: Arc, rootfs_path: &CStr) -> Result { - let oci = Image::open(vfsmount)?; + pub(crate) fn open(oci_root_dir: &CStr, rootfs_path: &CStr) -> Result { + let vfs_mount = Vfsmount::new_private_mount(oci_root_dir)?; + let oci = Image::open(vfs_mount)?; let rootfs = oci.open_rootfs_blob(rootfs_path)?; let mut layers = Vec::new(); @@ -46,3 +47,55 @@ pub(crate) fn find_inode(&self, ino: u64) -> Result { Err(WireFormatError::from_errno(ENOENT)) } } + +pub(crate) fn file_read( + oci: &Image, + inode: &Inode, + offset: usize, + data: &mut [u8], +) -> Result { + let chunks = match &inode.mode { + InodeMode::File { chunks } => chunks, + _ => return Err(WireFormatError::from_errno(ENOTDIR)), + }; + + // TODO: fix all this casting... + let end = offset + data.len(); + + let mut file_offset = 0; + let mut buf_offset = 0; + for chunk in chunks { + // have we read enough? + if file_offset > end { + break; + } + + // should we skip this chunk? + if file_offset + (chunk.len as usize) < offset { + file_offset += chunk.len as usize; + continue; + } + + let addl_offset = if offset > file_offset { + offset - file_offset + } else { + 0 + }; + + // ok, need to read this chunk; how much? + let left_in_buf = data.len() - buf_offset; + let to_read = min(left_in_buf, chunk.len as usize - addl_offset); + + let start = buf_offset; + let finish = start + to_read; + file_offset += addl_offset; + + // how many did we actually read? + let n = oci.fill_from_chunk(chunk.blob, addl_offset as u64, &mut data[start..finish])?; + file_offset += n; + buf_offset += n; + } + + // discard any extra if we hit EOF + Ok(buf_offset) +} diff --git a/samples/rust/puzzle/oci.rs b/samples/rust/puzzle/oci.rs index becb2b868450..5aa60ded8419 100644 --- a/samples/rust/puzzle/oci.rs +++ b/samples/rust/puzzle/oci.rs @@ -1,19 +1,21 @@ -use crate::puzzle::error::Result; +use crate::puzzle::error::{Result, WireFormatError}; +use crate::puzzle::types as format; use crate::puzzle::types::{Digest, MetadataBlob, Rootfs}; use kernel::c_str; use kernel::file; use kernel::file::RegularFile; use kernel::mount::Vfsmount; -use kernel::pr_info; +use kernel::pr_debug; +use kernel::prelude::ENOTSUPP; use kernel::str::{CStr, CString}; -use kernel::sync::Arc; +#[derive(Debug)] pub(crate) struct Image { - vfs_mount: Arc, + pub(crate) vfs_mount: Vfsmount, } impl Image { - pub(crate) fn open(vfsmount: Arc) -> Result { + pub(crate) fn open(vfsmount: Vfsmount) -> Result { Ok(Image { vfs_mount: vfsmount, }) @@ -26,7 +28,7 @@ pub(crate) fn blob_path_relative(&self) -> &CStr { fn open_raw_blob(&self, digest: &Digest) -> Result { let filename = CString::try_from_fmt(format_args!("{}/{digest}", self.blob_path_relative()))?; - pr_info!("trying to open {:?}\n", &filename); + pr_debug!("trying to open {:?}\n", &*filename); let file = RegularFile::from_path_in_root_mnt( &self.vfs_mount, @@ -48,4 +50,22 @@ pub(crate) fn open_rootfs_blob(&self, path: &CStr) -> Result { let rootfs = Rootfs::open(self.open_raw_blob(&digest)?)?; Ok(rootfs) } + + pub(crate) fn fill_from_chunk( + &self, + chunk: format::BlobRef, + addl_offset: u64, + buf: &mut [u8], + ) -> Result { + let digest = &::try_from(chunk)?; + + let blob = if chunk.compressed { + return Err(WireFormatError::KernelError(ENOTSUPP)); + } else { + self.open_raw_blob(digest)? + }; + + let n = blob.read_with_offset(buf, chunk.offset + addl_offset)?; + Ok(n) + } } diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs index 76dc59403db3..dad7ecc76eca 100644 --- a/samples/rust/puzzlefs.rs +++ b/samples/rust/puzzlefs.rs @@ -3,7 +3,6 @@ //! Rust file system sample. use kernel::module_fs; -use kernel::mount::Vfsmount; use kernel::prelude::*; use kernel::{ c_str, file, fs, @@ -13,7 +12,7 @@ mod puzzle; // Required by the autogenerated '_capnp.rs' files -use puzzle::inode::PuzzleFS; +use puzzle::inode::{file_read, PuzzleFS}; use puzzle::types::{Inode, InodeMode}; use puzzle::{manifest_capnp, metadata_capnp}; @@ -28,9 +27,8 @@ struct PuzzleFsModule; -#[derive(Debug)] struct PuzzlefsInfo { - vfs_mount: Arc, + puzzlefs: Arc, } #[vtable] @@ -139,14 +137,20 @@ impl fs::Type for PuzzleFsModule { const DCACHE_BASED: bool = true; fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock> { - let vfs_mount = Vfsmount::new_private_mount(c_str!("/home/puzzlefs_oci"))?; - pr_info!("vfs_mount {:?}\n", vfs_mount); + let puzzlefs = PuzzleFS::open( + c_str!("/home/puzzlefs_oci"), + c_str!("2d6602d678140540dc7e96de652a76a8b16e8aca190bae141297bcffdcae901b"), + ); - let arc_vfs_mount = Arc::try_new(vfs_mount)?; + if let Err(ref e) = puzzlefs { + pr_info!("error opening puzzlefs {e}\n"); + } + + let puzzlefs = Arc::try_new(puzzlefs?)?; let sb = sb.init( Box::try_new(PuzzlefsInfo { - vfs_mount: arc_vfs_mount.clone(), + puzzlefs: puzzlefs.clone(), })?, &fs::SuperParams { magic: 0x72757374, @@ -154,19 +158,9 @@ fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBl }, )?; - let puzzlefs = PuzzleFS::open( - arc_vfs_mount, - c_str!("2d6602d678140540dc7e96de652a76a8b16e8aca190bae141297bcffdcae901b"), - ); - - if let Err(ref e) = puzzlefs { - pr_info!("error opening puzzlefs {e}\n"); - } - - let mut puzzlefs = puzzlefs?; let root_inode = Arc::try_new(puzzlefs.find_inode(1)?)?; - let root = try_new_populated_root_puzzlefs_dentry(&sb, &mut puzzlefs, root_inode)?; + let root = try_new_populated_root_puzzlefs_dentry(&sb, &puzzlefs, root_inode)?; let sb = sb.init_root(root)?; Ok(sb) } @@ -180,32 +174,28 @@ impl file::Operations for FsFile { type OpenData = Arc; type Filesystem = PuzzleFsModule; // this is an Arc because Data must be ForeignOwnable and the only implementors of it are Box, - // Arc and (); we cannot pass a reference to read, so we share Vfsmount using and Arc - type Data = Arc; + // Arc and (); we cannot pass a reference to the read callback, so we share PuzzleFS using Arc + type Data = Arc; fn open( fs_info: &PuzzlefsInfo, _context: &Self::OpenData, _file: &file::File, ) -> Result { - Ok(fs_info.vfs_mount.clone()) + Ok(fs_info.puzzlefs.clone()) } fn read( - data: ArcBorrow<'_, Vfsmount>, - _file: &file::File, + data: ArcBorrow<'_, PuzzleFS>, + file: &file::File, writer: &mut impl IoBufferWriter, offset: u64, ) -> Result { + let inode = file.inode::().ok_or(EINVAL)?.fs_data(); let mut buf = Vec::try_with_capacity(writer.len())?; buf.try_resize(writer.len(), 0)?; - let file = file::RegularFile::from_path_in_root_mnt( - &data, - c_str!("data"), - file::flags::O_RDONLY.try_into().unwrap(), - 0, - )?; - let nr_bytes_read = file.read_with_offset(&mut buf[..], offset)?; - file::read_from_slice(&buf[..nr_bytes_read], writer, 0) + let read = file_read(&data.oci, inode, offset as usize, &mut buf)?; + buf.truncate(read); + file::read_from_slice(&buf, writer, 0) } } From patchwork Wed Jul 26 16:45:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ariel Miculas X-Patchwork-Id: 13328375 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 85DFCC41513 for ; Wed, 26 Jul 2023 16:48:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230115AbjGZQsM (ORCPT ); Wed, 26 Jul 2023 12:48:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34700 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231896AbjGZQrz (ORCPT ); Wed, 26 Jul 2023 12:47:55 -0400 Received: from aer-iport-2.cisco.com (aer-iport-2.cisco.com [173.38.203.52]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A8B2026BB for ; Wed, 26 Jul 2023 09:47:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=4334; q=dns/txt; s=iport; t=1690390052; x=1691599652; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7RIRVvP4MKCFvgB/74OSuv2zzERdm/ln1FIu9qAS8CY=; b=RKNTTHqgLg26sp1ZBoXYiFP6KGuPGD83EWixev3hTMZWg6gcTqhNRnIE zpyuQrlFQJE89/wjMKqMBz2u0V2o95of5t18w9asKHzVA0u/EGfBX+cto xUiAZGVWPsTOH9UlKWOhS1KfFD9srk7ifNybgfYpno9u3VDJICvMuorU4 c=; X-IronPort-AV: E=Sophos;i="6.01,232,1684800000"; d="scan'208";a="8452952" Received: from aer-iport-nat.cisco.com (HELO aer-core-7.cisco.com) ([173.38.203.22]) by aer-iport-2.cisco.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jul 2023 16:46:27 +0000 Received: from archlinux-cisco.cisco.com (dhcp-10-61-98-211.cisco.com [10.61.98.211]) (authenticated bits=0) by aer-core-7.cisco.com (8.15.2/8.15.2) with ESMTPSA id 36QGjqU2022602 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 26 Jul 2023 16:46:27 GMT From: Ariel Miculas To: rust-for-linux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, tycho@tycho.pizza, brauner@kernel.org, viro@zeniv.linux.org.uk, ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, Ariel Miculas Subject: [RFC PATCH v2 10/10] rust: puzzlefs: add oci_root_dir and image_manifest filesystem parameters Date: Wed, 26 Jul 2023 19:45:34 +0300 Message-ID: <20230726164535.230515-11-amiculas@cisco.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com> References: <20230726164535.230515-1-amiculas@cisco.com> MIME-Version: 1.0 X-Authenticated-User: amiculas X-Outbound-SMTP-Client: 10.61.98.211, dhcp-10-61-98-211.cisco.com X-Outbound-Node: aer-core-7.cisco.com Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org These parameters are passed when mounting puzzlefs using '-o' option of mount: -o oci_root_dir="/path/to/oci/dir" -o image_manifest="root_hash_of_image_manifest" For a particular manifest in the manifests array in index.json (located in the oci_root_dir), the root hash of the image manifest is found in the digest field. It would be nicer if we could pass the tag, but we don't support json deserialization. Example of mount: mount -t puzzlefs -o oci_root_dir="/home/puzzlefs_oci" -o \ image_manifest="2d6602d678140540dc7e96de652a76a8b16e8aca190bae141297bcffdcae901b" \ none /mnt Signed-off-by: Ariel Miculas --- samples/rust/puzzlefs.rs | 63 ++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/samples/rust/puzzlefs.rs b/samples/rust/puzzlefs.rs index dad7ecc76eca..4e9a8aedf0c1 100644 --- a/samples/rust/puzzlefs.rs +++ b/samples/rust/puzzlefs.rs @@ -7,6 +7,7 @@ use kernel::{ c_str, file, fs, io_buffer::IoBufferWriter, + str::CString, sync::{Arc, ArcBorrow}, }; @@ -31,27 +32,29 @@ struct PuzzlefsInfo { puzzlefs: Arc, } +#[derive(Default)] +struct PuzzleFsParams { + oci_root_dir: Option, + image_manifest: Option, +} + #[vtable] impl fs::Context for PuzzleFsModule { - type Data = (); - - kernel::define_fs_params! {(), - {flag, "flag", |_, v| { pr_info!("flag passed-in: {v}\n"); Ok(()) } }, - {flag_no, "flagno", |_, v| { pr_info!("flagno passed-in: {v}\n"); Ok(()) } }, - {bool, "bool", |_, v| { pr_info!("bool passed-in: {v}\n"); Ok(()) } }, - {u32, "u32", |_, v| { pr_info!("u32 passed-in: {v}\n"); Ok(()) } }, - {u32oct, "u32oct", |_, v| { pr_info!("u32oct passed-in: {v}\n"); Ok(()) } }, - {u32hex, "u32hex", |_, v| { pr_info!("u32hex passed-in: {v}\n"); Ok(()) } }, - {s32, "s32", |_, v| { pr_info!("s32 passed-in: {v}\n"); Ok(()) } }, - {u64, "u64", |_, v| { pr_info!("u64 passed-in: {v}\n"); Ok(()) } }, - {string, "string", |_, v| { pr_info!("string passed-in: {v}\n"); Ok(()) } }, - {enum, "enum", [("first", 10), ("second", 20)], |_, v| { - pr_info!("enum passed-in: {v}\n"); Ok(()) } - }, + type Data = Box; + + kernel::define_fs_params! {Box, + {string, "oci_root_dir", |s, v| { + s.oci_root_dir = Some(CString::try_from_fmt(format_args!("{v}"))?); + Ok(()) + }}, + {string, "image_manifest", |s, v| { + s.image_manifest = Some(CString::try_from_fmt(format_args!("{v}"))?); + Ok(()) + }}, } - fn try_new() -> Result { - Ok(()) + fn try_new() -> Result { + Ok(Box::try_new(PuzzleFsParams::default())?) } } @@ -136,11 +139,27 @@ impl fs::Type for PuzzleFsModule { const FLAGS: i32 = fs::flags::USERNS_MOUNT; const DCACHE_BASED: bool = true; - fn fill_super(_data: (), sb: fs::NewSuperBlock<'_, Self>) -> Result<&fs::SuperBlock> { - let puzzlefs = PuzzleFS::open( - c_str!("/home/puzzlefs_oci"), - c_str!("2d6602d678140540dc7e96de652a76a8b16e8aca190bae141297bcffdcae901b"), - ); + fn fill_super( + data: Box, + sb: fs::NewSuperBlock<'_, Self>, + ) -> Result<&fs::SuperBlock> { + let oci_root_dir = match data.oci_root_dir { + Some(val) => val, + None => { + pr_err!("missing oci_root_dir parameter!\n"); + return Err(ENOTSUPP); + } + }; + + let image_manifest = match data.image_manifest { + Some(val) => val, + None => { + pr_err!("missing image_manifest parameter!\n"); + return Err(ENOTSUPP); + } + }; + + let puzzlefs = PuzzleFS::open(&oci_root_dir, &image_manifest); if let Err(ref e) = puzzlefs { pr_info!("error opening puzzlefs {e}\n");