From: Ariel Miculas <amiculas@cisco.com>
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 <amiculas@cisco.com>
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 [thread overview]
Message-ID: <20230726164535.230515-9-amiculas@cisco.com> (raw)
In-Reply-To: <20230726164535.230515-1-amiculas@cisco.com>
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 <amiculas@cisco.com>
---
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<format::MetadataBlob>,
}
impl PuzzleFS {
- pub(crate) fn new(md: MetadataBlob) -> Result<Self> {
- let mut v = Vec::new();
- v.try_push(md)?;
- Ok(PuzzleFS { layers: v })
+ pub(crate) fn open(vfsmount: Arc<Vfsmount>, rootfs_path: &CStr) -> Result<PuzzleFS> {
+ 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<Inode> {
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<Vfsmount>,
+}
+
+impl Image {
+ pub(crate) fn open(vfsmount: Arc<Vfsmount>) -> Result<Self> {
+ 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<RegularFile> {
+ 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<MetadataBlob> {
+ let f = self.open_raw_blob(digest)?;
+ MetadataBlob::new(f)
+ }
+
+ pub(crate) fn open_rootfs_blob(&self, path: &CStr) -> Result<Rootfs> {
+ 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)?;
--
2.41.0
next prev parent reply other threads:[~2023-07-26 16:58 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-26 16:45 [RFC PATCH v2 00/10] Rust PuzleFS filesystem driver Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 01/10] samples: puzzlefs: add initial puzzlefs sample, copied from rust_fs.rs Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 02/10] kernel: configs: enable rust samples in rust.config Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 03/10] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount Ariel Miculas
2023-07-26 22:34 ` Trevor Gross
2023-07-27 13:10 ` Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 04/10] rust: file: Add a new RegularFile newtype useful for reading files Ariel Miculas
2023-07-26 23:52 ` Trevor Gross
2023-07-27 13:18 ` Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 05/10] samples: puzzlefs: add basic deserializing support for the puzzlefs metadata Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 06/10] rust: file: pass the filesystem context to the open function Ariel Miculas
2023-07-27 13:32 ` Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 07/10] samples: puzzlefs: populate the directory entries with the inodes from the puzzlefs metadata file Ariel Miculas
2023-07-26 16:45 ` Ariel Miculas [this message]
2023-07-26 16:45 ` [RFC PATCH v2 09/10] rust: puzzlefs: add support for reading files Ariel Miculas
2023-07-26 16:45 ` [RFC PATCH v2 10/10] rust: puzzlefs: add oci_root_dir and image_manifest filesystem parameters Ariel Miculas
2023-07-26 21:08 ` Trevor Gross
2023-07-26 23:47 ` Wedson Almeida Filho
2023-07-27 0:02 ` Trevor Gross
2023-07-27 8:06 ` Wedson Almeida Filho
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230726164535.230515-9-amiculas@cisco.com \
--to=amiculas@cisco.com \
--cc=alex.gaynor@gmail.com \
--cc=brauner@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tycho@tycho.pizza \
--cc=viro@zeniv.linux.org.uk \
--cc=wedsonaf@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).