From: Al Viro <viro@zeniv.linux.org.uk>
To: Christian Brauner <brauner@kernel.org>
Cc: Seth Forshee <sforshee@kernel.org>, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH RFC 3/5] fs: fix __lookup_mnt() documentation
Date: Fri, 21 Apr 2023 07:28:38 +0100 [thread overview]
Message-ID: <20230421062838.GD3390869@ZenIV> (raw)
In-Reply-To: <20230202-fs-move-mount-replace-v1-3-9b73026d5f10@kernel.org>
On Sat, Mar 18, 2023 at 04:51:59PM +0100, Christian Brauner wrote:
> The comment on top of __lookup_mnt() states that it finds the first
> mount implying that there could be multiple mounts mounted at the same
> dentry with the same parent.
>
> This was true on old kernels where __lookup_mnt() could encounter a
> stack of child mounts such that each child had the same parent mount and
> was mounted at the same dentry. These were called "shadow mounts" and
> were created during mount propagation. So back then if a mount @m in the
> destination propagation tree already had a child mount @p mounted at
> @mp then any mount @n we propagated to @m at the same @mp would be
> appended after the preexisting mount @p in @mount_hashtable.
>
> This hasn't been the case for quite a while now and I don't see an
> obvious way how such mount stacks could be created in another way.
Not quite, actually - there's a nasty corner case where mnt_change_mountpoint()
would create those. And your subsequent patch steps into the same fun.
Look: suppose the root of the tree you are feeding to attach_recursive_mnt()
has managed to grow a mount right on top of its root. The same will be
reproduced in all its copies created by propagate_mnt(). Now, suppose
one of the slaves of the place where we are trying to mount it on already
has something mounted on it. Well, we hit this:
q = __lookup_mnt(&child->mnt_parent->mnt,
child->mnt_mountpoint);
if (q)
mnt_change_mountpoint(child, smp, q);
which will tuck the child (a copy we'd made) under q (existing mount on
top of the place that copy is for). Result: 'q' overmounts the root of
'child' now. So does the copy of whatever had been overmounting the
root of 'source_mnt'...
And yes, it can happen. Consider e.g. do_loopback(); we have looked
up the mountpoint ('path'), we have looked up the subtree to copy
('old_path'), we had lock_mount(path) made sure that namespace_sem
is held *and* path is not overmounted (followed into whatever
overmounts that might have happened since we looked the mountpoint
up). Now, think what happens if 'old_path' is also overmounted while
we are trying to get namespace_sem...
A similar scenario exists for do_move_mount(), and there it's in
a sense worse - there we have to cope with the possibility that
from_dfd is an O_PATH descriptor created by fsmount(). And I'm
not at all convinced that we can't arrange for automount point
to be there and be triggered by the time of move_mount(2)...
The reason it's worse is that here we can't just follow mounts
all the way down - we want to take the entire mount tree associated
with that descriptor.
> And
> if that's possible it would invalidate assumptions made in other parts
> of the code.
Details? I'm not saying it's impossible - we might have a real bug in
that area.
next prev parent reply other threads:[~2023-04-21 6:28 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-18 15:51 [PATCH RFC 0/5] fs: allow to tuck mounts explicitly Christian Brauner
2023-03-18 15:51 ` [PATCH RFC 1/5] fs: add path_mounted() Christian Brauner
2023-03-18 15:51 ` [PATCH RFC 2/5] pnode: pass mountpoint directly Christian Brauner
2023-03-18 15:51 ` [PATCH RFC 3/5] fs: fix __lookup_mnt() documentation Christian Brauner
2023-04-21 6:28 ` Al Viro [this message]
2023-04-24 16:37 ` Christian Brauner
2023-03-18 15:52 ` [PATCH RFC 4/5] fs: use a for loop when locking a mount Christian Brauner
2023-03-18 15:52 ` [PATCH RFC 5/5] fs: allow to tuck mounts explicitly Christian Brauner
2023-04-21 6:29 ` Al Viro
2023-04-24 17:36 ` Christian Brauner
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=20230421062838.GD3390869@ZenIV \
--to=viro@zeniv.linux.org.uk \
--cc=brauner@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=sforshee@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 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.