rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ariel Miculas <amiculas@cisco.com>
To: rust-for-linux@vger.kernel.org
Cc: Wedson Almeida Filho <wedsonaf@google.com>
Subject: [PATCH 03/80] rust: define fs context
Date: Fri,  9 Jun 2023 09:30:01 +0300	[thread overview]
Message-ID: <20230609063118.24852-4-amiculas@cisco.com> (raw)
In-Reply-To: <20230609063118.24852-1-amiculas@cisco.com>

From: Wedson Almeida Filho <wedsonaf@google.com>

Also make fs mountable, but empty for now.

Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com>
---
 rust/bindings/bindings_helper.h |   3 +
 rust/bindings/lib.rs            |   2 +
 rust/helpers.c                  |  12 ++
 rust/kernel/error.rs            |  46 +++++++
 rust/kernel/fs.rs               | 224 ++++++++++++++++++++++++++++++--
 rust/kernel/lib.rs              |   5 +
 samples/rust/rust_fs.rs         |  13 ++
 7 files changed, 297 insertions(+), 8 deletions(-)

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index eeb5b7c0528a..556f2e7c3ddb 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -11,7 +11,10 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
+#include <linux/fs_parser.h>
 
 /* `bindgen` gets confused at certain things. */
 const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
 const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
+
+const loff_t BINDINGS_MAX_LFS_FILESIZE = MAX_LFS_FILESIZE;
diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs
index 9bcbea04dac3..cd1fceb31390 100644
--- a/rust/bindings/lib.rs
+++ b/rust/bindings/lib.rs
@@ -51,3 +51,5 @@ mod bindings_helper {
 
 pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;
 pub const __GFP_ZERO: gfp_t = BINDINGS___GFP_ZERO;
+
+pub const MAX_LFS_FILESIZE: loff_t = BINDINGS_MAX_LFS_FILESIZE;
diff --git a/rust/helpers.c b/rust/helpers.c
index e00c53c94c43..d6f277c3b7a7 100644
--- a/rust/helpers.c
+++ b/rust/helpers.c
@@ -135,6 +135,18 @@ struct dentry *rust_helper_dget(struct dentry *dentry)
 }
 EXPORT_SYMBOL_GPL(rust_helper_dget);
 
+void rust_helper_lockdep_register_key(struct lock_class_key *key)
+{
+	lockdep_register_key(key);
+}
+EXPORT_SYMBOL_GPL(rust_helper_lockdep_register_key);
+
+void rust_helper_lockdep_unregister_key(struct lock_class_key *key)
+{
+	lockdep_unregister_key(key);
+}
+EXPORT_SYMBOL_GPL(rust_helper_lockdep_unregister_key);
+
 /*
  * 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 7c1ce2bccd08..231f7dfd8005 100644
--- a/rust/kernel/error.rs
+++ b/rust/kernel/error.rs
@@ -296,3 +296,49 @@ pub(crate) fn from_result<T, F>(f: F) -> T
         Err(e) => T::from(e.to_errno() as i16),
     }
 }
+
+pub(crate) fn from_kernel_result_helper<T>(r: Result<T>) -> T
+where
+    T: From<i16>,
+{
+    match r {
+        Ok(v) => v,
+        // NO-OVERFLOW: negative `errno`s are no smaller than `-bindings::MAX_ERRNO`,
+        // `-bindings::MAX_ERRNO` fits in an `i16` as per invariant above,
+        // therefore a negative `errno` always fits in an `i16` and will not overflow.
+        Err(e) => T::from(e.to_errno() as i16),
+    }
+}
+
+/// Transforms a [`crate::error::Result<T>`] to a kernel C integer result.
+///
+/// This is useful when calling Rust functions that return [`crate::error::Result<T>`]
+/// from inside `extern "C"` functions that need to return an integer
+/// error result.
+///
+/// `T` should be convertible to an `i16` via `From<i16>`.
+///
+/// # Examples
+///
+/// ```ignore
+/// # use kernel::from_kernel_result;
+/// # use kernel::bindings;
+/// unsafe extern "C" fn probe_callback(
+///     pdev: *mut bindings::platform_device,
+/// ) -> core::ffi::c_int {
+///     from_kernel_result! {
+///         let ptr = devm_alloc(pdev)?;
+///         bindings::platform_set_drvdata(pdev, ptr);
+///         Ok(0)
+///     }
+/// }
+/// ```
+macro_rules! from_kernel_result {
+    ($($tt:tt)*) => {{
+        $crate::error::from_kernel_result_helper((|| {
+            $($tt)*
+        })())
+    }};
+}
+
+pub(crate) use from_kernel_result;
diff --git a/rust/kernel/fs.rs b/rust/kernel/fs.rs
index b61e6f03e871..187f0c19dcd0 100644
--- a/rust/kernel/fs.rs
+++ b/rust/kernel/fs.rs
@@ -5,15 +5,162 @@
 //! C headers: [`include/linux/fs.h`](../../../../include/linux/fs.h)
 
 use crate::{bindings, error::code::*, str::CStr, ThisModule};
-use crate::error::{to_result, Result};
-use crate::types::AlwaysRefCounted;
+use crate::error::{to_result, from_kernel_result, Result};
+use crate::types::{AlwaysRefCounted, ForeignOwnable, ScopeGuard};
 use core::{cell::UnsafeCell, marker::PhantomPinned, pin::Pin, ptr};
+use macros::vtable;
+
+/// A file system context.
+///
+/// It is used to gather configuration to then mount or reconfigure a file system.
+#[vtable]
+pub trait Context<T: Type + ?Sized> {
+    /// Type of the data associated with the context.
+    type Data: ForeignOwnable + Send + Sync + 'static;
+
+    /// Creates a new context.
+    fn try_new() -> Result<Self::Data>;
+}
+
+struct Tables<T: Type + ?Sized>(T);
+impl<T: Type + ?Sized> Tables<T> {
+    const CONTEXT: bindings::fs_context_operations = bindings::fs_context_operations {
+        free: Some(Self::free_callback),
+        parse_param: None,
+        get_tree: Some(Self::get_tree_callback),
+        reconfigure: Some(Self::reconfigure_callback),
+        parse_monolithic: None,
+        dup: None,
+    };
+
+    unsafe extern "C" fn free_callback(fc: *mut bindings::fs_context) {
+        // SAFETY: The callback contract guarantees that `fc` is valid.
+        let ptr = unsafe { (*fc).fs_private };
+        if !ptr.is_null() {
+            // SAFETY: `fs_private` was initialised with the result of a `to_pointer` call in
+            // `init_fs_context_callback`, so it's ok to call `from_foreign` here.
+            unsafe { <T::Context as Context<T>>::Data::from_foreign(ptr) };
+        }
+    }
+
+    unsafe extern "C" fn fill_super_callback(
+        sb_ptr: *mut bindings::super_block,
+        _fc: *mut bindings::fs_context,
+    ) -> core::ffi::c_int {
+        from_kernel_result! {
+            // The following is temporary code to create the root inode and dentry. It will be
+            // replaced with calls to Rust code.
+
+            // SAFETY: The callback contract guarantees that `sb_ptr` is the only pointer to a
+            // newly-allocated superblock, so it is safe to mutably reference it.
+            let sb = unsafe { &mut *sb_ptr };
+
+            sb.s_maxbytes = bindings::MAX_LFS_FILESIZE;
+            sb.s_blocksize = crate::PAGE_SIZE as _;
+            sb.s_blocksize_bits = bindings::PAGE_SHIFT as _;
+            sb.s_magic = T::MAGIC as _;
+            sb.s_op = &Tables::<T>::SUPER_BLOCK;
+            sb.s_time_gran = 1;
+
+            // Create and initialise the root inode.
+            let inode = unsafe { bindings::new_inode(sb) };
+            if inode.is_null() {
+                return Err(ENOMEM);
+            }
+
+            {
+                // SAFETY: This is a newly-created inode. No other references to it exist, so it is
+                // safe to mutably dereference it.
+                let inode = unsafe { &mut *inode };
+
+                // SAFETY: `current_time` requires that `inode.sb` be valid, which is the case here
+                // since we allocated the inode through the superblock.
+                let time = unsafe { bindings::current_time(inode) };
+                inode.i_ino = 1;
+                inode.i_mode = (bindings::S_IFDIR | 0o755) as _;
+                inode.i_mtime = time;
+                inode.i_atime = time;
+                inode.i_ctime = time;
+
+                // SAFETY: `simple_dir_operations` never changes, it's safe to reference it.
+                inode.__bindgen_anon_3.i_fop = unsafe { &bindings::simple_dir_operations };
+
+                // SAFETY: `simple_dir_inode_operations` never changes, it's safe to reference it.
+                inode.i_op = unsafe { &bindings::simple_dir_inode_operations };
+
+                // SAFETY: `inode` is valid for write.
+                unsafe { bindings::set_nlink(inode, 2) };
+            }
+
+            // SAFETY: `d_make_root` requires that `inode` be valid and referenced, which is the
+            // case for this call.
+            //
+            // It takes over the inode, even on failure, so we don't need to clean it up.
+            let dentry = unsafe { bindings::d_make_root(inode) };
+            if dentry.is_null() {
+                return Err(ENOMEM);
+            }
+
+            sb.s_root = dentry;
+            Ok(0)
+        }
+    }
+
+    unsafe extern "C" fn get_tree_callback(fc: *mut bindings::fs_context) -> core::ffi::c_int {
+        // SAFETY: `fc` is valid per the callback contract. `fill_super_callback` also has the
+        // right type and is a valid callback.
+        unsafe { bindings::get_tree_nodev(fc, Some(Self::fill_super_callback)) }
+    }
+
+    unsafe extern "C" fn reconfigure_callback(_fc: *mut bindings::fs_context) -> core::ffi::c_int {
+        EINVAL.to_errno()
+    }
+
+    const SUPER_BLOCK: bindings::super_operations = bindings::super_operations {
+        alloc_inode: None,
+        destroy_inode: None,
+        free_inode: None,
+        dirty_inode: None,
+        write_inode: None,
+        drop_inode: None,
+        evict_inode: None,
+        put_super: None,
+        sync_fs: None,
+        freeze_super: None,
+        freeze_fs: None,
+        thaw_super: None,
+        unfreeze_fs: None,
+        statfs: None,
+        remount_fs: None,
+        umount_begin: None,
+        show_options: None,
+        show_devname: None,
+        show_path: None,
+        show_stats: None,
+        #[cfg(CONFIG_QUOTA)]
+        quota_read: None,
+        #[cfg(CONFIG_QUOTA)]
+        quota_write: None,
+        #[cfg(CONFIG_QUOTA)]
+        get_dquots: None,
+        nr_cached_objects: None,
+        free_cached_objects: None,
+    };
+}
 
 /// A file system type.
 pub trait Type {
+    /// The context used to build fs configuration before it is mounted or reconfigured.
+    type Context: Context<Self> + ?Sized;
+
     /// The name of the file system type.
     const NAME: &'static CStr;
 
+    /// The magic number associated with the file system.
+    ///
+    /// This is normally one of the values in `include/uapi/linux/magic.h`.
+    const MAGIC: u32;
+
     /// The flags of this file system type.
     ///
     /// It is a combination of the flags in the [`flags`] module.
@@ -80,7 +227,7 @@ pub fn new() -> Self {
     /// The file system is described by the [`Type`] argument.
     ///
     /// It is automatically unregistered when the registration is dropped.
-    pub fn register<T: Type>(self: Pin<&mut Self>, module: &'static ThisModule) -> Result {
+    pub fn register<T: Type + ?Sized>(self: Pin<&mut Self>, module: &'static ThisModule) -> Result {
         // SAFETY: We never move out of `this`.
         let this = unsafe { self.get_unchecked_mut() };
 
@@ -94,20 +241,81 @@ pub fn register<T: Type>(self: Pin<&mut Self>, module: &'static ThisModule) -> R
         fs.fs_flags = T::FLAGS;
         fs.init_fs_context = Some(Self::init_fs_context_callback::<T>);
         fs.kill_sb = Some(Self::kill_sb_callback::<T>);
+
+        // SAFETY: This block registers all fs type keys with lockdep. We just need the memory
+        // locations to be owned by the caller, which is the case.
+        unsafe {
+            bindings::lockdep_register_key(&mut fs.s_lock_key);
+            bindings::lockdep_register_key(&mut fs.s_umount_key);
+            bindings::lockdep_register_key(&mut fs.s_vfs_rename_key);
+            bindings::lockdep_register_key(&mut fs.i_lock_key);
+            bindings::lockdep_register_key(&mut fs.i_mutex_key);
+            bindings::lockdep_register_key(&mut fs.invalidate_lock_key);
+            bindings::lockdep_register_key(&mut fs.i_mutex_dir_key);
+            for key in &mut fs.s_writers_key {
+                bindings::lockdep_register_key(key);
+            }
+        }
+
+        let ptr = this.fs.get();
+
+        // SAFETY: `ptr` as valid as it points to the `self.fs`.
+        let key_guard = ScopeGuard::new(|| unsafe { Self::unregister_keys(ptr) });
+
         // SAFETY: Pointers stored in `fs` are either static so will live for as long as the
         // registration is active (it is undone in `drop`).
-        to_result(unsafe { bindings::register_filesystem(this.fs.get()) })?;
+        to_result(unsafe { bindings::register_filesystem(ptr) })?;
+        key_guard.dismiss();
         this.is_registered = true;
         Ok(())
     }
 
-    unsafe extern "C" fn init_fs_context_callback<T: Type>(
-        _fc_ptr: *mut bindings::fs_context,
+    /// Unregisters the lockdep keys in the file system type.
+    ///
+    /// # Safety
+    ///
+    /// `fs` must be non-null and valid.
+    unsafe fn unregister_keys(fs: *mut bindings::file_system_type) {
+        // SAFETY: This block unregisters all fs type keys from lockdep. They must have been
+        // registered before.
+        unsafe {
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).s_lock_key));
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).s_umount_key));
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).s_vfs_rename_key));
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).i_lock_key));
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).i_mutex_key));
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).invalidate_lock_key));
+            bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).i_mutex_dir_key));
+            for i in 0..(*fs).s_writers_key.len() {
+                bindings::lockdep_unregister_key(ptr::addr_of_mut!((*fs).s_writers_key[i]));
+            }
+        }
+    }
+
+    unsafe extern "C" fn init_fs_context_callback<T: Type + ?Sized>(
+        fc_ptr: *mut bindings::fs_context,
     ) -> core::ffi::c_int {
-        EINVAL.to_errno()
+        from_kernel_result! {
+            let data = T::Context::try_new()?;
+            // SAFETY: The callback contract guarantees that `fc_ptr` is the only pointer to a
+            // newly-allocated fs context, so it is safe to mutably reference it.
+            let fc = unsafe { &mut *fc_ptr };
+            fc.fs_private = data.into_foreign() as _;
+            fc.ops = &Tables::<T>::CONTEXT;
+            Ok(0)
+        }
     }
 
-    unsafe extern "C" fn kill_sb_callback<T: Type>(_sb_ptr: *mut bindings::super_block) {}
+    unsafe extern "C" fn kill_sb_callback<T: Type + ?Sized>(sb_ptr: *mut bindings::super_block) {
+        // SAFETY: We always call `get_tree_nodev` from `get_tree_callback`, so we never have a
+        // device, so it is ok to call the function below. Additionally, the callback contract
+        // guarantees that `sb_ptr` is valid.
+        unsafe { bindings::kill_anon_super(sb_ptr) }
+
+        // SAFETY: The callback contract guarantees that `sb_ptr` is valid, and the `kill_sb`
+        // callback being called implies that the `s_type` is also valid.
+        unsafe { Self::unregister_keys((*sb_ptr).s_type) };
+    }
 }
 
 impl Drop for Registration {
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index 486f60912132..48da79b02422 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -98,3 +98,8 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
     // instead of `!`. See <https://github.com/rust-lang/rust-bindgen/issues/2094>.
     loop {}
 }
+
+/// Page size defined in terms of the `PAGE_SHIFT` macro from C.
+///
+/// [`PAGE_SHIFT`]: ../../../include/asm-generic/page.h
+pub const PAGE_SIZE: usize = 1 << bindings::PAGE_SHIFT;
diff --git a/samples/rust/rust_fs.rs b/samples/rust/rust_fs.rs
index 2caacea50e73..2bd4e563c694 100644
--- a/samples/rust/rust_fs.rs
+++ b/samples/rust/rust_fs.rs
@@ -13,9 +13,22 @@
 }
 
 struct RustFs;
+
+#[vtable]
+impl fs::Context<Self> for RustFs {
+    type Data = ();
+
+    fn try_new() -> Result {
+        pr_info!("context created!\n");
+        Ok(())
+    }
+}
+
 impl fs::Type for RustFs {
+    type Context = Self;
     const NAME: &'static CStr = c_str!("rustfs");
     const FLAGS: i32 = fs::flags::USERNS_MOUNT;
+    const MAGIC: u32 = 0x72757374;
 }
 
 struct FsModule {
-- 
2.40.1


  parent reply	other threads:[~2023-06-09  6:54 UTC|newest]

Thread overview: 134+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-09  6:29 [RFC PATCH 00/80] Rust PuzzleFS filesystem driver Ariel Miculas
2023-06-09  6:29 ` [PATCH 01/80] rust: add definitions for ref-counted inodes and dentries Ariel Miculas
2023-06-09  6:30 ` [PATCH 02/80] rust: add ability to register a file system Ariel Miculas
2023-06-09  9:23   ` Miguel Ojeda
2023-06-09  6:30 ` Ariel Miculas [this message]
2023-06-09  6:30 ` [PATCH 04/80] rust: add support for file system parameters Ariel Miculas
2023-06-09  6:30 ` [PATCH 05/80] rust: kernel: add libraries required by the filesystem abstractions Ariel Miculas
2023-06-09  9:46   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 06/80] rust: allow fs driver to initialise new superblocks Ariel Miculas
2023-06-09  6:30 ` [PATCH 07/80] rust: add `module_fs` macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 08/80] WIP: rust: allow fs to be populated Ariel Miculas
2023-06-09  6:30 ` [PATCH 09/80] rust: kernel: backport the delay module from the rust branch Ariel Miculas
2023-06-09  9:29   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 10/80] rust: kernel: add container_of macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 11/80] rust: kernel: add offset_of macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 12/80] drop: Add crate::pr_warn declaration Ariel Miculas
2023-06-09  9:29   ` Miguel Ojeda
2023-06-09 10:46     ` Ariel Miculas (amiculas)
2023-06-09  6:30 ` [PATCH 13/80] rust: kernel: rename from_kernel_errno to from_errno Ariel Miculas
2023-06-09  9:56   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 14/80] rust: kernel: Rename from_pointer to from_foreing and into_pointer to into_foreign Ariel Miculas
2023-06-09  9:57   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 15/80] rust: kernel: add count_paren_items macro, needed by define_fs_params macro Ariel Miculas
2023-06-09  6:30 ` [PATCH 16/80] rust: helpers: add missing rust helper 'alloc_pages' Ariel Miculas
2023-06-09  9:57   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 17/80] kernel: configs: add qemu-busybox-min.config Ariel Miculas
2023-06-09  9:39   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 18/80] rust: kernel: format the rust code Ariel Miculas
2023-06-09  9:21   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 19/80] samples: puzzlefs: add initial puzzlefs sample, copied from rust_fs.rs Ariel Miculas
2023-06-09  6:30 ` [PATCH 20/80] kernel: configs: enable rust samples in rust.config Ariel Miculas
2023-06-09  9:25   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 22/80] rust: proc-macro2: add SPDX License Identifiers Ariel Miculas
2023-06-09  6:30 ` [PATCH 23/80] rust: proc-macro2: remove `unicode_ident` dependency Ariel Miculas
2023-06-09  6:30 ` [PATCH 24/80] rust: quote: import crate Ariel Miculas
2023-06-09  6:30 ` [PATCH 25/80] rust: quote: add SPDX License Identifiers Ariel Miculas
2023-06-09  6:30 ` [PATCH 27/80] rust: syn: " Ariel Miculas
2023-06-09  6:30 ` [PATCH 28/80] rust: syn: remove `unicode-ident` dependency Ariel Miculas
2023-06-09  6:30 ` [PATCH 30/80] rust: serde: add `no_fp_fmt_parse` support Ariel Miculas
2023-06-09  6:30 ` [PATCH 31/80] rust: serde: add SPDX License Identifiers Ariel Miculas
2023-06-10  0:19   ` Kent Overstreet
2023-06-10  6:43     ` Greg KH
2023-06-10 13:18       ` Kent Overstreet
2023-06-10 15:28         ` Greg KH
2023-06-10  0:25   ` Kent Overstreet
2023-06-10  9:04     ` Andreas Hindborg (Samsung)
2023-06-10 13:20       ` Kent Overstreet
2023-06-12  8:56         ` Ariel Miculas
2023-06-10  9:33     ` Miguel Ojeda
2023-06-12 11:58     ` Ariel Miculas
2023-06-15 15:05     ` Ariel Miculas
2023-06-17 16:04       ` Kent Overstreet
2023-06-09  6:30 ` [PATCH 33/80] rust: serde_derive: " Ariel Miculas
2023-06-09  6:30 ` [PATCH 34/80] rust: Kbuild: enable `proc-macro2`, `quote`, `syn`, `serde` and `serde_derive` Ariel Miculas
2023-06-09  6:30 ` [PATCH 35/80] rust: test `serde` support Ariel Miculas
2023-06-09  6:30 ` [PATCH 36/80] Add SAMPLE_RUST_SERDE in rust.config Ariel Miculas
2023-06-09  6:30 ` [PATCH 37/80] rust: kernel: fix compile errors after rebase to rust-next Ariel Miculas
2023-06-09  9:38   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 39/80] rust: serde_cbor: add SPDX License Identifiers Ariel Miculas
2023-06-09  6:30 ` [PATCH 40/80] rust: serde_cbor: add no_fp_fmt_parse support Ariel Miculas
2023-06-09  6:30 ` [PATCH 41/80] rust: Kbuild: enable serde_cbor Ariel Miculas
2023-06-09 10:21   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 42/80] samples: rust: add cbor serialize/deserialize example Ariel Miculas
2023-06-09  6:30 ` [PATCH 43/80] rust: serde_cbor: add support for serde_cbor's from_slice method by using a custom alloc_kernel feature Ariel Miculas
2023-06-09  9:55   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 44/80] rust: serde: add support for deserializing Vec with kernel_alloc feature Ariel Miculas
2023-06-09 10:10   ` Miguel Ojeda
2023-06-09  6:30 ` [PATCH 45/80] rust: file: Replace UnsafeCell with Opaque for File Ariel Miculas
2023-06-09  6:30 ` [PATCH 46/80] rust: kernel: implement fmt::Debug for CString Ariel Miculas
2023-06-09  6:30 ` [PATCH 47/80] samples: puzzlefs: rename RustFs to PuzzleFs Ariel Miculas
2023-06-09  6:30 ` [PATCH 48/80] samples: puzzlefs: add basic deserializing support for the puzzlefs metadata Ariel Miculas
2023-06-09  6:30 ` [PATCH 49/80] rust: file: present the filesystem context to the open function Ariel Miculas
2023-06-09  6:30 ` [PATCH 50/80] rust: kernel: add an abstraction over vfsmount to allow cloning a new private mount Ariel Miculas
2023-06-09  6:30 ` [PATCH 51/80] rust: file: add from_path, from_path_in_root_mnt and read_with_offset methods to File Ariel Miculas
2023-06-09  6:30 ` [PATCH 52/80] samples: puzzlefs: pass the Vfsmount structure from open to read and return the contents of the data file inside /home/puzzlefs_oci Ariel Miculas
2023-06-09  6:30 ` [PATCH 53/80] rust: file: move from_path, from_path_in_root_mnt and read_with_offset methods to a RegularFile newtype Ariel Miculas
2023-06-09  6:30 ` [PATCH 54/80] rust: file: ensure RegularFile can only create regular files Ariel Miculas
2023-06-09  6:30 ` [PATCH 55/80] rust: file: add get_pos method to RegularFile Ariel Miculas
2023-06-09  6:30 ` [PATCH 56/80] rust: file: add methods read_to_end, get_file_size and update_pos " Ariel Miculas
2023-06-09  6:30 ` [PATCH 57/80] rust: file: define a minimal Read trait and implement it for RegularFile Ariel Miculas
2023-06-09  6:30 ` [PATCH 58/80] samples: puzzlefs: add cbor_get_array_size method Ariel Miculas
2023-06-09  6:30 ` [PATCH 59/80] samples: puzzlefs: add KernelError to WireFormatError and implement From conversion Ariel Miculas
2023-06-09  6:30 ` [PATCH 60/80] samples: puzzlefs: implement new for MetadataBlob Ariel Miculas
2023-06-09  6:30 ` [PATCH 61/80] samples: puzzlefs: build puzzlefs into the kernel, thus avoiding the need to export rust symbols Ariel Miculas
2023-06-09  6:31 ` [PATCH 62/80] rust: alloc: add try_clone for Vec<T> Ariel Miculas
2023-06-09  6:31 ` [PATCH 63/80] rust: alloc: add from_iter_fallible " Ariel Miculas
2023-06-09 10:06   ` Miguel Ojeda
2023-06-09  6:31 ` [PATCH 64/80] samples: puzzlefs: implement to_errno and from_errno for WireFormatError Ariel Miculas
2023-06-09  6:31 ` [PATCH 65/80] samples: puzzlefs: add TryReserveError (and from conversion) to WireFormatError Ariel Miculas
2023-06-09  6:31 ` [PATCH 66/80] samples: puzzlefs: add higher level inode related functionality Ariel Miculas
2023-06-09  6:31 ` [PATCH 67/80] samples: puzzlefs: populate the directory entries with the inodes from the puzzlefs metadata file Ariel Miculas
2023-06-09  6:31 ` [PATCH 68/80] rust: hex: import crate Ariel Miculas
2023-06-09  6:31 ` [PATCH 69/80] rust: hex: add SPDX license identifiers Ariel Miculas
2023-06-09  6:31 ` [PATCH 70/80] rust: Kbuild: enable `hex` Ariel Miculas
2023-06-09  6:31 ` [PATCH 71/80] rust: hex: implement FromHex trait and hex::decode using a custom kernel_alloc feature Ariel Miculas
2023-06-09  6:31 ` [PATCH 72/80] rust: hex: add encode_hex_iter and encode_hex_upper_iter methods Ariel Miculas
2023-06-09  6:31 ` [PATCH 73/80] rust: puzzlefs: add HexError to WireFormatError and implement the From conversion Ariel Miculas
2023-06-09  6:31 ` [PATCH 74/80] rust: puzzlefs: display the error value for WireFormatError::KernelError Ariel Miculas
2023-06-09  6:31 ` [PATCH 75/80] samples: puzzlefs: add Rootfs and Digest structs to types.rs Ariel Miculas
2023-06-09  6:31 ` [PATCH 76/80] samples: puzzlefs: implement the conversion from WireFormatError to kernel::error::Error Ariel Miculas
2023-06-09  6:31 ` [PATCH 77/80] rust: puzzlefs: read the puzzlefs image manifest instead of an individual metadata layer Ariel Miculas
2023-06-09  6:31 ` [PATCH 78/80] rust: puzzlefs: rename PuzzleFs to PuzzleFsModule to avoid confusion with the PuzzleFS struct Ariel Miculas
2023-06-09  6:31 ` [PATCH 79/80] rust: puzzlefs: add support for reading files Ariel Miculas
2023-06-09  6:31 ` [PATCH 80/80] rust: puzzlefs: add oci_root_dir and image_manifest filesystem parameters Ariel Miculas
2023-06-09 10:26 ` [RFC PATCH 00/80] Rust PuzzleFS filesystem driver Miguel Ojeda
2023-06-09 10:36 ` Christian Brauner
2023-06-09 11:42   ` Miguel Ojeda
     [not found]   ` <CH0PR11MB529981313ED5A1F815350E41CD51A@CH0PR11MB5299.namprd11.prod.outlook.com>
2023-06-09 11:45     ` Christian Brauner
2023-06-09 12:03       ` Ariel Miculas (amiculas)
2023-06-09 12:56         ` Gao Xiang
2023-06-09 12:07       ` Miguel Ojeda
2023-06-09 12:11         ` Ariel Miculas (amiculas)
2023-06-09 12:21           ` Greg KH
2023-06-09 13:05         ` Alice Ryhl
2023-06-09 12:20       ` Colin Walters
2023-06-09 12:42         ` Christian Brauner
2023-06-09 17:28           ` Serge Hallyn
2023-06-09 13:45         ` Ariel Miculas (amiculas)
2023-06-09 17:10           ` Trilok Soni
2023-06-09 17:16             ` Ariel Miculas (amiculas)
2023-06-09 17:41               ` Miguel Ojeda
2023-06-09 18:49                 ` James Bottomley
2023-06-09 19:08                   ` Miguel Ojeda
2023-06-09 19:11                   ` Ariel Miculas
2023-06-09 20:01                     ` James Bottomley
2023-06-10  9:34                     ` Miguel Ojeda
2023-06-09 18:43               ` James Bottomley
2023-06-09 18:59                 ` Ariel Miculas (amiculas)
2023-06-09 19:20                   ` Ariel Miculas
2023-06-09 19:45                     ` Trilok Soni
2023-06-09 19:53                   ` Alice Ryhl
2023-06-09 23:52   ` Kent Overstreet
2023-06-10  9:40     ` Miguel Ojeda
2023-06-10  0:09 ` Kent Overstreet

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=20230609063118.24852-4-amiculas@cisco.com \
    --to=amiculas@cisco.com \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=wedsonaf@google.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).