]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
new predicate: anon_ns_root(mount)
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 9 Jun 2025 03:25:36 +0000 (23:25 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 29 Jun 2025 22:13:41 +0000 (18:13 -0400)
checks if mount is the root of an anonymouns namespace.
Switch open-coded equivalents to using it.

For mounts that belong to anon namespace !mnt_has_parent(mount)
is the same as mount == ns->root, and intent is more obvious in
the latter form.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/mount.h
fs/namespace.c

index f10776003643aa2bd5f9c9512d12f62fe6fedb7c..f20e6ed845fec013c8f4bfb9ef6b633234f065fe 100644 (file)
@@ -161,6 +161,13 @@ static inline bool is_anon_ns(struct mnt_namespace *ns)
        return ns->seq == 0;
 }
 
+static inline bool anon_ns_root(const struct mount *m)
+{
+       struct mnt_namespace *ns = READ_ONCE(m->mnt_ns);
+
+       return !IS_ERR_OR_NULL(ns) && is_anon_ns(ns) && m == ns->root;
+}
+
 static inline bool mnt_ns_attached(const struct mount *mnt)
 {
        return !RB_EMPTY_NODE(&mnt->mnt_node);
index c4feb83159785f3014c30dfe6d2abf8c3d9a6583..ea01fea2ac93ca5dd4a25831c337b4515589bad5 100644 (file)
@@ -2480,9 +2480,7 @@ struct vfsmount *clone_private_mount(const struct path *path)
         * loops get created.
         */
        if (!check_mnt(old_mnt)) {
-               if (!is_mounted(&old_mnt->mnt) ||
-                       !is_anon_ns(old_mnt->mnt_ns) ||
-                       mnt_has_parent(old_mnt))
+               if (!anon_ns_root(old_mnt))
                        return ERR_PTR(-EINVAL);
 
                if (!check_for_nsfs_mounts(old_mnt))
@@ -3649,9 +3647,6 @@ static int do_move_mount(struct path *old_path,
        ns = old->mnt_ns;
 
        err = -EINVAL;
-       /* The thing moved must be mounted... */
-       if (!is_mounted(&old->mnt))
-               goto out;
 
        if (check_mnt(old)) {
                /* if the source is in our namespace... */
@@ -3664,10 +3659,8 @@ static int do_move_mount(struct path *old_path,
        } else {
                /*
                 * otherwise the source must be the root of some anon namespace.
-                * AV: check for mount being root of an anon namespace is worth
-                * an inlined predicate...
                 */
-               if (!is_anon_ns(ns) || mnt_has_parent(old))
+               if (!anon_ns_root(old))
                        goto out;
                /*
                 * Bail out early if the target is within the same namespace -
@@ -5028,22 +5021,7 @@ static int do_mount_setattr(struct path *path, struct mount_kattr *kattr)
        err = -EINVAL;
        lock_mount_hash();
 
-       /* Ensure that this isn't anything purely vfs internal. */
-       if (!is_mounted(&mnt->mnt))
-               goto out;
-
-       /*
-        * If this is an attached mount make sure it's located in the callers
-        * mount namespace. If it's not don't let the caller interact with it.
-        *
-        * If this mount doesn't have a parent it's most often simply a
-        * detached mount with an anonymous mount namespace. IOW, something
-        * that's simply not attached yet. But there are apparently also users
-        * that do change mount properties on the rootfs itself. That obviously
-        * neither has a parent nor is it a detached mount so we cannot
-        * unconditionally check for detached mounts.
-        */
-       if ((mnt_has_parent(mnt) || !is_anon_ns(mnt->mnt_ns)) && !check_mnt(mnt))
+       if (!anon_ns_root(mnt) && !check_mnt(mnt))
                goto out;
 
        /*