From: Gao Xiang <hsiangkao@linux.alibaba.com>
To: Yiyang Wu <toolmanp@tlmp.cc>, Al Viro <viro@zeniv.linux.org.uk>
Cc: linux-erofs@lists.ozlabs.org, rust-for-linux@vger.kernel.org,
linux-fsdevel@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH 19/24] erofs: introduce namei alternative to C
Date: Tue, 17 Sep 2024 15:14:58 +0800 [thread overview]
Message-ID: <1edf9fe3-5e39-463b-8825-67b4d1ad01be@linux.alibaba.com> (raw)
In-Reply-To: <ocmc6tmkyl6fnlijx4r3ztrmjfv5eep6q6dvbtfja4v43ujtqx@y43boqba3p5f>
On 2024/9/17 14:48, Yiyang Wu wrote:
> On Mon, Sep 16, 2024 at 06:08:01PM GMT, Al Viro wrote:
>> On Mon, Sep 16, 2024 at 09:56:29PM +0800, Yiyang Wu wrote:
>>> +/// Lookup function for dentry-inode lookup replacement.
>>> +#[no_mangle]
>>> +pub unsafe extern "C" fn erofs_lookup_rust(
>>> + k_inode: NonNull<inode>,
>>> + dentry: NonNull<dentry>,
>>> + _flags: c_uint,
>>> +) -> *mut c_void {
>>> + // SAFETY: We are sure that the inode is a Kernel Inode since alloc_inode is called
>>> + let erofs_inode = unsafe { &*container_of!(k_inode.as_ptr(), KernelInode, k_inode) };
>>
>> Ummm... A wrapper would be highly useful. And the reason why
>> it's safe is different - your function is called only via ->i_op->lookup,
>> the is only one instance of inode_operations that has that ->lookup
>> method, and the only place where an inode gets ->i_op set to that
>> is erofs_fill_inode(). Which is always passed erofs_inode::vfs_inode.
>>
> So my original intention behind this is that all vfs_inodes come from
> that erofs_iget function and it's always gets initialized in this case
> And this just followes the same convention here. I can document this
> more precisely.
I think Al just would like a wrapper here, like the current C EROFS_I().
>>> + // SAFETY: The super_block is initialized when the erofs_alloc_sbi_rust is called.
>>> + let sbi = erofs_sbi(unsafe { NonNull::new(k_inode.as_ref().i_sb).unwrap() });
>>
>> Again, that calls for a wrapper - this time not erofs-specific;
>> inode->i_sb is *always* non-NULL, is assign-once and always points
>> to live struct super_block instance at least until the call of
>> destroy_inode().
>>
>
> Will be modified correctly, I'm not a native speaker and I just can't
> find a better way, I will take my note here.
Same here, like the current EROFS_I_SB().
>>> + // SAFETY: this is backed by qstr which is c representation of a valid slice.
>>
>> What is that sentence supposed to mean? Nevermind "why is it correct"...
>>
>>> + let name = unsafe {
>>> + core::str::from_utf8_unchecked(core::slice::from_raw_parts(
>>> + dentry.as_ref().d_name.name,
>>> + dentry.as_ref().d_name.__bindgen_anon_1.__bindgen_anon_1.len as usize,
>>
...
>
>> Current erofs_lookup() (and your version as well) *is* indeed
>> safe in that respect, but the proof (from filesystem POV) is that "it's
>> called only as ->lookup() instance, so dentry is initially unhashed
>> negative and will remain such until it's passed to d_splice_alias();
>> until that point it is guaranteed to have ->d_name and ->d_parent stable".
Agreed.
>>
>> Note that once you _have_ called d_splice_alias(), you can't
>> count upon the ->d_name stability - or, indeed, upon ->d_name.name you've
>> sampled still pointing to allocated memory.
>>
>> For directory-modifying methods it's "stable, since parent is held
>> exclusive". Some internal function called from different environments?
>> Well... Swear, look through the call graph and see what can be proven
>> for each.
>
> Sorry for my ignorance.
> I mean i just borrowed the code from the fs/erofs/namei.c and i directly
> translated that into Rust code. That might be a problem that also
> exists in original working C code.
As for EROFS (an immutable fs), I think after d_splice_alias(), d_name is
still stable (since we don't have rename semantics likewise for now).
But as the generic filesystem POV, d_name access is actually tricky under
RCU walk path indeed.
>
>> Expressing that kind of fun in any kind of annotations (Rust type
>> system included) is not pleasant. _Probably_ might be handled by a type
>> that would be a dentry pointer with annotation along the lines "->d_name
>> and ->d_parent of that one are stable". Then e.g. ->lookup() would
>> take that thing as an argument and d_splice_alias() would consume it.
>> ->mkdir() would get the same thing, etc. I hadn't tried to get that
>> all way through (the amount of annotation churn in existing filesystems
>> would be high and hard to split into reviewable patch series), so there
>> might be dragons - and there definitely are places where the stability is
>> proven in different ways (e.g. if dentry->d_lock is held, we have the damn
>> thing stable; then there's a "take a safe snapshot of name" API; etc.).
>
> That's kinda interesting, I originally thought that VFS will make sure
> its d_name / d_parent is stable in the first place.
> Again, I just don't have a full picture or understanding of VFS and my
> code is just basic translation of original C code, Maybe we can address
> this later.
d_alloc will allocate an unhashed dentry which is almost unrecognized
by VFS dcache (d_name is stable of course).
After d_splice_alias() and d_add(), rename() could change d_name. So
either we take d_lock or with rcu_read_lock() to take a snapshot of
d_name in the RCU walk path. That is my overall understanding.
But for EROFS, since we don't have rename, so it doesn't matter.
Thanks,
Gao Xiang
next prev parent reply other threads:[~2024-09-17 7:15 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 ` [RFC PATCH 18/24] erofs: introduce iget alternative " Yiyang Wu
2024-09-16 13:56 ` [RFC PATCH 19/24] erofs: introduce namei " Yiyang Wu
2024-09-16 17:08 ` Al Viro
2024-09-17 6:48 ` Yiyang Wu
2024-09-17 7:14 ` Gao Xiang [this message]
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=1edf9fe3-5e39-463b-8825-67b4d1ad01be@linux.alibaba.com \
--to=hsiangkao@linux.alibaba.com \
--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 \
--cc=toolmanp@tlmp.cc \
--cc=viro@zeniv.linux.org.uk \
/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
all inboxes | Powered by JetHome®