mirror of https://github.com/torvalds/linux.git
new predicate: anon_ns_root(mount)
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>
This commit is contained in:
parent
e031251cb2
commit
05da054d43
|
|
@ -161,6 +161,13 @@ static inline bool is_anon_ns(struct mnt_namespace *ns)
|
||||||
return ns->seq == 0;
|
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)
|
static inline bool mnt_ns_attached(const struct mount *mnt)
|
||||||
{
|
{
|
||||||
return !RB_EMPTY_NODE(&mnt->mnt_node);
|
return !RB_EMPTY_NODE(&mnt->mnt_node);
|
||||||
|
|
|
||||||
|
|
@ -2480,9 +2480,7 @@ struct vfsmount *clone_private_mount(const struct path *path)
|
||||||
* loops get created.
|
* loops get created.
|
||||||
*/
|
*/
|
||||||
if (!check_mnt(old_mnt)) {
|
if (!check_mnt(old_mnt)) {
|
||||||
if (!is_mounted(&old_mnt->mnt) ||
|
if (!anon_ns_root(old_mnt))
|
||||||
!is_anon_ns(old_mnt->mnt_ns) ||
|
|
||||||
mnt_has_parent(old_mnt))
|
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
if (!check_for_nsfs_mounts(old_mnt))
|
if (!check_for_nsfs_mounts(old_mnt))
|
||||||
|
|
@ -3649,9 +3647,6 @@ static int do_move_mount(struct path *old_path,
|
||||||
ns = old->mnt_ns;
|
ns = old->mnt_ns;
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
/* The thing moved must be mounted... */
|
|
||||||
if (!is_mounted(&old->mnt))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (check_mnt(old)) {
|
if (check_mnt(old)) {
|
||||||
/* if the source is in our namespace... */
|
/* if the source is in our namespace... */
|
||||||
|
|
@ -3664,10 +3659,8 @@ static int do_move_mount(struct path *old_path,
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* otherwise the source must be the root of some anon namespace.
|
* 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;
|
goto out;
|
||||||
/*
|
/*
|
||||||
* Bail out early if the target is within the same namespace -
|
* 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;
|
err = -EINVAL;
|
||||||
lock_mount_hash();
|
lock_mount_hash();
|
||||||
|
|
||||||
/* Ensure that this isn't anything purely vfs internal. */
|
if (!anon_ns_root(mnt) && !check_mnt(mnt))
|
||||||
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))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue