On Mon, Aug 25, 2025 at 05:43:18AM +0100, Al Viro wrote: > ... and document that locking requirements for is_path_reachable(). > There is one questionable caller in do_listmount() where we are not > holding mount_lock *and* might not have the first argument mounted. > However, in that case it will immediately return true without having > to look at the ancestors. Might be cleaner to move the check into > non-LSTM_ROOT case which it really belongs in - there the check is > not always true and is_mounted() is guaranteed. > > Document the locking environments for is_path_reachable() callers: > get_peer_under_root() > get_dominating_id() > do_statmount() > do_listmount() > > Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx> > --- Reviewed-by: Christian Brauner <brauner@xxxxxxxxxx> > fs/namespace.c | 12 ++++++------ > fs/pnode.c | 3 ++- > 2 files changed, 8 insertions(+), 7 deletions(-) > > diff --git a/fs/namespace.c b/fs/namespace.c > index acacfe767a7c..bf9a3a644faa 100644 > --- a/fs/namespace.c > +++ b/fs/namespace.c > @@ -4592,7 +4592,7 @@ SYSCALL_DEFINE5(move_mount, > /* > * Return true if path is reachable from root > * > - * namespace_sem or mount_lock is held > + * locks: mount_locked_reader || namespace_shared && is_mounted(mnt) > */ > bool is_path_reachable(struct mount *mnt, struct dentry *dentry, > const struct path *root) > @@ -4606,11 +4606,9 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry, > > bool path_is_under(const struct path *path1, const struct path *path2) > { > - bool res; > - read_seqlock_excl(&mount_lock); > - res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2); > - read_sequnlock_excl(&mount_lock); > - return res; > + scoped_guard(mount_locked_reader) > + return is_path_reachable(real_mount(path1->mnt), path1->dentry, > + path2); Same thing, no need for this scoped guard eyesore.