From: Yiyang Wu <toolmanp@tlmp.cc>
To: linux-erofs@lists.ozlabs.org
Cc: rust-for-linux@vger.kernel.org, linux-fsdevel@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>
Subject: [RFC PATCH 18/24] erofs: introduce iget alternative to C
Date: Mon, 16 Sep 2024 21:56:28 +0800 [thread overview]
Message-ID: <20240916135634.98554-19-toolmanp@tlmp.cc> (raw)
In-Reply-To: <20240916135634.98554-1-toolmanp@tlmp.cc>
This patch introduces iget and fast symlink alternative written in Rust.
After this patch, erofs_iget can be replaced with erofs_iget_rust.
Iget related test and set are lifted after this patch as
rust_helpers.c will also use it to port the iget_locked to Rust.
Signed-off-by: Yiyang Wu <toolmanp@tlmp.cc>
---
fs/erofs/Makefile | 2 +-
fs/erofs/inode.c | 8 ++++--
fs/erofs/inode_rs.rs | 59 ++++++++++++++++++++++++++++++++++++++++
fs/erofs/internal.h | 33 ++++++++++++++++++++++
fs/erofs/rust/kinode.rs | 29 +++++++++++++++++---
fs/erofs/rust_bindings.h | 12 ++++++++
fs/erofs/rust_helpers.c | 55 +++++++++++++++++++++++++++++++++++++
fs/erofs/rust_helpers.h | 4 ++-
fs/erofs/super.c | 34 ++++++++++++++++++-----
9 files changed, 220 insertions(+), 16 deletions(-)
create mode 100644 fs/erofs/inode_rs.rs
diff --git a/fs/erofs/Makefile b/fs/erofs/Makefile
index dfa03edbe29a..46de6f490ca2 100644
--- a/fs/erofs/Makefile
+++ b/fs/erofs/Makefile
@@ -9,4 +9,4 @@ erofs-$(CONFIG_EROFS_FS_ZIP_DEFLATE) += decompressor_deflate.o
erofs-$(CONFIG_EROFS_FS_ZIP_ZSTD) += decompressor_zstd.o
erofs-$(CONFIG_EROFS_FS_BACKED_BY_FILE) += fileio.o
erofs-$(CONFIG_EROFS_FS_ONDEMAND) += fscache.o
-erofs-$(CONFIG_EROFS_FS_RUST) += super_rs.o rust_helpers.o
+erofs-$(CONFIG_EROFS_FS_RUST) += super_rs.o inode_rs.o rust_helpers.o
diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
index d2fd51fcebd2..b8467272a670 100644
--- a/fs/erofs/inode.c
+++ b/fs/erofs/inode.c
@@ -269,7 +269,7 @@ int erofs_fill_inode(struct inode *inode)
* ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
* so that it will fit.
*/
-static ino_t erofs_squash_ino(erofs_nid_t nid)
+ino_t erofs_squash_ino(erofs_nid_t nid)
{
ino_t ino = (ino_t)nid;
@@ -278,12 +278,12 @@ static ino_t erofs_squash_ino(erofs_nid_t nid)
return ino;
}
-static int erofs_iget5_eq(struct inode *inode, void *opaque)
+int erofs_iget5_eq(struct inode *inode, void *opaque)
{
return EROFS_I(inode)->nid == *(erofs_nid_t *)opaque;
}
-static int erofs_iget5_set(struct inode *inode, void *opaque)
+int erofs_iget5_set(struct inode *inode, void *opaque)
{
const erofs_nid_t nid = *(erofs_nid_t *)opaque;
@@ -292,6 +292,7 @@ static int erofs_iget5_set(struct inode *inode, void *opaque)
return 0;
}
+#ifndef CONFIG_EROFS_FS_RUST
struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid)
{
struct inode *inode;
@@ -312,6 +313,7 @@ struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid)
}
return inode;
}
+#endif
int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
struct kstat *stat, u32 request_mask,
diff --git a/fs/erofs/inode_rs.rs b/fs/erofs/inode_rs.rs
new file mode 100644
index 000000000000..5cca2ae581ac
--- /dev/null
+++ b/fs/erofs/inode_rs.rs
@@ -0,0 +1,59 @@
+// Copyright 2024 Yiyang Wu
+// SPDX-License-Identifier: MIT or GPL-2.0-or-later
+
+//! EROFS Rust Kernel Module Helpers Implementation
+//! This is only for experimental purpose. Feedback is always welcome.
+
+#[allow(dead_code)]
+#[allow(missing_docs)]
+pub(crate) mod rust;
+
+use core::ffi::*;
+use core::mem::{offset_of, size_of};
+use core::ptr::NonNull;
+use kernel::bindings::{inode, super_block};
+use kernel::container_of;
+use rust::{
+ erofs_sys::{operations::*, *},
+ kinode::*,
+ ksuperblock::erofs_sbi,
+};
+
+/// Used as a size hint to be exported to kmem_caceh_create
+#[no_mangle]
+pub static EROFS_INODE_SIZE_RUST: c_uint = size_of::<KernelInode>() as c_uint;
+
+/// Used as a hint offset to be exported so EROFS_VFS_I to find the embedded the vfs inode.
+#[no_mangle]
+pub static EROFS_VFS_INODE_OFFSET_RUST: c_ulong = offset_of!(KernelInode, k_inode) as c_ulong;
+
+/// Used as a hint offset to be exported to EROFS_I to find the embedded c side erofs_inode.
+#[no_mangle]
+pub static EROFS_I_OFFSET_RUST: c_long =
+ offset_of!(KernelInode, k_opaque) as c_long - offset_of!(KernelInode, k_inode) as c_long;
+
+/// Exported as iget replacement
+#[no_mangle]
+pub unsafe extern "C" fn erofs_iget_rust(sb: NonNull<super_block>, nid: Nid) -> *mut c_void {
+ // SAFETY: The super_block is initialized when the erofs_alloc_sbi_rust is called.
+ let sbi = erofs_sbi(sb);
+ read_inode(sbi.filesystem.as_ref(), &mut sbi.inodes, nid)
+ .map_or_else(|e| e.into(), |inode| inode.k_inode.as_mut_ptr().cast())
+}
+
+fn try_fill_inode(k_inode: NonNull<inode>, nid: Nid) -> PosixResult<()> {
+ // SAFETY: The super_block is initialized when the erofs_fill_inode_rust is called.
+ let sbi = erofs_sbi(unsafe { NonNull::new(k_inode.as_ref().i_sb).unwrap() });
+ // SAFETY: k_inode is a part of KernelInode.
+ let erofs_inode: &mut KernelInode = unsafe {
+ &mut *(container_of!(k_inode.as_ptr(), KernelInode, k_inode) as *mut KernelInode)
+ };
+ erofs_inode.info.write(sbi.filesystem.read_inode_info(nid)?);
+ erofs_inode.nid.write(nid);
+ Ok(())
+}
+/// Exported as fill_inode additional fill inode
+#[no_mangle]
+pub unsafe extern "C" fn erofs_fill_inode_rust(k_inode: NonNull<inode>, nid: Nid) -> c_int {
+ try_fill_inode(k_inode, nid).map_or_else(|e| i32::from(e) as c_int, |_| 0)
+}
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 18e67219fbc8..42ce84783be7 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -306,10 +306,20 @@ struct erofs_inode {
#endif /* CONFIG_EROFS_FS_ZIP */
};
/* the corresponding vfs inode */
+#ifndef CONFIG_EROFS_FS_RUST
struct inode vfs_inode;
+#endif
};
+#ifdef CONFIG_EROFS_FS_RUST
+#define EROFS_I(ptr) (*(struct erofs_inode **)(((void *)(ptr)) + \
+ EROFS_I_OFFSET_RUST))
+#define EROFS_I_VFS(ptr) ((struct inode *)(((void *)(ptr)) + EROFS_VFS_INODE_OFFSET_RUST))
+#define EROFS_I_RUST(ptr) ((void *)(ptr) - EROFS_VFS_INODE_OFFSET_RUST)
+#else
#define EROFS_I(ptr) container_of(ptr, struct erofs_inode, vfs_inode)
+#define EROFS_I_VFS(ptr) (&((struct erofs_inode *)(ptr))->vfs_inode)
+#endif
static inline erofs_off_t erofs_iloc(struct inode *inode)
{
@@ -427,10 +437,18 @@ void erofs_onlinefolio_init(struct folio *folio);
void erofs_onlinefolio_split(struct folio *folio);
void erofs_onlinefolio_end(struct folio *folio, int err);
int erofs_fill_inode(struct inode *inode);
+ino_t erofs_squash_ino(erofs_nid_t nid);
+int erofs_iget5_eq(struct inode *inode, void *opaque);
+int erofs_iget5_set(struct inode *inode, void *opaque);
+#ifdef CONFIG_EROFS_FS_RUST
+#define erofs_iget erofs_iget_rust
+#else
struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid);
+#endif
int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
struct kstat *stat, u32 request_mask,
unsigned int query_flags);
+
int erofs_namei(struct inode *dir, const struct qstr *name,
erofs_nid_t *nid, unsigned int *d_type);
@@ -538,6 +556,21 @@ static inline struct bio *erofs_fscache_bio_alloc(struct erofs_map_dev *mdev) {
static inline void erofs_fscache_submit_bio(struct bio *bio) {}
#endif
+#ifdef CONFIG_EROFS_FS_RUST
+extern int erofs_init_rust(void);
+extern void erofs_destroy_rust(void);
+extern void erofs_init_inode_rust(struct inode *inode);
+extern void erofs_free_inode_rust(struct inode *inode);
+#else
+static inline int erofs_init_rust(void)
+{
+ return 0;
+}
+static inline void erofs_destroy_rust(void) {}
+static inline void erofs_init_inode_rust(struct inode *inode) {}
+static inline void erofs_free_inode_rust(struct inode *inode) {}
+#endif
+
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
#endif /* __EROFS_INTERNAL_H */
diff --git a/fs/erofs/rust/kinode.rs b/fs/erofs/rust/kinode.rs
index df6de40d0594..fac72bd8b6b3 100644
--- a/fs/erofs/rust/kinode.rs
+++ b/fs/erofs/rust/kinode.rs
@@ -1,16 +1,23 @@
// Copyright 2024 Yiyang Wu
// SPDX-License-Identifier: MIT or GPL-2.0-or-later
-use core::ffi::c_void;
+use core::ffi::*;
use core::mem::MaybeUninit;
use core::ptr::NonNull;
use kernel::bindings::{inode, super_block};
+use kernel::container_of;
+use super::erofs_sys::errnos::*;
use super::erofs_sys::inode::*;
use super::erofs_sys::superblock::*;
use super::erofs_sys::*;
+extern "C" {
+ #[link_name = "erofs_iget_locked_rust_helper"]
+ fn iget_locked(sb: NonNull<c_void>, nid: Nid) -> *mut c_void;
+}
+
#[repr(C)]
pub(crate) struct KernelInode {
pub(crate) info: MaybeUninit<InodeInfo>,
@@ -21,7 +28,12 @@ pub(crate) struct KernelInode {
impl Inode for KernelInode {
fn new(_sb: &SuperBlock, _info: InodeInfo, _nid: Nid) -> Self {
- unimplemented!();
+ Self {
+ info: MaybeUninit::uninit(),
+ nid: MaybeUninit::uninit(),
+ k_inode: MaybeUninit::uninit(),
+ k_opaque: MaybeUninit::uninit(),
+ }
}
fn nid(&self) -> Nid {
unsafe { self.nid.assume_init() }
@@ -37,8 +49,17 @@ pub(crate) struct KernelInodeCollection {
impl InodeCollection for KernelInodeCollection {
type I = KernelInode;
- fn iget(&mut self, _nid: Nid, _f: &dyn FileSystem<Self::I>) -> PosixResult<&mut Self::I> {
- unimplemented!();
+ fn iget(&mut self, nid: Nid, _f: &dyn FileSystem<Self::I>) -> PosixResult<&mut Self::I> {
+ // SAFETY: iget_locked is safe to call here.
+ let k_inode = unsafe { iget_locked(self.sb.cast(), nid) };
+ if is_value_err(k_inode.cast()) {
+ return Err(Errno::from(k_inode as i32));
+ } else {
+ let erofs_inode: &mut KernelInode =
+ // SAFETY: iget_locked returns a valid pointer to a vfs inode and it's embedded in a KernelInode.
+ unsafe { &mut *(container_of!(k_inode, KernelInode, k_inode) as *mut KernelInode) };
+ return Ok(erofs_inode);
+ }
}
}
diff --git a/fs/erofs/rust_bindings.h b/fs/erofs/rust_bindings.h
index 9695c5ed5a7c..657f109dd6e7 100644
--- a/fs/erofs/rust_bindings.h
+++ b/fs/erofs/rust_bindings.h
@@ -6,7 +6,19 @@
#include <linux/fs.h>
+
+typedef u64 erofs_nid_t;
+typedef u64 erofs_off_t;
+/* data type for filesystem-wide blocks number */
+typedef u32 erofs_blk_t;
+
extern const unsigned long EROFS_SB_INFO_OFFSET_RUST;
+extern const unsigned int EROFS_INODE_SIZE_RUST;
+extern const unsigned long EROFS_VFS_INODE_OFFSET_RUST;
+extern const long EROFS_I_OFFSET_RUST;
+
extern void *erofs_alloc_sbi_rust(struct super_block *sb);
extern void *erofs_free_sbi_rust(struct super_block *sb);
+extern int erofs_iget5_eq_rust(struct inode *inode, void *opaque);
+extern struct inode *erofs_iget_rust(struct super_block *sb, erofs_nid_t nid);
#endif
diff --git a/fs/erofs/rust_helpers.c b/fs/erofs/rust_helpers.c
index 5fdc158ed9ef..94e9153fc3ff 100644
--- a/fs/erofs/rust_helpers.c
+++ b/fs/erofs/rust_helpers.c
@@ -1,5 +1,7 @@
#include "rust_helpers.h"
+static struct kmem_cache *erofs_inode_cachep __read_mostly;
+
static void erofs_init_metabuf_rust_helper(struct erofs_buf *buf,
struct super_block *sb,
struct erofs_sb_info *sbi)
@@ -29,3 +31,56 @@ void erofs_put_metabuf_rust_helper(void *addr)
.kmap_type = EROFS_KMAP,
});
}
+
+int erofs_init_rust(void)
+{
+ erofs_inode_cachep = kmem_cache_create("erofs_inode",
+ sizeof(struct erofs_inode), 0,
+ SLAB_RECLAIM_ACCOUNT, NULL);
+ if (!erofs_inode_cachep)
+ return -ENOMEM;
+ return 0;
+}
+
+void erofs_destroy_rust(void)
+{
+ if (erofs_inode_cachep)
+ kmem_cache_destroy(erofs_inode_cachep);
+}
+
+void erofs_init_inode_rust(struct inode *inode)
+{
+ EROFS_I(inode) = kmem_cache_alloc(erofs_inode_cachep, GFP_KERNEL);
+}
+
+void erofs_free_inode_rust(struct inode *inode)
+{
+ struct erofs_inode *vi = EROFS_I(inode);
+ if (vi)
+ kmem_cache_free(erofs_inode_cachep, vi);
+}
+
+struct inode *erofs_iget_locked_rust_helper(struct super_block *sb, erofs_nid_t nid)
+{
+ struct inode *inode;
+ int err;
+
+ inode = iget5_locked(sb, erofs_squash_ino(nid), erofs_iget5_eq,
+ erofs_iget5_set, &nid);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ err = erofs_fill_inode(inode);
+ if(err)
+ goto err_out;
+
+ err = erofs_fill_inode_rust(inode, nid);
+ if(err)
+ goto err_out;
+
+ return inode;
+err_out:
+ if (err)
+ iget_failed(inode);
+ return ERR_PTR(err);
+}
diff --git a/fs/erofs/rust_helpers.h b/fs/erofs/rust_helpers.h
index 158b21438314..5bcd452f6d82 100644
--- a/fs/erofs/rust_helpers.h
+++ b/fs/erofs/rust_helpers.h
@@ -17,5 +17,7 @@ void *erofs_read_metabuf_rust_helper(struct super_block *sb,
struct erofs_sb_info *sbi,
erofs_off_t offset);
void erofs_put_metabuf_rust_helper(void *addr);
-
+extern int erofs_fill_inode_rust(struct inode *inode, erofs_nid_t nid);
+struct inode *erofs_iget_locked_rust_helper(struct super_block *sb,
+ erofs_nid_t nid);
#endif
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 61f138a7d8e2..659502bdf5fe 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -81,22 +81,23 @@ static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata)
static void erofs_inode_init_once(void *ptr)
{
- struct erofs_inode *vi = ptr;
-
- inode_init_once(&vi->vfs_inode);
+ inode_init_once(EROFS_I_VFS(ptr));
+ erofs_init_inode_rust(EROFS_I_VFS(ptr));
}
static struct inode *erofs_alloc_inode(struct super_block *sb)
{
- struct erofs_inode *vi =
+ void *ptr =
alloc_inode_sb(sb, erofs_inode_cachep, GFP_KERNEL);
- if (!vi)
+ if (!ptr)
return NULL;
+#ifndef CONFIG_EROFS_FS_RUST
/* zero out everything except vfs_inode */
- memset(vi, 0, offsetof(struct erofs_inode, vfs_inode));
- return &vi->vfs_inode;
+ memset(ptr, 0, offsetof(struct erofs_inode, vfs_inode));
+#endif
+ return EROFS_I_VFS(ptr);
}
static void erofs_free_inode(struct inode *inode)
@@ -106,7 +107,12 @@ static void erofs_free_inode(struct inode *inode)
if (inode->i_op == &erofs_fast_symlink_iops)
kfree(inode->i_link);
kfree(vi->xattr_shared_xattrs);
+ erofs_free_inode_rust(inode);
+#ifdef CONFIG_EROFS_FS_RUST
+ kmem_cache_free(erofs_inode_cachep, EROFS_I_RUST(inode));
+#else
kmem_cache_free(erofs_inode_cachep, vi);
+#endif
}
/* read variable-sized metadata, offset will be aligned by 4-byte */
@@ -871,13 +877,25 @@ static int __init erofs_module_init(void)
erofs_check_ondisk_layout_definitions();
+#ifndef CONFIG_EROFS_FS_RUST
erofs_inode_cachep = kmem_cache_create("erofs_inode",
sizeof(struct erofs_inode), 0,
SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT,
erofs_inode_init_once);
+#else
+ erofs_inode_cachep = kmem_cache_create("erofs_inode_rust",
+ EROFS_INODE_SIZE_RUST, 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT,
+ erofs_inode_init_once);
+#endif
+
if (!erofs_inode_cachep)
return -ENOMEM;
+ err = erofs_init_rust();
+ if(err)
+ goto rust_err;
+
err = erofs_init_shrinker();
if (err)
goto shrinker_err;
@@ -904,6 +922,8 @@ static int __init erofs_module_init(void)
erofs_exit_shrinker();
shrinker_err:
kmem_cache_destroy(erofs_inode_cachep);
+rust_err:
+ erofs_destroy_rust();
return err;
}
--
2.46.0
next prev parent reply other threads:[~2024-09-16 13:57 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-16 13:56 [RFC PATCH 00/24] erofs: introduce Rust implementation Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 01/24] erofs: lift up erofs_fill_inode to global Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 02/24] erofs: add superblock data structure in Rust Yiyang Wu
2024-09-16 17:55 ` Greg KH
2024-09-17 0:18 ` Gao Xiang
2024-09-17 5:34 ` Greg KH
2024-09-17 5:45 ` Gao Xiang
2024-09-17 5:27 ` Yiyang Wu
2024-09-17 5:39 ` Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 03/24] erofs: add Errno " Yiyang Wu
2024-09-16 17:51 ` Greg KH
2024-09-16 23:45 ` Gao Xiang
2024-09-20 2:49 ` [PATCH RESEND 0/1] rust: introduce declare_err! autogeneration Yiyang Wu
2024-09-20 2:49 ` [PATCH RESEND 1/1] rust: error: auto-generate error declarations Yiyang Wu
2024-09-20 2:57 ` [RFC PATCH 03/24] erofs: add Errno in Rust Yiyang Wu
2024-09-16 20:01 ` Gary Guo
2024-09-16 23:58 ` Gao Xiang
2024-09-19 13:45 ` Benno Lossin
2024-09-19 15:13 ` Gao Xiang
2024-09-19 19:36 ` Benno Lossin
2024-09-20 0:49 ` Gao Xiang
2024-09-21 8:37 ` Greg Kroah-Hartman
2024-09-21 9:29 ` Gao Xiang
2024-09-25 15:48 ` Ariel Miculas
2024-09-25 16:35 ` Gao Xiang
2024-09-25 21:45 ` Ariel Miculas
2024-09-26 0:40 ` Gao Xiang
2024-09-26 1:04 ` Gao Xiang
2024-09-26 8:10 ` Ariel Miculas
2024-09-26 8:25 ` Gao Xiang
2024-09-26 9:51 ` Ariel Miculas
2024-09-26 10:46 ` Gao Xiang
2024-09-26 11:01 ` Ariel Miculas
2024-09-26 11:05 ` Gao Xiang
2024-09-26 11:23 ` Gao Xiang
2024-09-26 12:50 ` Ariel Miculas
2024-09-27 2:18 ` Gao Xiang
2024-09-26 8:48 ` Gao Xiang
2024-09-16 13:56 ` [RFC PATCH 04/24] erofs: add xattrs data structure " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 05/24] erofs: add inode " Yiyang Wu
2024-09-18 13:04 ` [External Mail][RFC " Huang Jianan
2024-09-16 13:56 ` [RFC PATCH 06/24] erofs: add alloc_helper " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 07/24] erofs: add data abstraction " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 08/24] erofs: add device data structure " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 09/24] erofs: add continuous iterators " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 10/24] erofs: add device_infos implementation " Yiyang Wu
2024-09-21 9:44 ` Jianan Huang
2024-09-16 13:56 ` [RFC PATCH 11/24] erofs: add map data structure " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 12/24] erofs: add directory entry " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 13/24] erofs: add runtime filesystem and inode " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 14/24] erofs: add block mapping capability " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 15/24] erofs: add iter methods in filesystem " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 16/24] erofs: implement dir and inode operations " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 17/24] erofs: introduce Rust SBI to C Yiyang Wu
2024-09-16 13:56 ` Yiyang Wu [this message]
2024-09-16 13:56 ` [RFC PATCH 19/24] erofs: introduce namei alternative " Yiyang Wu
2024-09-16 17:08 ` Al Viro
2024-09-17 6:48 ` Yiyang Wu
2024-09-17 7:14 ` Gao Xiang
2024-09-17 7:31 ` Al Viro
2024-09-17 7:44 ` Al Viro
2024-09-17 8:08 ` Gao Xiang
2024-09-17 22:22 ` Al Viro
2024-09-17 8:06 ` Gao Xiang
2024-09-16 13:56 ` [RFC PATCH 20/24] erofs: introduce readdir " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 21/24] erofs: introduce erofs_map_blocks " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 22/24] erofs: add skippable iters in Rust Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 23/24] erofs: implement xattrs operations " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 24/24] erofs: introduce xattrs replacement to C Yiyang Wu
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=20240916135634.98554-19-toolmanp@tlmp.cc \
--to=toolmanp@tlmp.cc \
--cc=linux-erofs@lists.ozlabs.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rust-for-linux@vger.kernel.org \
/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).