From: Yonghong Song <yonghong.song@linux.dev>
To: Song Liu <songliubraving@meta.com>
Cc: Song Liu <song@kernel.org>,
"bpf@vger.kernel.org" <bpf@vger.kernel.org>,
"linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-security-module@vger.kernel.org"
<linux-security-module@vger.kernel.org>,
Kernel Team <kernel-team@meta.com>,
"andrii@kernel.org" <andrii@kernel.org>,
"eddyz87@gmail.com" <eddyz87@gmail.com>,
"ast@kernel.org" <ast@kernel.org>,
"daniel@iogearbox.net" <daniel@iogearbox.net>,
"martin.lau@linux.dev" <martin.lau@linux.dev>,
"viro@zeniv.linux.org.uk" <viro@zeniv.linux.org.uk>,
"brauner@kernel.org" <brauner@kernel.org>,
"jack@suse.cz" <jack@suse.cz>,
"kpsingh@kernel.org" <kpsingh@kernel.org>,
"mattbobrowski@google.com" <mattbobrowski@google.com>,
"m@maowtm.org" <m@maowtm.org>,
"neil@brown.name" <neil@brown.name>
Subject: Re: [PATCH v5 bpf-next 1/5] namei: Introduce new helper function path_walk_parent()
Date: Mon, 7 Jul 2025 10:53:24 -0700 [thread overview]
Message-ID: <74ae6eb2-cea7-4e3e-82eb-72978dd0f101@linux.dev> (raw)
In-Reply-To: <58FB95C4-1499-4865-8FA7-3E1F64EB5EDE@meta.com>
On 7/6/25 4:54 PM, Song Liu wrote:
>
>> On Jul 4, 2025, at 10:40 AM, Yonghong Song <yonghong.song@linux.dev> wrote:
> [...]
>>> +static struct dentry *__path_walk_parent(struct path *path, const struct path *root, int flags)
>>> {
>>> - struct dentry *parent;
>>> -
>>> - if (path_equal(&nd->path, &nd->root))
>>> + if (path_equal(path, root))
>>> goto in_root;
>>> - if (unlikely(nd->path.dentry == nd->path.mnt->mnt_root)) {
>>> - struct path path;
>>> + if (unlikely(path->dentry == path->mnt->mnt_root)) {
>>> + struct path new_path;
>>> - if (!choose_mountpoint(real_mount(nd->path.mnt),
>>> - &nd->root, &path))
>>> + if (!choose_mountpoint(real_mount(path->mnt),
>>> + root, &new_path))
>>> goto in_root;
>>> - path_put(&nd->path);
>>> - nd->path = path;
>>> - nd->inode = path.dentry->d_inode;
>>> - if (unlikely(nd->flags & LOOKUP_NO_XDEV))
>>> + path_put(path);
>>> + *path = new_path;
>>> + if (unlikely(flags & LOOKUP_NO_XDEV))
>>> return ERR_PTR(-EXDEV);
>>> }
>>> /* rare case of legitimate dget_parent()... */
>>> - parent = dget_parent(nd->path.dentry);
>>> + return dget_parent(path->dentry);
>> I have some confusion with this patch when crossing mount boundary.
>>
>> In d_path.c, we have
>>
>> static int __prepend_path(const struct dentry *dentry, const struct mount *mnt,
>> const struct path *root, struct prepend_buffer *p)
>> {
>> while (dentry != root->dentry || &mnt->mnt != root->mnt) {
>> const struct dentry *parent = READ_ONCE(dentry->d_parent);
>>
>> if (dentry == mnt->mnt.mnt_root) {
>> struct mount *m = READ_ONCE(mnt->mnt_parent);
>> struct mnt_namespace *mnt_ns;
>>
>> if (likely(mnt != m)) {
>> dentry = READ_ONCE(mnt->mnt_mountpoint);
>> mnt = m;
>> continue;
>> }
>> /* Global root */
>> mnt_ns = READ_ONCE(mnt->mnt_ns);
>> /* open-coded is_mounted() to use local mnt_ns */
>> if (!IS_ERR_OR_NULL(mnt_ns) && !is_anon_ns(mnt_ns))
>> return 1; // absolute root
>> else
>> return 2; // detached or not attached yet
>> }
>>
>> if (unlikely(dentry == parent))
>> /* Escaped? */
>> return 3;
>>
>> prefetch(parent);
>> if (!prepend_name(p, &dentry->d_name))
>> break;
>> dentry = parent;
>> }
>> return 0;
>> }
>>
>> At the mount boundary and not at root mount, the code has
>> dentry = READ_ONCE(mnt->mnt_mountpoint);
>> mnt = m; /* 'mnt' will be parent mount */
>> continue;
>>
>> After that, we have
>> const struct dentry *parent = READ_ONCE(dentry->d_parent);
>> if (dentry == mnt->mnt.mnt_root) {
>> /* assume this is false */
>> }
>> ...
>> prefetch(parent);
>> if (!prepend_name(p, &dentry->d_name))
>> break;
>> dentry = parent;
>>
>> So the prepend_name(p, &dentry->d_name) is actually from mnt->mnt_mountpoint.
> I am not quite following the question. In the code below:
>
> if (dentry == mnt->mnt.mnt_root) {
> struct mount *m = READ_ONCE(mnt->mnt_parent);
> struct mnt_namespace *mnt_ns;
>
> if (likely(mnt != m)) {
> dentry = READ_ONCE(mnt->mnt_mountpoint);
> mnt = m;
> continue;
> /* We either continue, here */
>
> }
> /* Global root */
> mnt_ns = READ_ONCE(mnt->mnt_ns);
> /* open-coded is_mounted() to use local mnt_ns */
> if (!IS_ERR_OR_NULL(mnt_ns) && !is_anon_ns(mnt_ns))
> return 1; // absolute root
> else
> return 2; // detached or not attached yet
> /* Or return here */
> }
>
> So we will not hit prepend_name(). Does this answer the
> question?
>
>> In your above code, maybe we should return path->dentry in the below if statement?
>>
>> if (unlikely(path->dentry == path->mnt->mnt_root)) {
>> struct path new_path;
>>
>> if (!choose_mountpoint(real_mount(path->mnt),
>> root, &new_path))
>> goto in_root;
>> path_put(path);
>> *path = new_path;
>> if (unlikely(flags & LOOKUP_NO_XDEV))
>> return ERR_PTR(-EXDEV);
>> + return path->dentry;
>> }
>> /* rare case of legitimate dget_parent()... */
>> return dget_parent(path->dentry);
>>
>> Also, could you add some selftests cross mount points? This will
>> have more coverages with __path_walk_parent().
Looks like __path_walk_parent() works for the root of mounted fs.
If this is the case, the implementation is correct. It could be
good to add some comments to clarify.
> Yeah, I will try to add more tests in the next revision.
>
> Thanks,
> Song
>
next prev parent reply other threads:[~2025-07-07 17:53 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-17 6:11 [PATCH v5 bpf-next 0/5] bpf path iterator Song Liu
2025-06-17 6:11 ` [PATCH v5 bpf-next 1/5] namei: Introduce new helper function path_walk_parent() Song Liu
2025-06-18 1:02 ` kernel test robot
2025-06-24 12:18 ` Jan Kara
2025-06-24 17:37 ` Song Liu
2025-06-25 10:30 ` Jan Kara
2025-07-04 17:40 ` Yonghong Song
2025-07-06 23:54 ` Song Liu
2025-07-07 17:53 ` Yonghong Song [this message]
2025-06-17 6:11 ` [PATCH v5 bpf-next 2/5] landlock: Use path_walk_parent() Song Liu
2025-07-03 18:29 ` Mickaël Salaün
2025-07-03 22:27 ` Song Liu
2025-07-04 9:00 ` Mickaël Salaün
2025-07-06 22:29 ` Song Liu
2025-07-07 10:28 ` Christian Brauner
2025-06-17 6:11 ` [PATCH v5 bpf-next 3/5] bpf: Introduce path iterator Song Liu
2025-06-17 6:11 ` [PATCH v5 bpf-next 4/5] selftests/bpf: Add tests for bpf " Song Liu
2025-06-17 6:11 ` [PATCH v5 bpf-next 5/5] selftests/bpf: Path walk test Song Liu
2025-06-20 21:59 ` [PATCH v5 bpf-next 0/5] bpf path iterator Song Liu
2025-06-24 18:45 ` Mickaël Salaün
2025-06-24 21:38 ` NeilBrown
2025-06-25 13:14 ` Mickaël Salaün
2025-06-25 23:04 ` NeilBrown
2025-06-25 23:17 ` Song Liu
2025-06-26 0:07 ` Tingmao Wang
2025-06-26 1:05 ` NeilBrown
2025-06-26 5:52 ` Song Liu
2025-06-26 9:43 ` Mickaël Salaün
2025-06-26 14:49 ` Song Liu
2025-06-26 10:22 ` NeilBrown
2025-06-26 14:28 ` Song Liu
2025-06-26 22:51 ` NeilBrown
2025-06-27 0:21 ` Song Liu
2025-07-07 10:46 ` Christian Brauner
2025-07-07 11:17 ` Christian Brauner
2025-07-07 18:50 ` Song Liu
2025-07-09 16:06 ` Mickaël Salaün
2025-07-09 17:31 ` Song Liu
2025-07-09 22:24 ` NeilBrown
2025-07-09 22:50 ` Song Liu
2025-07-10 0:58 ` NeilBrown
2025-07-10 6:28 ` Song Liu
2025-07-14 21:09 ` Song Liu
2025-07-24 17:35 ` Mickaël Salaün
2025-07-26 9:52 ` Song Liu
2025-07-09 22:14 ` NeilBrown
2025-07-09 22:41 ` Song Liu
2025-07-10 0:58 ` NeilBrown
2025-07-07 10:43 ` Christian Brauner
2025-07-03 5:04 ` Song Liu
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=74ae6eb2-cea7-4e3e-82eb-72978dd0f101@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brauner@kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=jack@suse.cz \
--cc=kernel-team@meta.com \
--cc=kpsingh@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=m@maowtm.org \
--cc=martin.lau@linux.dev \
--cc=mattbobrowski@google.com \
--cc=neil@brown.name \
--cc=song@kernel.org \
--cc=songliubraving@meta.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.