From d7b7253a0adc6e24869ef74a2085767cb11eb6fc Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Aug 2025 17:12:15 -0400 Subject: [PATCH] copy_mnt_ns(): use guards * mntput() of rootmnt and pwdmnt done via __free(mntput) * mnt_ns_tree_add() can be done within namespace_excl scope. Signed-off-by: Al Viro --- fs/namespace.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index b4374d6d4bae2..b5a082fae0066 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4158,7 +4158,8 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, struct user_namespace *user_ns, struct fs_struct *new_fs) { struct mnt_namespace *new_ns; - struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; + struct vfsmount *rootmnt __free(mntput) = NULL; + struct vfsmount *pwdmnt __free(mntput) = NULL; struct mount *p, *q; struct mount *old; struct mount *new; @@ -4177,7 +4178,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, if (IS_ERR(new_ns)) return new_ns; - namespace_lock(); + guard(namespace_excl)(); /* First pass: copy the tree topology */ copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE; if (user_ns != ns->user_ns) @@ -4185,13 +4186,11 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, new = copy_tree(old, old->mnt.mnt_root, copy_flags); if (IS_ERR(new)) { emptied_ns = new_ns; - namespace_unlock(); return ERR_CAST(new); } if (user_ns != ns->user_ns) { - lock_mount_hash(); + guard(mount_writer)(); lock_mnt_tree(new); - unlock_mount_hash(); } new_ns->root = new; @@ -4223,13 +4222,6 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, while (p->mnt.mnt_root != q->mnt.mnt_root) p = next_mnt(skip_mnt_tree(p), old); } - namespace_unlock(); - - if (rootmnt) - mntput(rootmnt); - if (pwdmnt) - mntput(pwdmnt); - mnt_ns_tree_add(new_ns); return new_ns; } -- 2.47.3