// SPDX-License-Identifier: GPL-2.0-only
/*
 *  linux/fs/namespace.c
 *
 * (C) Copyright Al Viro 2000, 2001
 *
 * Based on code from fs/super.c, copyright Linus Torvalds and others.
 * Heavily rewritten.
 */

#include <linux/syscalls.h>
#include <linux/export.h>
#include <linux/capability.h>
#include <linux/mnt_namespace.h>
#include <linux/user_namespace.h>
#include <linux/namei.h>
#include <linux/security.h>
#include <linux/cred.h>
#include <linux/idr.h>
#include <linux/init.h>		/* init_rootfs */
#include <linux/fs_struct.h>	/* get_fs_root et.al. */
#include <linux/fsnotify.h>	/* fsnotify_vfsmount_delete */
#include <linux/file.h>
#include <linux/uaccess.h>
#include <linux/proc_ns.h>
#include <linux/magic.h>
#include <linux/memblock.h>
#include <linux/proc_fs.h>
#include <linux/task_work.h>
#include <linux/sched/task.h>
#include <uapi/linux/mount.h>
#include <linux/fs_context.h>
#include <linux/shmem_fs.h>
#include <linux/mnt_idmapping.h>
#include <linux/pidfs.h>
#include <linux/nstree.h>

#include "pnode.h"
#include "internal.h"

/* Maximum number of mounts in a mount namespace */
static unsigned int sysctl_mount_max __read_mostly = 100000;

static unsigned int m_hash_mask __ro_after_init;
static unsigned int m_hash_shift __ro_after_init;
static unsigned int mp_hash_mask __ro_after_init;
static unsigned int mp_hash_shift __ro_after_init;

static __initdata unsigned long mhash_entries;
static int __init set_mhash_entries(char *str)
{
	return kstrtoul(str, 0, &mhash_entries) == 0;
}
__setup("mhash_entries=", set_mhash_entries);

static __initdata unsigned long mphash_entries;
static int __init set_mphash_entries(char *str)
{
	return kstrtoul(str, 0, &mphash_entries) == 0;
}
__setup("mphash_entries=", set_mphash_entries);

static char * __initdata initramfs_options;
static int __init initramfs_options_setup(char *str)
{
	initramfs_options = str;
	return 1;
}

__setup("initramfs_options=", initramfs_options_setup);

static u64 event;
static DEFINE_XARRAY_FLAGS(mnt_id_xa, XA_FLAGS_ALLOC);
static DEFINE_IDA(mnt_group_ida);

/* Don't allow confusion with old 32bit mount ID */
#define MNT_UNIQUE_ID_OFFSET (1ULL << 31)
static u64 mnt_id_ctr = MNT_UNIQUE_ID_OFFSET;

static struct hlist_head *mount_hashtable __ro_after_init;
static struct hlist_head *mountpoint_hashtable __ro_after_init;
static struct kmem_cache *mnt_cache __ro_after_init;
static DECLARE_RWSEM(namespace_sem);
static HLIST_HEAD(unmounted);	/* protected by namespace_sem */
static LIST_HEAD(ex_mountpoints); /* protected by namespace_sem */
static struct mnt_namespace *emptied_ns; /* protected by namespace_sem */

static inline void namespace_lock(void);
static void namespace_unlock(void);
DEFINE_LOCK_GUARD_0(namespace_excl, namespace_lock(), namespace_unlock())
DEFINE_LOCK_GUARD_0(namespace_shared, down_read(&namespace_sem),
				      up_read(&namespace_sem))

DEFINE_FREE(mntput, struct vfsmount *, if (!IS_ERR(_T)) mntput(_T))

#ifdef CONFIG_FSNOTIFY
LIST_HEAD(notify_list); /* protected by namespace_sem */
#endif

enum mount_kattr_flags_t {
	MOUNT_KATTR_RECURSE		= (1 << 0),
	MOUNT_KATTR_IDMAP_REPLACE	= (1 << 1),
};

struct mount_kattr {
	unsigned int attr_set;
	unsigned int attr_clr;
	unsigned int propagation;
	unsigned int lookup_flags;
	enum mount_kattr_flags_t kflags;
	struct user_namespace *mnt_userns;
	struct mnt_idmap *mnt_idmap;
};

/* /sys/fs */
struct kobject *fs_kobj __ro_after_init;
EXPORT_SYMBOL_GPL(fs_kobj);

/*
 * vfsmount lock may be taken for read to prevent changes to the
 * vfsmount hash, ie. during mountpoint lookups or walking back
 * up the tree.
 *
 * It should be taken for write in all cases where the vfsmount
 * tree or hash is modified or when a vfsmount structure is modified.
 */
__cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock);

static void mnt_ns_release(struct mnt_namespace *ns)
{
	/* keep alive for {list,stat}mount() */
	if (ns && refcount_dec_and_test(&ns->passive)) {
		fsnotify_mntns_delete(ns);
		put_user_ns(ns->user_ns);
		kfree(ns);
	}
}
DEFINE_FREE(mnt_ns_release, struct mnt_namespace *,
	    if (!IS_ERR(_T)) mnt_ns_release(_T))

static void mnt_ns_release_rcu(struct rcu_head *rcu)
{
	mnt_ns_release(container_of(rcu, struct mnt_namespace, ns.ns_rcu));
}

static void mnt_ns_tree_remove(struct mnt_namespace *ns)
{
	/* remove from global mount namespace list */
	if (ns_tree_active(ns))
		ns_tree_remove(ns);

	call_rcu(&ns->ns.ns_rcu, mnt_ns_release_rcu);
}

/*
 * Lookup a mount namespace by id and take a passive reference count. Taking a
 * passive reference means the mount namespace can be emptied if e.g., the last
 * task holding an active reference exits. To access the mounts of the
 * namespace the @namespace_sem must first be acquired. If the namespace has
 * already shut down before acquiring @namespace_sem, {list,stat}mount() will
 * see that the mount rbtree of the namespace is empty.
 *
 * Note the lookup is lockless protected by a sequence counter. We only
 * need to guard against false negatives as false positives aren't
 * possible. So if we didn't find a mount namespace and the sequence
 * counter has changed we need to retry. If the sequence counter is
 * still the same we know the search actually failed.
 */
static struct mnt_namespace *lookup_mnt_ns(u64 mnt_ns_id)
{
	struct mnt_namespace *mnt_ns;
	struct ns_common *ns;

	guard(rcu)();
	ns = ns_tree_lookup_rcu(mnt_ns_id, CLONE_NEWNS);
	if (!ns)
		return NULL;

	/*
	 * The last reference count is put with RCU delay so we can
	 * unconditonally acquire a reference here.
	 */
	mnt_ns = container_of(ns, struct mnt_namespace, ns);
	refcount_inc(&mnt_ns->passive);
	return mnt_ns;
}

static inline void lock_mount_hash(void)
{
	write_seqlock(&mount_lock);
}

static inline void unlock_mount_hash(void)
{
	write_sequnlock(&mount_lock);
}

static inline struct hlist_head *m_hash(struct vfsmount *mnt, struct dentry *dentry)
{
	unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
	tmp += ((unsigned long)dentry / L1_CACHE_BYTES);
	tmp = tmp + (tmp >> m_hash_shift);
	return &mount_hashtable[tmp & m_hash_mask];
}

static inline struct hlist_head *mp_hash(struct dentry *dentry)
{
	unsigned long tmp = ((unsigned long)dentry / L1_CACHE_BYTES);
	tmp = tmp + (tmp >> mp_hash_shift);
	return &mountpoint_hashtable[tmp & mp_hash_mask];
}

static int mnt_alloc_id(struct mount *mnt)
{
	int res;

	xa_lock(&mnt_id_xa);
	res = __xa_alloc(&mnt_id_xa, &mnt->mnt_id, mnt, xa_limit_31b, GFP_KERNEL);
	if (!res)
		mnt->mnt_id_unique = ++mnt_id_ctr;
	xa_unlock(&mnt_id_xa);
	return res;
}

static void mnt_free_id(struct mount *mnt)
{
	xa_erase(&mnt_id_xa, mnt->mnt_id);
}

/*
 * Allocate a new peer group ID
 */
static int mnt_alloc_group_id(struct mount *mnt)
{
	int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL);

	if (res < 0)
		return res;
	mnt->mnt_group_id = res;
	return 0;
}

/*
 * Release a peer group ID
 */
void mnt_release_group_id(struct mount *mnt)
{
	ida_free(&mnt_group_ida, mnt->mnt_group_id);
	mnt->mnt_group_id = 0;
}

/*
 * vfsmount lock must be held for read
 */
static inline void mnt_add_count(struct mount *mnt, int n)
{
#ifdef CONFIG_SMP
	this_cpu_add(mnt->mnt_pcp->mnt_count, n);
#else
	preempt_disable();
	mnt->mnt_count += n;
	preempt_enable();
#endif
}

/*
 * vfsmount lock must be held for write
 */
int mnt_get_count(struct mount *mnt)
{
#ifdef CONFIG_SMP
	int count = 0;
	int cpu;

	for_each_possible_cpu(cpu) {
		count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
	}

	return count;
#else
	return mnt->mnt_count;
#endif
}

static struct mount *alloc_vfsmnt(const char *name)
{
	struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
	if (mnt) {
		int err;

		err = mnt_alloc_id(mnt);
		if (err)
			goto out_free_cache;

		if (name)
			mnt->mnt_devname = kstrdup_const(name,
							 GFP_KERNEL_ACCOUNT);
		else
			mnt->mnt_devname = "none";
		if (!mnt->mnt_devname)
			goto out_free_id;

#ifdef CONFIG_SMP
		mnt->mnt_pcp = alloc_percpu(struct mnt_pcp);
		if (!mnt->mnt_pcp)
			goto out_free_devname;

		this_cpu_add(mnt->mnt_pcp->mnt_count, 1);
#else
		mnt->mnt_count = 1;
		mnt->mnt_writers = 0;
#endif

		INIT_HLIST_NODE(&mnt->mnt_hash);
		INIT_LIST_HEAD(&mnt->mnt_child);
		INIT_LIST_HEAD(&mnt->mnt_mounts);
		INIT_LIST_HEAD(&mnt->mnt_list);
		INIT_LIST_HEAD(&mnt->mnt_expire);
		INIT_LIST_HEAD(&mnt->mnt_share);
		INIT_HLIST_HEAD(&mnt->mnt_slave_list);
		INIT_HLIST_NODE(&mnt->mnt_slave);
		INIT_HLIST_NODE(&mnt->mnt_mp_list);
		INIT_HLIST_HEAD(&mnt->mnt_stuck_children);
		RB_CLEAR_NODE(&mnt->mnt_node);
		mnt->mnt.mnt_idmap = &nop_mnt_idmap;
	}
	return mnt;

#ifdef CONFIG_SMP
out_free_devname:
	kfree_const(mnt->mnt_devname);
#endif
out_free_id:
	mnt_free_id(mnt);
out_free_cache:
	kmem_cache_free(mnt_cache, mnt);
	return NULL;
}

/*
 * Most r/o checks on a fs are for operations that take
 * discrete amounts of time, like a write() or unlink().
 * We must keep track of when those operations start
 * (for permission checks) and when they end, so that
 * we can determine when writes are able to occur to
 * a filesystem.
 */
/*
 * __mnt_is_readonly: check whether a mount is read-only
 * @mnt: the mount to check for its write status
 *
 * This shouldn't be used directly ouside of the VFS.
 * It does not guarantee that the filesystem will stay
 * r/w, just that it is right *now*.  This can not and
 * should not be used in place of IS_RDONLY(inode).
 * mnt_want/drop_write() will _keep_ the filesystem
 * r/w.
 */
bool __mnt_is_readonly(const struct vfsmount *mnt)
{
	return (mnt->mnt_flags & MNT_READONLY) || sb_rdonly(mnt->mnt_sb);
}
EXPORT_SYMBOL_GPL(__mnt_is_readonly);

static inline void mnt_inc_writers(struct mount *mnt)
{
#ifdef CONFIG_SMP
	this_cpu_inc(mnt->mnt_pcp->mnt_writers);
#else
	mnt->mnt_writers++;
#endif
}

static inline void mnt_dec_writers(struct mount *mnt)
{
#ifdef CONFIG_SMP
	this_cpu_dec(mnt->mnt_pcp->mnt_writers);
#else
	mnt->mnt_writers--;
#endif
}

static unsigned int mnt_get_writers(struct mount *mnt)
{
#ifdef CONFIG_SMP
	unsigned int count = 0;
	int cpu;

	for_each_possible_cpu(cpu) {
		count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_writers;
	}

	return count;
#else
	return mnt->mnt_writers;
#endif
}

static int mnt_is_readonly(const struct vfsmount *mnt)
{
	if (READ_ONCE(mnt->mnt_sb->s_readonly_remount))
		return 1;
	/*
	 * The barrier pairs with the barrier in sb_start_ro_state_change()
	 * making sure if we don't see s_readonly_remount set yet, we also will
	 * not see any superblock / mount flag changes done by remount.
	 * It also pairs with the barrier in sb_end_ro_state_change()
	 * assuring that if we see s_readonly_remount already cleared, we will
	 * see the values of superblock / mount flags updated by remount.
	 */
	smp_rmb();
	return __mnt_is_readonly(mnt);
}

/*
 * Most r/o & frozen checks on a fs are for operations that take discrete
 * amounts of time, like a write() or unlink().  We must keep track of when
 * those operations start (for permission checks) and when they end, so that we
 * can determine when writes are able to occur to a filesystem.
 */
/**
 * mnt_get_write_access - get write access to a mount without freeze protection
 * @m: the mount on which to take a write
 *
 * This tells the low-level filesystem that a write is about to be performed to
 * it, and makes sure that writes are allowed (mnt it read-write) before
 * returning success. This operation does not protect against filesystem being
 * frozen. When the write operation is finished, mnt_put_write_access() must be
 * called. This is effectively a refcount.
 */
int mnt_get_write_access(struct vfsmount *m)
{
	struct mount *mnt = real_mount(m);
	int ret = 0;

	preempt_disable();
	mnt_inc_writers(mnt);
	/*
	 * The store to mnt_inc_writers must be visible before we pass
	 * WRITE_HOLD loop below, so that the slowpath can see our
	 * incremented count after it has set WRITE_HOLD.
	 */
	smp_mb();
	might_lock(&mount_lock.lock);
	while (__test_write_hold(READ_ONCE(mnt->mnt_pprev_for_sb))) {
		if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
			cpu_relax();
		} else {
			/*
			 * This prevents priority inversion, if the task
			 * setting WRITE_HOLD got preempted on a remote
			 * CPU, and it prevents life lock if the task setting
			 * WRITE_HOLD has a lower priority and is bound to
			 * the same CPU as the task that is spinning here.
			 */
			preempt_enable();
			read_seqlock_excl(&mount_lock);
			read_sequnlock_excl(&mount_lock);
			preempt_disable();
		}
	}
	/*
	 * The barrier pairs with the barrier sb_start_ro_state_change() making
	 * sure that if we see WRITE_HOLD cleared, we will also see
	 * s_readonly_remount set (or even SB_RDONLY / MNT_READONLY flags) in
	 * mnt_is_readonly() and bail in case we are racing with remount
	 * read-only.
	 */
	smp_rmb();
	if (mnt_is_readonly(m)) {
		mnt_dec_writers(mnt);
		ret = -EROFS;
	}
	preempt_enable();

	return ret;
}
EXPORT_SYMBOL_GPL(mnt_get_write_access);

/**
 * mnt_want_write - get write access to a mount
 * @m: the mount on which to take a write
 *
 * This tells the low-level filesystem that a write is about to be performed to
 * it, and makes sure that writes are allowed (mount is read-write, filesystem
 * is not frozen) before returning success.  When the write operation is
 * finished, mnt_drop_write() must be called.  This is effectively a refcount.
 */
int mnt_want_write(struct vfsmount *m)
{
	int ret;

	sb_start_write(m->mnt_sb);
	ret = mnt_get_write_access(m);
	if (ret)
		sb_end_write(m->mnt_sb);
	return ret;
}
EXPORT_SYMBOL_GPL(mnt_want_write);

/**
 * mnt_get_write_access_file - get write access to a file's mount
 * @file: the file who's mount on which to take a write
 *
 * This is like mnt_get_write_access, but if @file is already open for write it
 * skips incrementing mnt_writers (since the open file already has a reference)
 * and instead only does the check for emergency r/o remounts.  This must be
 * paired with mnt_put_write_access_file.
 */
int mnt_get_write_access_file(struct file *file)
{
	if (file->f_mode & FMODE_WRITER) {
		/*
		 * Superblock may have become readonly while there are still
		 * writable fd's, e.g. due to a fs error with errors=remount-ro
		 */
		if (__mnt_is_readonly(file->f_path.mnt))
			return -EROFS;
		return 0;
	}
	return mnt_get_write_access(file->f_path.mnt);
}

/**
 * mnt_want_write_file - get write access to a file's mount
 * @file: the file who's mount on which to take a write
 *
 * This is like mnt_want_write, but if the file is already open for writing it
 * skips incrementing mnt_writers (since the open file already has a reference)
 * and instead only does the freeze protection and the check for emergency r/o
 * remounts.  This must be paired with mnt_drop_write_file.
 */
int mnt_want_write_file(struct file *file)
{
	int ret;

	sb_start_write(file_inode(file)->i_sb);
	ret = mnt_get_write_access_file(file);
	if (ret)
		sb_end_write(file_inode(file)->i_sb);
	return ret;
}
EXPORT_SYMBOL_GPL(mnt_want_write_file);

/**
 * mnt_put_write_access - give up write access to a mount
 * @mnt: the mount on which to give up write access
 *
 * Tells the low-level filesystem that we are done
 * performing writes to it.  Must be matched with
 * mnt_get_write_access() call above.
 */
void mnt_put_write_access(struct vfsmount *mnt)
{
	preempt_disable();
	mnt_dec_writers(real_mount(mnt));
	preempt_enable();
}
EXPORT_SYMBOL_GPL(mnt_put_write_access);

/**
 * mnt_drop_write - give up write access to a mount
 * @mnt: the mount on which to give up write access
 *
 * Tells the low-level filesystem that we are done performing writes to it and
 * also allows filesystem to be frozen again.  Must be matched with
 * mnt_want_write() call above.
 */
void mnt_drop_write(struct vfsmount *mnt)
{
	mnt_put_write_access(mnt);
	sb_end_write(mnt->mnt_sb);
}
EXPORT_SYMBOL_GPL(mnt_drop_write);

void mnt_put_write_access_file(struct file *file)
{
	if (!(file->f_mode & FMODE_WRITER))
		mnt_put_write_access(file->f_path.mnt);
}

void mnt_drop_write_file(struct file *file)
{
	mnt_put_write_access_file(file);
	sb_end_write(file_inode(file)->i_sb);
}
EXPORT_SYMBOL(mnt_drop_write_file);

/**
 * mnt_hold_writers - prevent write access to the given mount
 * @mnt: mnt to prevent write access to
 *
 * Prevents write access to @mnt if there are no active writers for @mnt.
 * This function needs to be called and return successfully before changing
 * properties of @mnt that need to remain stable for callers with write access
 * to @mnt.
 *
 * After this functions has been called successfully callers must pair it with
 * a call to mnt_unhold_writers() in order to stop preventing write access to
 * @mnt.
 *
 * Context: This function expects to be in mount_locked_reader scope serializing
 *          setting WRITE_HOLD.
 * Return: On success 0 is returned.
 *	   On error, -EBUSY is returned.
 */
static inline int mnt_hold_writers(struct mount *mnt)
{
	set_write_hold(mnt);
	/*
	 * After storing WRITE_HOLD, we'll read the counters. This store
	 * should be visible before we do.
	 */
	smp_mb();

	/*
	 * With writers on hold, if this value is zero, then there are
	 * definitely no active writers (although held writers may subsequently
	 * increment the count, they'll have to wait, and decrement it after
	 * seeing MNT_READONLY).
	 *
	 * It is OK to have counter incremented on one CPU and decremented on
	 * another: the sum will add up correctly. The danger would be when we
	 * sum up each counter, if we read a counter before it is incremented,
	 * but then read another CPU's count which it has been subsequently
	 * decremented from -- we would see more decrements than we should.
	 * WRITE_HOLD protects against this scenario, because
	 * mnt_want_write first increments count, then smp_mb, then spins on
	 * WRITE_HOLD, so it can't be decremented by another CPU while
	 * we're counting up here.
	 */
	if (mnt_get_writers(mnt) > 0)
		return -EBUSY;

	return 0;
}

/**
 * mnt_unhold_writers - stop preventing write access to the given mount
 * @mnt: mnt to stop preventing write access to
 *
 * Stop preventing write access to @mnt allowing callers to gain write access
 * to @mnt again.
 *
 * This function can only be called after a call to mnt_hold_writers().
 *
 * Context: This function expects to be in the same mount_locked_reader scope
 * as the matching mnt_hold_writers().
 */
static inline void mnt_unhold_writers(struct mount *mnt)
{
	if (!test_write_hold(mnt))
		return;
	/*
	 * MNT_READONLY must become visible before ~WRITE_HOLD, so writers
	 * that become unheld will see MNT_READONLY.
	 */
	smp_wmb();
	clear_write_hold(mnt);
}

static inline void mnt_del_instance(struct mount *m)
{
	struct mount **p = m->mnt_pprev_for_sb;
	struct mount *next = m->mnt_next_for_sb;

	if (next)
		next->mnt_pprev_for_sb = p;
	*p = next;
}

static inline void mnt_add_instance(struct mount *m, struct super_block *s)
{
	struct mount *first = s->s_mounts;

	if (first)
		first->mnt_pprev_for_sb = &m->mnt_next_for_sb;
	m->mnt_next_for_sb = first;
	m->mnt_pprev_for_sb = &s->s_mounts;
	s->s_mounts = m;
}

static int mnt_make_readonly(struct mount *mnt)
{
	int ret;

	ret = mnt_hold_writers(mnt);
	if (!ret)
		mnt->mnt.mnt_flags |= MNT_READONLY;
	mnt_unhold_writers(mnt);
	return ret;
}

int sb_prepare_remount_readonly(struct super_block *sb)
{
	int err = 0;

	/* Racy optimization.  Recheck the counter under WRITE_HOLD */
	if (atomic_long_read(&sb->s_remove_count))
		return -EBUSY;

	guard(mount_locked_reader)();

	for (struct mount *m = sb->s_mounts; m; m = m->mnt_next_for_sb) {
		if (!(m->mnt.mnt_flags & MNT_READONLY)) {
			err = mnt_hold_writers(m);
			if (err)
				break;
		}
	}
	if (!err && atomic_long_read(&sb->s_remove_count))
		err = -EBUSY;

	if (!err)
		sb_start_ro_state_change(sb);
	for (struct mount *m = sb->s_mounts; m; m = m->mnt_next_for_sb) {
		if (test_write_hold(m))
			clear_write_hold(m);
	}

	return err;
}

static void free_vfsmnt(struct mount *mnt)
{
	mnt_idmap_put(mnt_idmap(&mnt->mnt));
	kfree_const(mnt->mnt_devname);
#ifdef CONFIG_SMP
	free_percpu(mnt->mnt_pcp);
#endif
	kmem_cache_free(mnt_cache, mnt);
}

static void delayed_free_vfsmnt(struct rcu_head *head)
{
	free_vfsmnt(container_of(head, struct mount, mnt_rcu));
}

/* call under rcu_read_lock */
int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
{
	struct mount *mnt;
	if (read_seqretry(&mount_lock, seq))
		return 1;
	if (bastard == NULL)
		return 0;
	mnt = real_mount(bastard);
	mnt_add_count(mnt, 1);
	smp_mb();		// see mntput_no_expire() and do_umount()
	if (likely(!read_seqretry(&mount_lock, seq)))
		return 0;
	lock_mount_hash();
	if (unlikely(bastard->mnt_flags & (MNT_SYNC_UMOUNT | MNT_DOOMED))) {
		mnt_add_count(mnt, -1);
		unlock_mount_hash();
		return 1;
	}
	unlock_mount_hash();
	/* caller will mntput() */
	return -1;
}

/* call under rcu_read_lock */
static bool legitimize_mnt(struct vfsmount *bastard, unsigned seq)
{
	int res = __legitimize_mnt(bastard, seq);
	if (likely(!res))
		return true;
	if (unlikely(res < 0)) {
		rcu_read_unlock();
		mntput(bastard);
		rcu_read_lock();
	}
	return false;
}

/**
 * __lookup_mnt - mount hash lookup
 * @mnt:	parent mount
 * @dentry:	dentry of mountpoint
 *
 * If @mnt has a child mount @c mounted on @dentry find and return it.
 * Caller must either hold the spinlock component of @mount_lock or
 * hold rcu_read_lock(), sample the seqcount component before the call
 * and recheck it afterwards.
 *
 * Return: The child of @mnt mounted on @dentry or %NULL.
 */
struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
{
	struct hlist_head *head = m_hash(mnt, dentry);
	struct mount *p;

	hlist_for_each_entry_rcu(p, head, mnt_hash)
		if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
			return p;
	return NULL;
}

/**
 * lookup_mnt - Return the child mount mounted at given location
 * @path:	location in the namespace
 *
 * Acquires and returns a new reference to mount at given location
 * or %NULL if nothing is mounted there.
 */
struct vfsmount *lookup_mnt(const struct path *path)
{
	struct mount *child_mnt;
	struct vfsmount *m;
	unsigned seq;

	rcu_read_lock();
	do {
		seq = read_seqbegin(&mount_lock);
		child_mnt = __lookup_mnt(path->mnt, path->dentry);
		m = child_mnt ? &child_mnt->mnt : NULL;
	} while (!legitimize_mnt(m, seq));
	rcu_read_unlock();
	return m;
}

/*
 * __is_local_mountpoint - Test to see if dentry is a mountpoint in the
 *                         current mount namespace.
 *
 * The common case is dentries are not mountpoints at all and that
 * test is handled inline.  For the slow case when we are actually
 * dealing with a mountpoint of some kind, walk through all of the
 * mounts in the current mount namespace and test to see if the dentry
 * is a mountpoint.
 *
 * The mount_hashtable is not usable in the context because we
 * need to identify all mounts that may be in the current mount
 * namespace not just a mount that happens to have some specified
 * parent mount.
 */
bool __is_local_mountpoint(const struct dentry *dentry)
{
	struct mnt_namespace *ns = current->nsproxy->mnt_ns;
	struct mount *mnt, *n;

	guard(namespace_shared)();

	rbtree_postorder_for_each_entry_safe(mnt, n, &ns->mounts, mnt_node)
		if (mnt->mnt_mountpoint == dentry)
			return true;

	return false;
}

struct pinned_mountpoint {
	struct hlist_node node;
	struct mountpoint *mp;
	struct mount *parent;
};

static bool lookup_mountpoint(struct dentry *dentry, struct pinned_mountpoint *m)
{
	struct hlist_head *chain = mp_hash(dentry);
	struct mountpoint *mp;

	hlist_for_each_entry(mp, chain, m_hash) {
		if (mp->m_dentry == dentry) {
			hlist_add_head(&m->node, &mp->m_list);
			m->mp = mp;
			return true;
		}
	}
	return false;
}

static int get_mountpoint(struct dentry *dentry, struct pinned_mountpoint *m)
{
	struct mountpoint *mp __free(kfree) = NULL;
	bool found;
	int ret;

	if (d_mountpoint(dentry)) {
		/* might be worth a WARN_ON() */
		if (d_unlinked(dentry))
			return -ENOENT;
mountpoint:
		read_seqlock_excl(&mount_lock);
		found = lookup_mountpoint(dentry, m);
		read_sequnlock_excl(&mount_lock);
		if (found)
			return 0;
	}

	if (!mp)
		mp = kmalloc_obj(struct mountpoint);
	if (!mp)
		return -ENOMEM;

	/* Exactly one processes may set d_mounted */
	ret = d_set_mounted(dentry);

	/* Someone else set d_mounted? */
	if (ret == -EBUSY)
		goto mountpoint;

	/* The dentry is not available as a mountpoint? */
	if (ret)
		return ret;

	/* Add the new mountpoint to the hash table */
	read_seqlock_excl(&mount_lock);
	mp->m_dentry = dget(dentry);
	hlist_add_head(&mp->m_hash, mp_hash(dentry));
	INIT_HLIST_HEAD(&mp->m_list);
	hlist_add_head(&m->node, &mp->m_list);
	m->mp = no_free_ptr(mp);
	read_sequnlock_excl(&mount_lock);
	return 0;
}

/*
 * vfsmount lock must be held.  Additionally, the caller is responsible
 * for serializing calls for given disposal list.
 */
static void maybe_free_mountpoint(struct mountpoint *mp, struct list_head *list)
{
	if (hlist_empty(&mp->m_list)) {
		struct dentry *dentry = mp->m_dentry;
		spin_lock(&dentry->d_lock);
		dentry->d_flags &= ~DCACHE_MOUNTED;
		spin_unlock(&dentry->d_lock);
		dput_to_list(dentry, list);
		hlist_del(&mp->m_hash);
		kfree(mp);
	}
}

/*
 * locks: mount_lock [read_seqlock_excl], namespace_sem [excl]
 */
static void unpin_mountpoint(struct pinned_mountpoint *m)
{
	if (m->mp) {
		hlist_del(&m->node);
		maybe_free_mountpoint(m->mp, &ex_mountpoints);
	}
}

static inline int check_mnt(const struct mount *mnt)
{
	return mnt->mnt_ns == current->nsproxy->mnt_ns;
}

static inline bool check_anonymous_mnt(struct mount *mnt)
{
	u64 seq;

	if (!is_anon_ns(mnt->mnt_ns))
		return false;

	seq = mnt->mnt_ns->seq_origin;
	return !seq || (seq == current->nsproxy->mnt_ns->ns.ns_id);
}

/*
 * vfsmount lock must be held for write
 */
static void touch_mnt_namespace(struct mnt_namespace *ns)
{
	if (ns) {
		ns->event = ++event;
		wake_up_interruptible(&ns->poll);
	}
}

/*
 * vfsmount lock must be held for write
 */
static void __touch_mnt_namespace(struct mnt_namespace *ns)
{
	if (ns && ns->event != event) {
		ns->event = event;
		wake_up_interruptible(&ns->poll);
	}
}

/*
 * locks: mount_lock[write_seqlock]
 */
static void __umount_mnt(struct mount *mnt, struct list_head *shrink_list)
{
	struct mountpoint *mp;
	struct mount *parent = mnt->mnt_parent;
	if (unlikely(parent->overmount == mnt))
		parent->overmount = NULL;
	mnt->mnt_parent = mnt;
	mnt->mnt_mountpoint = mnt->mnt.mnt_root;
	list_del_init(&mnt->mnt_child);
	hlist_del_init_rcu(&mnt->mnt_hash);
	hlist_del_init(&mnt->mnt_mp_list);
	mp = mnt->mnt_mp;
	mnt->mnt_mp = NULL;
	maybe_free_mountpoint(mp, shrink_list);
}

/*
 * locks: mount_lock[write_seqlock], namespace_sem[excl] (for ex_mountpoints)
 */
static void umount_mnt(struct mount *mnt)
{
	__umount_mnt(mnt, &ex_mountpoints);
}

/*
 * vfsmount lock must be held for write
 */
void mnt_set_mountpoint(struct mount *mnt,
			struct mountpoint *mp,
			struct mount *child_mnt)
{
	child_mnt->mnt_mountpoint = mp->m_dentry;
	child_mnt->mnt_parent = mnt;
	child_mnt->mnt_mp = mp;
	hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list);
}

static void make_visible(struct mount *mnt)
{
	struct mount *parent = mnt->mnt_parent;
	if (unlikely(mnt->mnt_mountpoint == parent->mnt.mnt_root))
		parent->overmount = mnt;
	hlist_add_head_rcu(&mnt->mnt_hash,
			   m_hash(&parent->mnt, mnt->mnt_mountpoint));
	list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
}

/**
 * attach_mnt - mount a mount, attach to @mount_hashtable and parent's
 *              list of child mounts
 * @parent:  the parent
 * @mnt:     the new mount
 * @mp:      the new mountpoint
 *
 * Mount @mnt at @mp on @parent. Then attach @mnt
 * to @parent's child mount list and to @mount_hashtable.
 *
 * Note, when make_visible() is called @mnt->mnt_parent already points
 * to the correct parent.
 *
 * Context: This function expects namespace_lock() and lock_mount_hash()
 *          to have been acquired in that order.
 */
static void attach_mnt(struct mount *mnt, struct mount *parent,
		       struct mountpoint *mp)
{
	mnt_set_mountpoint(parent, mp, mnt);
	make_visible(mnt);
}

void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, struct mount *mnt)
{
	struct mountpoint *old_mp = mnt->mnt_mp;

	list_del_init(&mnt->mnt_child);
	hlist_del_init(&mnt->mnt_mp_list);
	hlist_del_init_rcu(&mnt->mnt_hash);

	attach_mnt(mnt, parent, mp);

	maybe_free_mountpoint(old_mp, &ex_mountpoints);
}

static inline struct mount *node_to_mount(struct rb_node *node)
{
	return node ? rb_entry(node, struct mount, mnt_node) : NULL;
}

static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt)
{
	struct rb_node **link = &ns->mounts.rb_node;
	struct rb_node *parent = NULL;
	bool mnt_first_node = true, mnt_last_node = true;

	WARN_ON(mnt_ns_attached(mnt));
	mnt->mnt_ns = ns;
	while (*link) {
		parent = *link;
		if (mnt->mnt_id_unique < node_to_mount(parent)->mnt_id_unique) {
			link = &parent->rb_left;
			mnt_last_node = false;
		} else {
			link = &parent->rb_right;
			mnt_first_node = false;
		}
	}

	if (mnt_last_node)
		ns->mnt_last_node = &mnt->mnt_node;
	if (mnt_first_node)
		ns->mnt_first_node = &mnt->mnt_node;
	rb_link_node(&mnt->mnt_node, parent, link);
	rb_insert_color(&mnt->mnt_node, &ns->mounts);

	mnt_notify_add(mnt);
}

static struct mount *next_mnt(struct mount *p, struct mount *root)
{
	struct list_head *next = p->mnt_mounts.next;
	if (next == &p->mnt_mounts) {
		while (1) {
			if (p == root)
				return NULL;
			next = p->mnt_child.next;
			if (next != &p->mnt_parent->mnt_mounts)
				break;
			p = p->mnt_parent;
		}
	}
	return list_entry(next, struct mount, mnt_child);
}

static struct mount *skip_mnt_tree(struct mount *p)
{
	struct list_head *prev = p->mnt_mounts.prev;
	while (prev != &p->mnt_mounts) {
		p = list_entry(prev, struct mount, mnt_child);
		prev = p->mnt_mounts.prev;
	}
	return p;
}

/*
 * vfsmount lock must be held for write
 */
static void commit_tree(struct mount *mnt)
{
	struct mnt_namespace *n = mnt->mnt_parent->mnt_ns;

	if (!mnt_ns_attached(mnt)) {
		for (struct mount *m = mnt; m; m = next_mnt(m, mnt))
			mnt_add_to_ns(n, m);
		n->nr_mounts += n->pending_mounts;
		n->pending_mounts = 0;
	}

	make_visible(mnt);
	touch_mnt_namespace(n);
}

static void setup_mnt(struct mount *m, struct dentry *root)
{
	struct super_block *s = root->d_sb;

	atomic_inc(&s->s_active);
	m->mnt.mnt_sb = s;
	m->mnt.mnt_root = dget(root);
	m->mnt_mountpoint = m->mnt.mnt_root;
	m->mnt_parent = m;

	guard(mount_locked_reader)();
	mnt_add_instance(m, s);
}

/**
 * vfs_create_mount - Create a mount for a configured superblock
 * @fc: The configuration context with the superblock attached
 *
 * Create a mount to an already configured superblock.  If necessary, the
 * caller should invoke vfs_get_tree() before calling this.
 *
 * Note that this does not attach the mount to anything.
 */
struct vfsmount *vfs_create_mount(struct fs_context *fc)
{
	struct mount *mnt;

	if (!fc->root)
		return ERR_PTR(-EINVAL);

	mnt = alloc_vfsmnt(fc->source);
	if (!mnt)
		return ERR_PTR(-ENOMEM);

	if (fc->sb_flags & SB_KERNMOUNT)
		mnt->mnt.mnt_flags = MNT_INTERNAL;

	setup_mnt(mnt, fc->root);

	return &mnt->mnt;
}
EXPORT_SYMBOL(vfs_create_mount);

struct vfsmount *fc_mount(struct fs_context *fc)
{
	int err = vfs_get_tree(fc);
	if (!err) {
		up_write(&fc->root->d_sb->s_umount);
		return vfs_create_mount(fc);
	}
	return ERR_PTR(err);
}
EXPORT_SYMBOL(fc_mount);

struct vfsmount *fc_mount_longterm(struct fs_context *fc)
{
	struct vfsmount *mnt = fc_mount(fc);
	if (!IS_ERR(mnt))
		real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
	return mnt;
}
EXPORT_SYMBOL(fc_mount_longterm);

struct vfsmount *vfs_kern_mount(struct file_system_type *type,
				int flags, const char *name,
				void *data)
{
	struct fs_context *fc;
	struct vfsmount *mnt;
	int ret = 0;

	if (!type)
		return ERR_PTR(-EINVAL);

	fc = fs_context_for_mount(type, flags);
	if (IS_ERR(fc))
		return ERR_CAST(fc);

	if (name)
		ret = vfs_parse_fs_string(fc, "source", name);
	if (!ret)
		ret = parse_monolithic_mount_data(fc, data);
	if (!ret)
		mnt = fc_mount(fc);
	else
		mnt = ERR_PTR(ret);

	put_fs_context(fc);
	return mnt;
}
EXPORT_SYMBOL_GPL(vfs_kern_mount);

static struct mount *clone_mnt(struct mount *old, struct dentry *root,
					int flag)
{
	struct mount *mnt;
	int err;

	mnt = alloc_vfsmnt(old->mnt_devname);
	if (!mnt)
		return ERR_PTR(-ENOMEM);

	mnt->mnt.mnt_flags = READ_ONCE(old->mnt.mnt_flags) &
			     ~MNT_INTERNAL_FLAGS;

	if (flag & (CL_SLAVE | CL_PRIVATE))
		mnt->mnt_group_id = 0; /* not a peer of original */
	else
		mnt->mnt_group_id = old->mnt_group_id;

	if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) {
		err = mnt_alloc_group_id(mnt);
		if (err)
			goto out_free;
	}

	if (mnt->mnt_group_id)
		set_mnt_shared(mnt);

	mnt->mnt.mnt_idmap = mnt_idmap_get(mnt_idmap(&old->mnt));

	setup_mnt(mnt, root);

	if (flag & CL_PRIVATE)	// we are done with it
		return mnt;

	if (peers(mnt, old))
		list_add(&mnt->mnt_share, &old->mnt_share);

	if ((flag & CL_SLAVE) && old->mnt_group_id) {
		hlist_add_head(&mnt->mnt_slave, &old->mnt_slave_list);
		mnt->mnt_master = old;
	} else if (IS_MNT_SLAVE(old)) {
		hlist_add_behind(&mnt->mnt_slave, &old->mnt_slave);
		mnt->mnt_master = old->mnt_master;
	}
	return mnt;

 out_free:
	mnt_free_id(mnt);
	free_vfsmnt(mnt);
	return ERR_PTR(err);
}

static void cleanup_mnt(struct mount *mnt)
{
	struct hlist_node *p;
	struct mount *m;
	/*
	 * The warning here probably indicates that somebody messed
	 * up a mnt_want/drop_write() pair.  If this happens, the
	 * filesystem was probably unable to make r/w->r/o transitions.
	 * The locking used to deal with mnt_count decrement provides barriers,
	 * so mnt_get_writers() below is safe.
	 */
	WARN_ON(mnt_get_writers(mnt));
	if (unlikely(mnt->mnt_pins.first))
		mnt_pin_kill(mnt);
	hlist_for_each_entry_safe(m, p, &mnt->mnt_stuck_children, mnt_umount) {
		hlist_del(&m->mnt_umount);
		mntput(&m->mnt);
	}
	fsnotify_vfsmount_delete(&mnt->mnt);
	dput(mnt->mnt.mnt_root);
	deactivate_super(mnt->mnt.mnt_sb);
	mnt_free_id(mnt);
	call_rcu(&mnt->mnt_rcu, delayed_free_vfsmnt);
}

static void __cleanup_mnt(struct rcu_head *head)
{
	cleanup_mnt(container_of(head, struct mount, mnt_rcu));
}

static LLIST_HEAD(delayed_mntput_list);
static void delayed_mntput(struct work_struct *unused)
{
	struct llist_node *node = llist_del_all(&delayed_mntput_list);
	struct mount *m, *t;

	llist_for_each_entry_safe(m, t, node, mnt_llist)
		cleanup_mnt(m);
}
static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);

static void noinline mntput_no_expire_slowpath(struct mount *mnt)
{
	LIST_HEAD(list);
	int count;

	VFS_BUG_ON(mnt->mnt_ns);
	lock_mount_hash();
	/*
	 * make sure that if __legitimize_mnt() has not seen us grab
	 * mount_lock, we'll see their refcount increment here.
	 */
	smp_mb();
	mnt_add_count(mnt, -1);
	count = mnt_get_count(mnt);
	if (count != 0) {
		WARN_ON(count < 0);
		rcu_read_unlock();
		unlock_mount_hash();
		return;
	}
	if (unlikely(mnt->mnt.mnt_flags & MNT_DOOMED)) {
		rcu_read_unlock();
		unlock_mount_hash();
		return;
	}
	mnt->mnt.mnt_flags |= MNT_DOOMED;
	rcu_read_unlock();

	mnt_del_instance(mnt);
	if (unlikely(!list_empty(&mnt->mnt_expire)))
		list_del(&mnt->mnt_expire);

	if (unlikely(!list_empty(&mnt->mnt_mounts))) {
		struct mount *p, *tmp;
		list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts,  mnt_child) {
			__umount_mnt(p, &list);
			hlist_add_head(&p->mnt_umount, &mnt->mnt_stuck_children);
		}
	}
	unlock_mount_hash();
	shrink_dentry_list(&list);

	if (likely(!(mnt->mnt.mnt_flags & MNT_INTERNAL))) {
		struct task_struct *task = current;
		if (likely(!(task->flags & PF_KTHREAD))) {
			init_task_work(&mnt->mnt_rcu, __cleanup_mnt);
			if (!task_work_add(task, &mnt->mnt_rcu, TWA_RESUME))
				return;
		}
		if (llist_add(&mnt->mnt_llist, &delayed_mntput_list))
			schedule_delayed_work(&delayed_mntput_work, 1);
		return;
	}
	cleanup_mnt(mnt);
}

static void mntput_no_expire(struct mount *mnt)
{
	rcu_read_lock();
	if (likely(READ_ONCE(mnt->mnt_ns))) {
		/*
		 * Since we don't do lock_mount_hash() here,
		 * ->mnt_ns can change under us.  However, if it's
		 * non-NULL, then there's a reference that won't
		 * be dropped until after an RCU delay done after
		 * turning ->mnt_ns NULL.  So if we observe it
		 * non-NULL under rcu_read_lock(), the reference
		 * we are dropping is not the final one.
		 */
		mnt_add_count(mnt, -1);
		rcu_read_unlock();
		return;
	}
	mntput_no_expire_slowpath(mnt);
}

void mntput(struct vfsmount *mnt)
{
	if (mnt) {
		struct mount *m = real_mount(mnt);
		/* avoid cacheline pingpong */
		if (unlikely(m->mnt_expiry_mark))
			WRITE_ONCE(m->mnt_expiry_mark, 0);
		mntput_no_expire(m);
	}
}
EXPORT_SYMBOL(mntput);

struct vfsmount *mntget(struct vfsmount *mnt)
{
	if (mnt)
		mnt_add_count(real_mount(mnt), 1);
	return mnt;
}
EXPORT_SYMBOL(mntget);

/*
 * Make a mount point inaccessible to new lookups.
 * Because there may still be current users, the caller MUST WAIT
 * for an RCU grace period before destroying the mount point.
 */
void mnt_make_shortterm(struct vfsmount *mnt)
{
	if (mnt)
		real_mount(mnt)->mnt_ns = NULL;
}

/**
 * path_is_mountpoint() - Check if path is a mount in the current namespace.
 * @path: path to check
 *
 *  d_mountpoint() can only be used reliably to establish if a dentry is
 *  not mounted in any namespace and that common case is handled inline.
 *  d_mountpoint() isn't aware of the possibility there may be multiple
 *  mounts using a given dentry in a different namespace. This function
 *  checks if the passed in path is a mountpoint rather than the dentry
 *  alone.
 */
bool path_is_mountpoint(const struct path *path)
{
	unsigned seq;
	bool res;

	if (!d_mountpoint(path->dentry))
		return false;

	rcu_read_lock();
	do {
		seq = read_seqbegin(&mount_lock);
		res = __path_is_mountpoint(path);
	} while (read_seqretry(&mount_lock, seq));
	rcu_read_unlock();

	return res;
}
EXPORT_SYMBOL(path_is_mountpoint);

struct vfsmount *mnt_clone_internal(const struct path *path)
{
	struct mount *p;
	p = clone_mnt(real_mount(path->mnt), path->dentry, CL_PRIVATE);
	if (IS_ERR(p))
		return ERR_CAST(p);
	p->mnt.mnt_flags |= MNT_INTERNAL;
	return &p->mnt;
}

/*
 * Returns the mount which either has the specified mnt_id, or has the next
 * smallest id afer the specified one.
 */
static struct mount *mnt_find_id_at(struct mnt_namespace *ns, u64 mnt_id)
{
	struct rb_node *node = ns->mounts.rb_node;
	struct mount *ret = NULL;

	while (node) {
		struct mount *m = node_to_mount(node);

		if (mnt_id <= m->mnt_id_unique) {
			ret = node_to_mount(node);
			if (mnt_id == m->mnt_id_unique)
				break;
			node = node->rb_left;
		} else {
			node = node->rb_right;
		}
	}
	return ret;
}

/*
 * Returns the mount which either has the specified mnt_id, or has the next
 * greater id before the specified one.
 */
static struct mount *mnt_find_id_at_reverse(struct mnt_namespace *ns, u64 mnt_id)
{
	struct rb_node *node = ns->mounts.rb_node;
	struct mount *ret = NULL;

	while (node) {
		struct mount *m = node_to_mount(node);

		if (mnt_id >= m->mnt_id_unique) {
			ret = node_to_mount(node);
			if (mnt_id == m->mnt_id_unique)
				break;
			node = node->rb_right;
		} else {
			node = node->rb_left;
		}
	}
	return ret;
}

#ifdef CONFIG_PROC_FS

/* iterator; we want it to have access to namespace_sem, thus here... */
static void *m_start(struct seq_file *m, loff_t *pos)
{
	struct proc_mounts *p = m->private;
	struct mount *mnt;

	down_read(&namespace_sem);

	mnt = mnt_find_id_at(p->ns, *pos);
	if (mnt)
		*pos = mnt->mnt_id_unique;
	return mnt;
}

static void *m_next(struct seq_file *m, void *v, loff_t *pos)
{
	struct mount *mnt = v;
	struct rb_node *node = rb_next(&mnt->mnt_node);

	if (node) {
		struct mount *next = node_to_mount(node);
		*pos = next->mnt_id_unique;
		return next;
	}

	/*
	 * No more mounts. Set pos past current mount's ID so that if
	 * iteration restarts, mnt_find_id_at() returns NULL.
	 */
	*pos = mnt->mnt_id_unique + 1;
	return NULL;
}

static void m_stop(struct seq_file *m, void *v)
{
	up_read(&namespace_sem);
}

static int m_show(struct seq_file *m, void *v)
{
	struct proc_mounts *p = m->private;
	struct mount *r = v;
	return p->show(m, &r->mnt);
}

const struct seq_operations mounts_op = {
	.start	= m_start,
	.next	= m_next,
	.stop	= m_stop,
	.show	= m_show,
};

#endif  /* CONFIG_PROC_FS */

/**
 * may_umount_tree - check if a mount tree is busy
 * @m: root of mount tree
 *
 * This is called to check if a tree of mounts has any
 * open files, pwds, chroots or sub mounts that are
 * busy.
 */
int may_umount_tree(struct vfsmount *m)
{
	struct mount *mnt = real_mount(m);
	bool busy = false;

	/* write lock needed for mnt_get_count */
	lock_mount_hash();
	for (struct mount *p = mnt; p; p = next_mnt(p, mnt)) {
		if (mnt_get_count(p) > (p == mnt ? 2 : 1)) {
			busy = true;
			break;
		}
	}
	unlock_mount_hash();

	return !busy;
}

EXPORT_SYMBOL(may_umount_tree);

/**
 * may_umount - check if a mount point is busy
 * @mnt: root of mount
 *
 * This is called to check if a mount point has any
 * open files, pwds, chroots or sub mounts. If the
 * mount has sub mounts this will return busy
 * regardless of whether the sub mounts are busy.
 *
 * Doesn't take quota and stuff into account. IOW, in some cases it will
 * give false negatives. The main reason why it's here is that we need
 * a non-destructive way to look for easily umountable filesystems.
 */
int may_umount(struct vfsmount *mnt)
{
	int ret = 1;
	down_read(&namespace_sem);
	lock_mount_hash();
	if (propagate_mount_busy(real_mount(mnt), 2))
		ret = 0;
	unlock_mount_hash();
	up_read(&namespace_sem);
	return ret;
}

EXPORT_SYMBOL(may_umount);

#ifdef CONFIG_FSNOTIFY
static void mnt_notify(struct mount *p)
{
	if (!p->prev_ns && p->mnt_ns) {
		fsnotify_mnt_attach(p->mnt_ns, &p->mnt);
	} else if (p->prev_ns && !p->mnt_ns) {
		fsnotify_mnt_detach(p->prev_ns, &p->mnt);
	} else if (p->prev_ns == p->mnt_ns) {
		fsnotify_mnt_move(p->mnt_ns, &p->mnt);
	} else {
		fsnotify_mnt_detach(p->prev_ns, &p->mnt);
		fsnotify_mnt_attach(p->mnt_ns, &p->mnt);
	}
	p->prev_ns = p->mnt_ns;
}

static void notify_mnt_list(void)
{
	struct mount *m, *tmp;
	/*
	 * Notify about mounts that were added/reparented/detached/remain
	 * connected after unmount.
	 */
	list_for_each_entry_safe(m, tmp, &notify_list, to_notify) {
		mnt_notify(m);
		list_del_init(&m->to_notify);
	}
}

static bool need_notify_mnt_list(void)
{
	return !list_empty(&notify_list);
}
#else
static void notify_mnt_list(void)
{
}

static bool need_notify_mnt_list(void)
{
	return false;
}
#endif

static void free_mnt_ns(struct mnt_namespace *);
static void namespace_unlock(void)
{
	struct hlist_head head;
	struct hlist_node *p;
	struct mount *m;
	struct mnt_namespace *ns = emptied_ns;
	LIST_HEAD(list);

	hlist_move_list(&unmounted, &head);
	list_splice_init(&ex_mountpoints, &list);
	emptied_ns = NULL;

	if (need_notify_mnt_list()) {
		/*
		 * No point blocking out concurrent readers while notifications
		 * are sent. This will also allow statmount()/listmount() to run
		 * concurrently.
		 */
		downgrade_write(&namespace_sem);
		notify_mnt_list();
		up_read(&namespace_sem);
	} else {
		up_write(&namespace_sem);
	}
	if (unlikely(ns)) {
		/* Make sure we notice when we leak mounts. */
		VFS_WARN_ON_ONCE(!mnt_ns_empty(ns));
		free_mnt_ns(ns);
	}

	shrink_dentry_list(&list);

	if (likely(hlist_empty(&head)))
		return;

	synchronize_rcu_expedited();

	hlist_for_each_entry_safe(m, p, &head, mnt_umount) {
		hlist_del(&m->mnt_umount);
		mntput(&m->mnt);
	}
}

static inline void namespace_lock(void)
{
	down_write(&namespace_sem);
}

enum umount_tree_flags {
	UMOUNT_SYNC = 1,
	UMOUNT_PROPAGATE = 2,
	UMOUNT_CONNECTED = 4,
};

static bool disconnect_mount(struct mount *mnt, enum umount_tree_flags how)
{
	/* Leaving mounts connected is only valid for lazy umounts */
	if (how & UMOUNT_SYNC)
		return true;

	/* A mount without a parent has nothing to be connected to */
	if (!mnt_has_parent(mnt))
		return true;

	/* Because the reference counting rules change when mounts are
	 * unmounted and connected, umounted mounts may not be
	 * connected to mounted mounts.
	 */
	if (!(mnt->mnt_parent->mnt.mnt_flags & MNT_UMOUNT))
		return true;

	/* Has it been requested that the mount remain connected? */
	if (how & UMOUNT_CONNECTED)
		return false;

	/* Is the mount locked such that it needs to remain connected? */
	if (IS_MNT_LOCKED(mnt))
		return false;

	/* By default disconnect the mount */
	return true;
}

/*
 * mount_lock must be held
 * namespace_sem must be held for write
 */
static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
{
	LIST_HEAD(tmp_list);
	struct mount *p;

	if (how & UMOUNT_PROPAGATE)
		propagate_mount_unlock(mnt);

	/* Gather the mounts to umount */
	for (p = mnt; p; p = next_mnt(p, mnt)) {
		p->mnt.mnt_flags |= MNT_UMOUNT;
		if (mnt_ns_attached(p))
			move_from_ns(p);
		list_add_tail(&p->mnt_list, &tmp_list);
	}

	/* Hide the mounts from mnt_mounts */
	list_for_each_entry(p, &tmp_list, mnt_list) {
		list_del_init(&p->mnt_child);
	}

	/* Add propagated mounts to the tmp_list */
	if (how & UMOUNT_PROPAGATE)
		propagate_umount(&tmp_list);

	bulk_make_private(&tmp_list);

	while (!list_empty(&tmp_list)) {
		struct mnt_namespace *ns;
		bool disconnect;
		p = list_first_entry(&tmp_list, struct mount, mnt_list);
		list_del_init(&p->mnt_expire);
		list_del_init(&p->mnt_list);
		ns = p->mnt_ns;
		if (ns) {
			ns->nr_mounts--;
			__touch_mnt_namespace(ns);
		}
		p->mnt_ns = NULL;
		if (how & UMOUNT_SYNC)
			p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;

		disconnect = disconnect_mount(p, how);
		if (mnt_has_parent(p)) {
			if (!disconnect) {
				/* Don't forget about p */
				list_add_tail(&p->mnt_child, &p->mnt_parent->mnt_mounts);
			} else {
				umount_mnt(p);
			}
		}
		if (disconnect)
			hlist_add_head(&p->mnt_umount, &unmounted);

		/*
		 * At this point p->mnt_ns is NULL, notification will be queued
		 * only if
		 *
		 *  - p->prev_ns is non-NULL *and*
		 *  - p->prev_ns->n_fsnotify_marks is non-NULL
		 *
		 * This will preclude queuing the mount if this is a cleanup
		 * after a failed copy_tree() or destruction of an anonymous
		 * namespace, etc.
		 */
		mnt_notify_add(p);
	}
}

static void shrink_submounts(struct mount *mnt);

static int do_umount_root(struct super_block *sb)
{
	int ret = 0;

	down_write(&sb->s_umount);
	if (!sb_rdonly(sb)) {
		struct fs_context *fc;

		fc = fs_context_for_reconfigure(sb->s_root, SB_RDONLY,
						SB_RDONLY);
		if (IS_ERR(fc)) {
			ret = PTR_ERR(fc);
		} else {
			ret = parse_monolithic_mount_data(fc, NULL);
			if (!ret)
				ret = reconfigure_super(fc);
			put_fs_context(fc);
		}
	}
	up_write(&sb->s_umount);
	return ret;
}

static int do_umount(struct mount *mnt, int flags)
{
	struct super_block *sb = mnt->mnt.mnt_sb;
	int retval;

	retval = security_sb_umount(&mnt->mnt, flags);
	if (retval)
		return retval;

	/*
	 * Allow userspace to request a mountpoint be expired rather than
	 * unmounting unconditionally. Unmount only happens if:
	 *  (1) the mark is already set (the mark is cleared by mntput())
	 *  (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
	 */
	if (flags & MNT_EXPIRE) {
		if (&mnt->mnt == current->fs->root.mnt ||
		    flags & (MNT_FORCE | MNT_DETACH))
			return -EINVAL;

		/*
		 * probably don't strictly need the lock here if we examined
		 * all race cases, but it's a slowpath.
		 */
		lock_mount_hash();
		if (!list_empty(&mnt->mnt_mounts) || mnt_get_count(mnt) != 2) {
			unlock_mount_hash();
			return -EBUSY;
		}
		unlock_mount_hash();

		if (!xchg(&mnt->mnt_expiry_mark, 1))
			return -EAGAIN;
	}

	/*
	 * If we may have to abort operations to get out of this
	 * mount, and they will themselves hold resources we must
	 * allow the fs to do things. In the Unix tradition of
	 * 'Gee thats tricky lets do it in userspace' the umount_begin
	 * might fail to complete on the first run through as other tasks
	 * must return, and the like. Thats for the mount program to worry
	 * about for the moment.
	 */

	if (flags & MNT_FORCE && sb->s_op->umount_begin) {
		sb->s_op->umount_begin(sb);
	}

	/*
	 * No sense to grab the lock for this test, but test itself looks
	 * somewhat bogus. Suggestions for better replacement?
	 * Ho-hum... In principle, we might treat that as umount + switch
	 * to rootfs. GC would eventually take care of the old vfsmount.
	 * Actually it makes sense, especially if rootfs would contain a
	 * /reboot - static binary that would close all descriptors and
	 * call reboot(9). Then init(8) could umount root and exec /reboot.
	 */
	if (&mnt->mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
		/*
		 * Special case for "unmounting" root ...
		 * we just try to remount it readonly.
		 */
		if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
			return -EPERM;
		return do_umount_root(sb);
	}

	namespace_lock();
	lock_mount_hash();

	/* Repeat the earlier racy checks, now that we are holding the locks */
	retval = -EINVAL;
	if (!check_mnt(mnt))
		goto out;

	if (mnt->mnt.mnt_flags & MNT_LOCKED)
		goto out;

	if (!mnt_has_parent(mnt)) /* not the absolute root */
		goto out;

	event++;
	if (flags & MNT_DETACH) {
		umount_tree(mnt, UMOUNT_PROPAGATE);
		retval = 0;
	} else {
		smp_mb(); // paired with __legitimize_mnt()
		shrink_submounts(mnt);
		retval = -EBUSY;
		if (!propagate_mount_busy(mnt, 2)) {
			umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
			retval = 0;
		}
	}
out:
	unlock_mount_hash();
	namespace_unlock();
	return retval;
}

/*
 * __detach_mounts - lazily unmount all mounts on the specified dentry
 *
 * During unlink, rmdir, and d_drop it is possible to loose the path
 * to an existing mountpoint, and wind up leaking the mount.
 * detach_mounts allows lazily unmounting those mounts instead of
 * leaking them.
 *
 * The caller may hold dentry->d_inode->i_rwsem.
 */
void __detach_mounts(struct dentry *dentry)
{
	struct pinned_mountpoint mp = {};
	struct mount *mnt;

	guard(namespace_excl)();
	guard(mount_writer)();

	if (!lookup_mountpoint(dentry, &mp))
		return;

	event++;
	while (mp.node.next) {
		mnt = hlist_entry(mp.node.next, struct mount, mnt_mp_list);
		if (mnt->mnt.mnt_flags & MNT_UMOUNT) {
			umount_mnt(mnt);
			hlist_add_head(&mnt->mnt_umount, &unmounted);
		}
		else umount_tree(mnt, UMOUNT_CONNECTED);
	}
	unpin_mountpoint(&mp);
}

/*
 * Is the caller allowed to modify his namespace?
 */
bool may_mount(void)
{
	return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
}

static void warn_mandlock(void)
{
	pr_warn_once("=======================================================\n"
		     "WARNING: The mand mount option has been deprecated and\n"
		     "         and is ignored by this kernel. Remove the mand\n"
		     "         option from the mount to silence this warning.\n"
		     "=======================================================\n");
}

static int can_umount(const struct path *path, int flags)
{
	struct mount *mnt = real_mount(path->mnt);
	struct super_block *sb = path->dentry->d_sb;

	if (!may_mount())
		return -EPERM;
	if (!path_mounted(path))
		return -EINVAL;
	if (!check_mnt(mnt))
		return -EINVAL;
	if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
		return -EINVAL;
	if (flags & MNT_FORCE && !ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
		return -EPERM;
	return 0;
}

// caller is responsible for flags being sane
int path_umount(const struct path *path, int flags)
{
	struct mount *mnt = real_mount(path->mnt);
	int ret;

	ret = can_umount(path, flags);
	if (!ret)
		ret = do_umount(mnt, flags);

	/* we mustn't call path_put() as that would clear mnt_expiry_mark */
	dput(path->dentry);
	mntput_no_expire(mnt);
	return ret;
}

static int ksys_umount(char __user *name, int flags)
{
	int lookup_flags = LOOKUP_MOUNTPOINT;
	struct path path;
	int ret;

	// basic validity checks done first
	if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
		return -EINVAL;

	if (!(flags & UMOUNT_NOFOLLOW))
		lookup_flags |= LOOKUP_FOLLOW;
	ret = user_path_at(AT_FDCWD, name, lookup_flags, &path);
	if (ret)
		return ret;
	return path_umount(&path, flags);
}

SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
{
	return ksys_umount(name, flags);
}

#ifdef __ARCH_WANT_SYS_OLDUMOUNT

/*
 *	The 2.0 compatible umount. No flags.
 */
SYSCALL_DEFINE1(oldumount, char __user *, name)
{
	return ksys_umount(name, 0);
}

#endif

static bool is_mnt_ns_file(struct dentry *dentry)
{
	struct ns_common *ns;

	/* Is this a proxy for a mount namespace? */
	if (dentry->d_op != &ns_dentry_operations)
		return false;

	ns = d_inode(dentry)->i_private;

	return ns->ops == &mntns_operations;
}

struct ns_common *from_mnt_ns(struct mnt_namespace *mnt)
{
	return &mnt->ns;
}

struct mnt_namespace *get_sequential_mnt_ns(struct mnt_namespace *mntns, bool previous)
{
	struct ns_common *ns;

	guard(rcu)();

	for (;;) {
		ns = ns_tree_adjoined_rcu(mntns, previous);
		if (IS_ERR(ns))
			return ERR_CAST(ns);

		mntns = to_mnt_ns(ns);

		/*
		 * The last passive reference count is put with RCU
		 * delay so accessing the mount namespace is not just
		 * safe but all relevant members are still valid.
		 */
		if (!ns_capable_noaudit(mntns->user_ns, CAP_SYS_ADMIN))
			continue;

		/*
		 * We need an active reference count as we're persisting
		 * the mount namespace and it might already be on its
		 * deathbed.
		 */
		if (!ns_ref_get(mntns))
			continue;

		return mntns;
	}
}

struct mnt_namespace *mnt_ns_from_dentry(struct dentry *dentry)
{
	if (!is_mnt_ns_file(dentry))
		return NULL;

	return to_mnt_ns(get_proc_ns(dentry->d_inode));
}

static bool mnt_ns_loop(struct dentry *dentry)
{
	/* Could bind mounting the mount namespace inode cause a
	 * mount namespace loop?
	 */
	struct mnt_namespace *mnt_ns = mnt_ns_from_dentry(dentry);

	if (!mnt_ns)
		return false;

	return current->nsproxy->mnt_ns->ns.ns_id >= mnt_ns->ns.ns_id;
}

struct mount *copy_tree(struct mount *src_root, struct dentry *dentry,
					int flag)
{
	struct mount *res, *src_parent, *src_root_child, *src_mnt,
		*dst_parent, *dst_mnt;

	if (!(flag & CL_COPY_UNBINDABLE) && IS_MNT_UNBINDABLE(src_root))
		return ERR_PTR(-EINVAL);

	if (!(flag & CL_COPY_MNT_NS_FILE) && is_mnt_ns_file(dentry))
		return ERR_PTR(-EINVAL);

	res = dst_mnt = clone_mnt(src_root, dentry, flag);
	if (IS_ERR(dst_mnt))
		return dst_mnt;

	src_parent = src_root;

	list_for_each_entry(src_root_child, &src_root->mnt_mounts, mnt_child) {
		if (!is_subdir(src_root_child->mnt_mountpoint, dentry))
			continue;

		for (src_mnt = src_root_child; src_mnt;
		    src_mnt = next_mnt(src_mnt, src_root_child)) {
			if (!(flag & CL_COPY_UNBINDABLE) &&
			    IS_MNT_UNBINDABLE(src_mnt)) {
				if (src_mnt->mnt.mnt_flags & MNT_LOCKED) {
					/* Both unbindable and locked. */
					dst_mnt = ERR_PTR(-EPERM);
					goto out;
				} else {
					src_mnt = skip_mnt_tree(src_mnt);
					continue;
				}
			}
			if (!(flag & CL_COPY_MNT_NS_FILE) &&
			    is_mnt_ns_file(src_mnt->mnt.mnt_root)) {
				src_mnt = skip_mnt_tree(src_mnt);
				continue;
			}
			while (src_parent != src_mnt->mnt_parent) {
				src_parent = src_parent->mnt_parent;
				dst_mnt = dst_mnt->mnt_parent;
			}

			src_parent = src_mnt;
			dst_parent = dst_mnt;
			dst_mnt = clone_mnt(src_mnt, src_mnt->mnt.mnt_root, flag);
			if (IS_ERR(dst_mnt))
				goto out;
			lock_mount_hash();
			if (src_mnt->mnt.mnt_flags & MNT_LOCKED)
				dst_mnt->mnt.mnt_flags |= MNT_LOCKED;
			if (unlikely(flag & CL_EXPIRE)) {
				/* stick the duplicate mount on the same expiry
				 * list as the original if that was on one */
				if (!list_empty(&src_mnt->mnt_expire))
					list_add(&dst_mnt->mnt_expire,
						 &src_mnt->mnt_expire);
			}
			attach_mnt(dst_mnt, dst_parent, src_parent->mnt_mp);
			unlock_mount_hash();
		}
	}
	return res;

out:
	if (res) {
		lock_mount_hash();
		umount_tree(res, UMOUNT_SYNC);
		unlock_mount_hash();
	}
	return dst_mnt;
}

static inline bool extend_array(struct path **res, struct path **to_free,
				unsigned n, unsigned *count, unsigned new_count)
{
	struct path *p;

	if (likely(n < *count))
		return true;
	p = kmalloc_objs(struct path, new_count);
	if (p && *count)
		memcpy(p, *res, *count * sizeof(struct path));
	*count = new_count;
	kfree(*to_free);
	*to_free = *res = p;
	return p;
}

const struct path *collect_paths(const struct path *path,
			      struct path *prealloc, unsigned count)
{
	struct mount *root = real_mount(path->mnt);
	struct mount *child;
	struct path *res = prealloc, *to_free = NULL;
	unsigned n = 0;

	guard(namespace_shared)();

	if (!check_mnt(root))
		return ERR_PTR(-EINVAL);
	if (!extend_array(&res, &to_free, 0, &count, 32))
		return ERR_PTR(-ENOMEM);
	res[n++] = *path;
	list_for_each_entry(child, &root->mnt_mounts, mnt_child) {
		if (!is_subdir(child->mnt_mountpoint, path->dentry))
			continue;
		for (struct mount *m = child; m; m = next_mnt(m, child)) {
			if (!extend_array(&res, &to_free, n, &count, 2 * count))
				return ERR_PTR(-ENOMEM);
			res[n].mnt = &m->mnt;
			res[n].dentry = m->mnt.mnt_root;
			n++;
		}
	}
	if (!extend_array(&res, &to_free, n, &count, count + 1))
		return ERR_PTR(-ENOMEM);
	memset(res + n, 0, (count - n) * sizeof(struct path));
	for (struct path *p = res; p->mnt; p++)
		path_get(p);
	return res;
}

void drop_collected_paths(const struct path *paths, const struct path *prealloc)
{
	for (const struct path *p = paths; p->mnt; p++)
		path_put(p);
	if (paths != prealloc)
		kfree(paths);
}

static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *, bool);

void dissolve_on_fput(struct vfsmount *mnt)
{
	struct mount *m = real_mount(mnt);

	/*
	 * m used to be the root of anon namespace; if it still is one,
	 * we need to dissolve the mount tree and free that namespace.
	 * Let's try to avoid taking namespace_sem if we can determine
	 * that there's nothing to do without it - rcu_read_lock() is
	 * enough to make anon_ns_root() memory-safe and once m has
	 * left its namespace, it's no longer our concern, since it will
	 * never become a root of anon ns again.
	 */

	scoped_guard(rcu) {
		if (!anon_ns_root(m))
			return;
	}

	scoped_guard(namespace_excl) {
		if (!anon_ns_root(m))
			return;

		emptied_ns = m->mnt_ns;
		lock_mount_hash();
		umount_tree(m, UMOUNT_CONNECTED);
		unlock_mount_hash();
	}
}

/* locks: namespace_shared && pinned(mnt) || mount_locked_reader */
static bool __has_locked_children(struct mount *mnt, struct dentry *dentry)
{
	struct mount *child;

	list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
		if (!is_subdir(child->mnt_mountpoint, dentry))
			continue;

		if (child->mnt.mnt_flags & MNT_LOCKED)
			return true;
	}
	return false;
}

bool has_locked_children(struct mount *mnt, struct dentry *dentry)
{
	guard(mount_locked_reader)();
	return __has_locked_children(mnt, dentry);
}

/*
 * Check that there aren't references to earlier/same mount namespaces in the
 * specified subtree.  Such references can act as pins for mount namespaces
 * that aren't checked by the mount-cycle checking code, thereby allowing
 * cycles to be made.
 *
 * locks: mount_locked_reader || namespace_shared && pinned(subtree)
 */
static bool check_for_nsfs_mounts(struct mount *subtree)
{
	for (struct mount *p = subtree; p; p = next_mnt(p, subtree))
		if (mnt_ns_loop(p->mnt.mnt_root))
			return false;
	return true;
}

/**
 * clone_private_mount - create a private clone of a path
 * @path: path to clone
 *
 * This creates a new vfsmount, which will be the clone of @path.  The new mount
 * will not be attached anywhere in the namespace and will be private (i.e.
 * changes to the originating mount won't be propagated into this).
 *
 * This assumes caller has called or done the equivalent of may_mount().
 *
 * Release with mntput().
 */
struct vfsmount *clone_private_mount(const struct path *path)
{
	struct mount *old_mnt = real_mount(path->mnt);
	struct mount *new_mnt;

	guard(namespace_shared)();

	if (IS_MNT_UNBINDABLE(old_mnt))
		return ERR_PTR(-EINVAL);

	/*
	 * Make sure the source mount is acceptable.
	 * Anything mounted in our mount namespace is allowed.
	 * Otherwise, it must be the root of an anonymous mount
	 * namespace, and we need to make sure no namespace
	 * loops get created.
	 */
	if (!check_mnt(old_mnt)) {
		if (!anon_ns_root(old_mnt))
			return ERR_PTR(-EINVAL);

		if (!check_for_nsfs_mounts(old_mnt))
			return ERR_PTR(-EINVAL);
	}

	if (!ns_capable(old_mnt->mnt_ns->user_ns, CAP_SYS_ADMIN))
		return ERR_PTR(-EPERM);

	if (__has_locked_children(old_mnt, path->dentry))
		return ERR_PTR(-EINVAL);

	new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
	if (IS_ERR(new_mnt))
		return ERR_PTR(-EINVAL);

	/* Longterm mount to be removed by kern_unmount*() */
	new_mnt->mnt_ns = MNT_NS_INTERNAL;
	return &new_mnt->mnt;
}
EXPORT_SYMBOL_GPL(clone_private_mount);

static void lock_mnt_tree(struct mount *mnt)
{
	struct mount *p;

	for (p = mnt; p; p = next_mnt(p, mnt)) {
		int flags = p->mnt.mnt_flags;
		/* Don't allow unprivileged users to change mount flags */
		flags |= MNT_LOCK_ATIME;

		if (flags & MNT_READONLY)
			flags |= MNT_LOCK_READONLY;

		if (flags & MNT_NODEV)
			flags |= MNT_LOCK_NODEV;

		if (flags & MNT_NOSUID)
			flags |= MNT_LOCK_NOSUID;

		if (flags & MNT_NOEXEC)
			flags |= MNT_LOCK_NOEXEC;
		/* Don't allow unprivileged users to reveal what is under a mount */
		if (list_empty(&p->mnt_expire) && p != mnt)
			flags |= MNT_LOCKED;
		p->mnt.mnt_flags = flags;
	}
}

static void cleanup_group_ids(struct mount *mnt, struct mount *end)
{
	struct mount *p;

	for (p = mnt; p != end; p = next_mnt(p, mnt)) {
		if (p->mnt_group_id && !IS_MNT_SHARED(p))
			mnt_release_group_id(p);
	}
}

static int invent_group_ids(struct mount *mnt, bool recurse)
{
	struct mount *p;

	for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
		if (!p->mnt_group_id) {
			int err = mnt_alloc_group_id(p);
			if (err) {
				cleanup_group_ids(mnt, p);
				return err;
			}
		}
	}

	return 0;
}

int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
{
	unsigned int max = READ_ONCE(sysctl_mount_max);
	unsigned int mounts = 0;
	struct mount *p;

	if (ns->nr_mounts >= max)
		return -ENOSPC;
	max -= ns->nr_mounts;
	if (ns->pending_mounts >= max)
		return -ENOSPC;
	max -= ns->pending_mounts;

	for (p = mnt; p; p = next_mnt(p, mnt))
		mounts++;

	if (mounts > max)
		return -ENOSPC;

	ns->pending_mounts += mounts;
	return 0;
}

enum mnt_tree_flags_t {
	MNT_TREE_BENEATH = BIT(0),
	MNT_TREE_PROPAGATION = BIT(1),
};

/**
 * attach_recursive_mnt - attach a source mount tree
 * @source_mnt: mount tree to be attached
 * @dest:	the context for mounting at the place where the tree should go
 *
 *  NOTE: in the table below explains the semantics when a source mount
 *  of a given type is attached to a destination mount of a given type.
 * ---------------------------------------------------------------------------
 * |         BIND MOUNT OPERATION                                            |
 * |**************************************************************************
 * | source-->| shared        |       private  |       slave    | unbindable |
 * | dest     |               |                |                |            |
 * |   |      |               |                |                |            |
 * |   v      |               |                |                |            |
 * |**************************************************************************
 * |  shared  | shared (++)   |     shared (+) |     shared(+++)|  invalid   |
 * |          |               |                |                |            |
 * |non-shared| shared (+)    |      private   |      slave (*) |  invalid   |
 * ***************************************************************************
 * A bind operation clones the source mount and mounts the clone on the
 * destination mount.
 *
 * (++)  the cloned mount is propagated to all the mounts in the propagation
 * 	 tree of the destination mount and the cloned mount is added to
 * 	 the peer group of the source mount.
 * (+)   the cloned mount is created under the destination mount and is marked
 *       as shared. The cloned mount is added to the peer group of the source
 *       mount.
 * (+++) the mount is propagated to all the mounts in the propagation tree
 *       of the destination mount and the cloned mount is made slave
 *       of the same master as that of the source mount. The cloned mount
 *       is marked as 'shared and slave'.
 * (*)   the cloned mount is made a slave of the same master as that of the
 * 	 source mount.
 *
 * ---------------------------------------------------------------------------
 * |         		MOVE MOUNT OPERATION                                 |
 * |**************************************************************************
 * | source-->| shared        |       private  |       slave    | unbindable |
 * | dest     |               |                |                |            |
 * |   |      |               |                |                |            |
 * |   v      |               |                |                |            |
 * |**************************************************************************
 * |  shared  | shared (+)    |     shared (+) |    shared(+++) |  invalid   |
 * |          |               |                |                |            |
 * |non-shared| shared (+*)   |      private   |    slave (*)   | unbindable |
 * ***************************************************************************
 *
 * (+)  the mount is moved to the destination. And is then propagated to
 * 	all the mounts in the propagation tree of the destination mount.
 * (+*)  the mount is moved to the destination.
 * (+++)  the mount is moved to the destination and is then propagated to
 * 	all the mounts belonging to the destination mount's propagation tree.
 * 	the mount is marked as 'shared and slave'.
 * (*)	the mount continues to be a slave at the new location.
 *
 * if the source mount is a tree, the operations explained above is
 * applied to each mount in the tree.
 * Must be called without spinlocks held, since this function can sleep
 * in allocations.
 *
 * Context: The function expects namespace_lock() to be held.
 * Return: If @source_mnt was successfully attached 0 is returned.
 *         Otherwise a negative error code is returned.
 */
static int attach_recursive_mnt(struct mount *source_mnt,
				const struct pinned_mountpoint *dest)
{
	struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
	struct mount *dest_mnt = dest->parent;
	struct mountpoint *dest_mp = dest->mp;
	HLIST_HEAD(tree_list);
	struct mnt_namespace *ns = dest_mnt->mnt_ns;
	struct pinned_mountpoint root = {};
	struct mountpoint *shorter = NULL;
	struct mount *child, *p;
	struct mount *top;
	struct hlist_node *n;
	int err = 0;
	bool moving = mnt_has_parent(source_mnt);

	/*
	 * Preallocate a mountpoint in case the new mounts need to be
	 * mounted beneath mounts on the same mountpoint.
	 */
	for (top = source_mnt; unlikely(top->overmount); top = top->overmount) {
		if (!shorter && is_mnt_ns_file(top->mnt.mnt_root))
			shorter = top->mnt_mp;
	}
	err = get_mountpoint(top->mnt.mnt_root, &root);
	if (err)
		return err;

	/* Is there space to add these mounts to the mount namespace? */
	if (!moving) {
		err = count_mounts(ns, source_mnt);
		if (err)
			goto out;
	}

	if (IS_MNT_SHARED(dest_mnt)) {
		err = invent_group_ids(source_mnt, true);
		if (err)
			goto out;
		err = propagate_mnt(dest_mnt, dest_mp, source_mnt, &tree_list);
	}
	lock_mount_hash();
	if (err)
		goto out_cleanup_ids;

	if (IS_MNT_SHARED(dest_mnt)) {
		for (p = source_mnt; p; p = next_mnt(p, source_mnt))
			set_mnt_shared(p);
	}

	if (moving) {
		umount_mnt(source_mnt);
		mnt_notify_add(source_mnt);
		/* if the mount is moved, it should no longer be expired
		 * automatically */
		list_del_init(&source_mnt->mnt_expire);
	} else {
		if (source_mnt->mnt_ns) {
			/* move from anon - the caller will destroy */
			emptied_ns = source_mnt->mnt_ns;
			for (p = source_mnt; p; p = next_mnt(p, source_mnt))
				move_from_ns(p);
		}
	}

	mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
	/*
	 * Now the original copy is in the same state as the secondaries -
	 * its root attached to mountpoint, but not hashed and all mounts
	 * in it are either in our namespace or in no namespace at all.
	 * Add the original to the list of copies and deal with the
	 * rest of work for all of them uniformly.
	 */
	hlist_add_head(&source_mnt->mnt_hash, &tree_list);

	hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) {
		struct mount *q;
		hlist_del_init(&child->mnt_hash);
		/* Notice when we are propagating across user namespaces */
		if (child->mnt_parent->mnt_ns->user_ns != user_ns)
			lock_mnt_tree(child);
		q = __lookup_mnt(&child->mnt_parent->mnt,
				 child->mnt_mountpoint);
		commit_tree(child);
		if (q) {
			struct mount *r = topmost_overmount(child);
			struct mountpoint *mp = root.mp;

			if (unlikely(shorter) && child != source_mnt)
				mp = shorter;
			mnt_change_mountpoint(r, mp, q);
		}
	}
	unpin_mountpoint(&root);
	unlock_mount_hash();

	return 0;

 out_cleanup_ids:
	while (!hlist_empty(&tree_list)) {
		child = hlist_entry(tree_list.first, struct mount, mnt_hash);
		child->mnt_parent->mnt_ns->pending_mounts = 0;
		umount_tree(child, UMOUNT_SYNC);
	}
	unlock_mount_hash();
	cleanup_group_ids(source_mnt, NULL);
 out:
	ns->pending_mounts = 0;

	read_seqlock_excl(&mount_lock);
	unpin_mountpoint(&root);
	read_sequnlock_excl(&mount_lock);

	return err;
}

static inline struct mount *where_to_mount(const struct path *path,
					   struct dentry **dentry,
					   bool beneath)
{
	struct mount *m;

	if (unlikely(beneath)) {
		m = topmost_overmount(real_mount(path->mnt));
		*dentry = m->mnt_mountpoint;
		return m->mnt_parent;
	}
	m = __lookup_mnt(path->mnt, path->dentry);
	if (unlikely(m)) {
		m = topmost_overmount(m);
		*dentry = m->mnt.mnt_root;
		return m;
	}
	*dentry = path->dentry;
	return real_mount(path->mnt);
}

/**
 * do_lock_mount - acquire environment for mounting
 * @path:	target path
 * @res:	context to set up
 * @beneath:	whether the intention is to mount beneath @path
 *
 * To mount something at given location, we need
 *	namespace_sem locked exclusive
 *	inode of dentry we are mounting on locked exclusive
 *	struct mountpoint for that dentry
 *	struct mount we are mounting on
 *
 * Results are stored in caller-supplied context (pinned_mountpoint);
 * on success we have res->parent and res->mp pointing to parent and
 * mountpoint respectively and res->node inserted into the ->m_list
 * of the mountpoint, making sure the mountpoint won't disappear.
 * On failure we have res->parent set to ERR_PTR(-E...), res->mp
 * left NULL, res->node - empty.
 * In case of success do_lock_mount returns with locks acquired (in
 * proper order - inode lock nests outside of namespace_sem).
 *
 * Request to mount on overmounted location is treated as "mount on
 * top of whatever's overmounting it"; request to mount beneath
 * a location - "mount immediately beneath the topmost mount at that
 * place".
 *
 * In all cases the location must not have been unmounted and the
 * chosen mountpoint must be allowed to be mounted on.  For "beneath"
 * case we also require the location to be at the root of a mount
 * that has a parent (i.e. is not a root of some namespace).
 */
static void do_lock_mount(const struct path *path,
			  struct pinned_mountpoint *res,
			  bool beneath)
{
	int err;

	if (unlikely(beneath) && !path_mounted(path)) {
		res->parent = ERR_PTR(-EINVAL);
		return;
	}

	do {
		struct dentry *dentry, *d;
		struct mount *m, *n;

		scoped_guard(mount_locked_reader) {
			m = where_to_mount(path, &dentry, beneath);
			if (&m->mnt != path->mnt) {
				mntget(&m->mnt);
				dget(dentry);
			}
		}

		inode_lock(dentry->d_inode);
		namespace_lock();

		// check if the chain of mounts (if any) has changed.
		scoped_guard(mount_locked_reader)
			n = where_to_mount(path, &d, beneath);

		if (unlikely(n != m || dentry != d))
			err = -EAGAIN;		// something moved, retry
		else if (unlikely(cant_mount(dentry) || !is_mounted(path->mnt)))
			err = -ENOENT;		// not to be mounted on
		else if (beneath && &m->mnt == path->mnt && !m->overmount)
			err = -EINVAL;
		else
			err = get_mountpoint(dentry, res);

		if (unlikely(err)) {
			res->parent = ERR_PTR(err);
			namespace_unlock();
			inode_unlock(dentry->d_inode);
		} else {
			res->parent = m;
		}
		/*
		 * Drop the temporary references.  This is subtle - on success
		 * we are doing that under namespace_sem, which would normally
		 * be forbidden.  However, in that case we are guaranteed that
		 * refcounts won't reach zero, since we know that path->mnt
		 * is mounted and thus all mounts reachable from it are pinned
		 * and stable, along with their mountpoints and roots.
		 */
		if (&m->mnt != path->mnt) {
			dput(dentry);
			mntput(&m->mnt);
		}
	} while (err == -EAGAIN);
}

static void __unlock_mount(struct pinned_mountpoint *m)
{
	inode_unlock(m->mp->m_dentry->d_inode);
	read_seqlock_excl(&mount_lock);
	unpin_mountpoint(m);
	read_sequnlock_excl(&mount_lock);
	namespace_unlock();
}

static inline void unlock_mount(struct pinned_mountpoint *m)
{
	if (!IS_ERR(m->parent))
		__unlock_mount(m);
}

static void lock_mount_exact(const struct path *path,
			     struct pinned_mountpoint *mp, bool copy_mount,
			     unsigned int copy_flags);

#define LOCK_MOUNT_MAYBE_BENEATH(mp, path, beneath) \
	struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \
	do_lock_mount((path), &mp, (beneath))
#define LOCK_MOUNT(mp, path) LOCK_MOUNT_MAYBE_BENEATH(mp, (path), false)
#define LOCK_MOUNT_EXACT(mp, path) \
	struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \
	lock_mount_exact((path), &mp, false, 0)
#define LOCK_MOUNT_EXACT_COPY(mp, path, copy_flags) \
	struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \
	lock_mount_exact((path), &mp, true, (copy_flags))

static int graft_tree(struct mount *mnt, const struct pinned_mountpoint *mp)
{
	if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER)
		return -EINVAL;

	if (d_is_dir(mp->mp->m_dentry) !=
	      d_is_dir(mnt->mnt.mnt_root))
		return -ENOTDIR;

	return attach_recursive_mnt(mnt, mp);
}

static int may_change_propagation(const struct mount *m)
{
        struct mnt_namespace *ns = m->mnt_ns;

	 // it must be mounted in some namespace
	 if (IS_ERR_OR_NULL(ns))         // is_mounted()
		 return -EINVAL;
	 // and the caller must be admin in userns of that namespace
	 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
		 return -EPERM;
	 return 0;
}

/*
 * Sanity check the flags to change_mnt_propagation.
 */

static int flags_to_propagation_type(int ms_flags)
{
	int type = ms_flags & ~(MS_REC | MS_SILENT);

	/* Fail if any non-propagation flags are set */
	if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
		return 0;
	/* Only one propagation flag should be set */
	if (!is_power_of_2(type))
		return 0;
	return type;
}

/*
 * recursively change the type of the mountpoint.
 */
static int do_change_type(const struct path *path, int ms_flags)
{
	struct mount *m;
	struct mount *mnt = real_mount(path->mnt);
	int recurse = ms_flags & MS_REC;
	int type;
	int err;

	if (!path_mounted(path))
		return -EINVAL;

	type = flags_to_propagation_type(ms_flags);
	if (!type)
		return -EINVAL;

	guard(namespace_excl)();

	err = may_change_propagation(mnt);
	if (err)
		return err;

	if (type == MS_SHARED) {
		err = invent_group_ids(mnt, recurse);
		if (err)
			return err;
	}

	for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
		change_mnt_propagation(m, type);

	return 0;
}

/* may_copy_tree() - check if a mount tree can be copied
 * @path: path to the mount tree to be copied
 *
 * This helper checks if the caller may copy the mount tree starting
 * from @path->mnt. The caller may copy the mount tree under the
 * following circumstances:
 *
 * (1) The caller is located in the mount namespace of the mount tree.
 *     This also implies that the mount does not belong to an anonymous
 *     mount namespace.
 * (2) The caller tries to copy an nfs mount referring to a mount
 *     namespace, i.e., the caller is trying to copy a mount namespace
 *     entry from nsfs.
 * (3) The caller tries to copy a pidfs mount referring to a pidfd.
 * (4) The caller is trying to copy a mount tree that belongs to an
 *     anonymous mount namespace.
 *
 *     For that to be safe, this helper enforces that the origin mount
 *     namespace the anonymous mount namespace was created from is the
 *     same as the caller's mount namespace by comparing the sequence
 *     numbers.
 *
 *     This is not strictly necessary. The current semantics of the new
 *     mount api enforce that the caller must be located in the same
 *     mount namespace as the mount tree it interacts with. Using the
 *     origin sequence number preserves these semantics even for
 *     anonymous mount namespaces. However, one could envision extending
 *     the api to directly operate across mount namespace if needed.
 *
 *     The ownership of a non-anonymous mount namespace such as the
 *     caller's cannot change.
 *     => We know that the caller's mount namespace is stable.
 *
 *     If the origin sequence number of the anonymous mount namespace is
 *     the same as the sequence number of the caller's mount namespace.
 *     => The owning namespaces are the same.
 *
 *     ==> The earlier capability check on the owning namespace of the
 *         caller's mount namespace ensures that the caller has the
 *         ability to copy the mount tree.
 *
 * Returns true if the mount tree can be copied, false otherwise.
 */
static inline bool may_copy_tree(const struct path *path)
{
	struct mount *mnt = real_mount(path->mnt);
	const struct dentry_operations *d_op;

	if (check_mnt(mnt))
		return true;

	d_op = path->dentry->d_op;
	if (d_op == &ns_dentry_operations)
		return true;

	if (d_op == &pidfs_dentry_operations)
		return true;

	if (!is_mounted(path->mnt))
		return false;

	return check_anonymous_mnt(mnt);
}

static struct mount *__do_loopback(const struct path *old_path,
				   unsigned int flags, unsigned int copy_flags)
{
	struct mount *old = real_mount(old_path->mnt);
	bool recurse = flags & AT_RECURSIVE;

	if (IS_MNT_UNBINDABLE(old))
		return ERR_PTR(-EINVAL);

	if (!may_copy_tree(old_path))
		return ERR_PTR(-EINVAL);

	if (!recurse && __has_locked_children(old, old_path->dentry))
		return ERR_PTR(-EINVAL);

	/*
	 * When creating a new mount namespace we don't want to copy over
	 * mounts of mount namespaces to avoid the risk of cycles and also to
	 * minimize the default complex interdependencies between mount
	 * namespaces.
	 *
	 * We could ofc just check whether all mount namespace files aren't
	 * creating cycles but really let's keep this simple.
	 */
	if (!(flags & OPEN_TREE_NAMESPACE))
		copy_flags |= CL_COPY_MNT_NS_FILE;

	if (recurse)
		return copy_tree(old, old_path->dentry, copy_flags);

	return clone_mnt(old, old_path->dentry, copy_flags);
}

/*
 * do loopback mount.
 */
static int do_loopback(const struct path *path, const char *old_name,
		       int recurse)
{
	struct path old_path __free(path_put) = {};
	struct mount *mnt = NULL;
	unsigned int flags = recurse ? AT_RECURSIVE : 0;
	int err;

	if (!old_name || !*old_name)
		return -EINVAL;
	err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
	if (err)
		return err;

	if (mnt_ns_loop(old_path.dentry))
		return -EINVAL;

	LOCK_MOUNT(mp, path);
	if (IS_ERR(mp.parent))
		return PTR_ERR(mp.parent);

	if (!check_mnt(mp.parent))
		return -EINVAL;

	mnt = __do_loopback(&old_path, flags, 0);
	if (IS_ERR(mnt))
		return PTR_ERR(mnt);

	err = graft_tree(mnt, &mp);
	if (err) {
		lock_mount_hash();
		umount_tree(mnt, UMOUNT_SYNC);
		unlock_mount_hash();
	}
	return err;
}

static struct mnt_namespace *get_detached_copy(const struct path *path, unsigned int flags)
{
	struct mnt_namespace *ns, *mnt_ns = current->nsproxy->mnt_ns, *src_mnt_ns;
	struct user_namespace *user_ns = mnt_ns->user_ns;
	struct mount *mnt, *p;

	ns = alloc_mnt_ns(user_ns, true);
	if (IS_ERR(ns))
		return ns;

	guard(namespace_excl)();

	/*
	 * Record the sequence number of the source mount namespace.
	 * This needs to hold namespace_sem to ensure that the mount
	 * doesn't get attached.
	 */
	if (is_mounted(path->mnt)) {
		src_mnt_ns = real_mount(path->mnt)->mnt_ns;
		if (is_anon_ns(src_mnt_ns))
			ns->seq_origin = src_mnt_ns->seq_origin;
		else
			ns->seq_origin = src_mnt_ns->ns.ns_id;
	}

	mnt = __do_loopback(path, flags, 0);
	if (IS_ERR(mnt)) {
		emptied_ns = ns;
		return ERR_CAST(mnt);
	}

	for (p = mnt; p; p = next_mnt(p, mnt)) {
		mnt_add_to_ns(ns, p);
		ns->nr_mounts++;
	}
	ns->root = mnt;
	return ns;
}

static struct file *open_detached_copy(struct path *path, unsigned int flags)
{
	struct mnt_namespace *ns = get_detached_copy(path, flags);
	struct file *file;

	if (IS_ERR(ns))
		return ERR_CAST(ns);

	mntput(path->mnt);
	path->mnt = mntget(&ns->root->mnt);
	file = dentry_open(path, O_PATH, current_cred());
	if (IS_ERR(file))
		dissolve_on_fput(path->mnt);
	else
		file->f_mode |= FMODE_NEED_UNMOUNT;
	return file;
}

static struct mnt_namespace *create_new_namespace(struct path *path, unsigned int flags)
{
	struct mnt_namespace *ns = current->nsproxy->mnt_ns;
	struct user_namespace *user_ns = current_user_ns();
	struct mnt_namespace *new_ns;
	struct mount *new_ns_root, *old_ns_root;
	struct path to_path;
	struct mount *mnt;
	unsigned int copy_flags = 0;
	bool locked = false;

	if (user_ns != ns->user_ns)
		copy_flags |= CL_SLAVE;

	new_ns = alloc_mnt_ns(user_ns, false);
	if (IS_ERR(new_ns))
		return ERR_CAST(new_ns);

	old_ns_root = ns->root;
	to_path.mnt = &old_ns_root->mnt;
	to_path.dentry = old_ns_root->mnt.mnt_root;

	VFS_WARN_ON_ONCE(old_ns_root->mnt.mnt_sb->s_type != &nullfs_fs_type);

	LOCK_MOUNT_EXACT_COPY(mp, &to_path, copy_flags);
	if (IS_ERR(mp.parent)) {
		free_mnt_ns(new_ns);
		return ERR_CAST(mp.parent);
	}
	new_ns_root = mp.parent;

	/*
	 * If the real rootfs had a locked mount on top of it somewhere
	 * in the stack, lock the new mount tree as well so it can't be
	 * exposed.
	 */
	mnt = old_ns_root;
	while (mnt->overmount) {
		mnt = mnt->overmount;
		if (mnt->mnt.mnt_flags & MNT_LOCKED)
			locked = true;
	}

	/*
	 * We don't emulate unshare()ing a mount namespace. We stick
	 * to the restrictions of creating detached bind-mounts. It
	 * has a lot saner and simpler semantics.
	 */
	mnt = __do_loopback(path, flags, copy_flags);
	scoped_guard(mount_writer) {
		if (IS_ERR(mnt)) {
			emptied_ns = new_ns;
			umount_tree(new_ns_root, 0);
			return ERR_CAST(mnt);
		}

		if (locked)
			mnt->mnt.mnt_flags |= MNT_LOCKED;
		/*
		 * now mount the detached tree on top of the copy
		 * of the real rootfs we created.
		 */
		attach_mnt(mnt, new_ns_root, mp.mp);
		if (user_ns != ns->user_ns)
			lock_mnt_tree(new_ns_root);
	}

	for (mnt = new_ns_root; mnt; mnt = next_mnt(mnt, new_ns_root)) {
		mnt_add_to_ns(new_ns, mnt);
		new_ns->nr_mounts++;
	}

	new_ns->root = new_ns_root;
	ns_tree_add_raw(new_ns);
	return new_ns;
}

static struct file *open_new_namespace(struct path *path, unsigned int flags)
{
	struct mnt_namespace *new_ns;

	new_ns = create_new_namespace(path, flags);
	if (IS_ERR(new_ns))
		return ERR_CAST(new_ns);
	return open_namespace_file(to_ns_common(new_ns));
}

static struct file *vfs_open_tree(int dfd, const char __user *filename, unsigned int flags)
{
	int ret;
	struct path path __free(path_put) = {};
	int lookup_flags = LOOKUP_AUTOMOUNT | LOOKUP_FOLLOW;

	BUILD_BUG_ON(OPEN_TREE_CLOEXEC != O_CLOEXEC);

	if (flags & ~(AT_EMPTY_PATH | AT_NO_AUTOMOUNT | AT_RECURSIVE |
		      AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLONE |
		      OPEN_TREE_CLOEXEC | OPEN_TREE_NAMESPACE))
		return ERR_PTR(-EINVAL);

	if ((flags & (AT_RECURSIVE | OPEN_TREE_CLONE | OPEN_TREE_NAMESPACE)) ==
	    AT_RECURSIVE)
		return ERR_PTR(-EINVAL);

	if (hweight32(flags & (OPEN_TREE_CLONE | OPEN_TREE_NAMESPACE)) > 1)
		return ERR_PTR(-EINVAL);

	if (flags & AT_NO_AUTOMOUNT)
		lookup_flags &= ~LOOKUP_AUTOMOUNT;
	if (flags & AT_SYMLINK_NOFOLLOW)
		lookup_flags &= ~LOOKUP_FOLLOW;

	/*
	 * If we create a new mount namespace with the cloned mount tree we
	 * just care about being privileged over our current user namespace.
	 * The new mount namespace will be owned by it.
	 */
	if ((flags & OPEN_TREE_NAMESPACE) &&
	    !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
		return ERR_PTR(-EPERM);

	if ((flags & OPEN_TREE_CLONE) && !may_mount())
		return ERR_PTR(-EPERM);

	CLASS(filename_uflags, name)(filename, flags);
	ret = filename_lookup(dfd, name, lookup_flags, &path, NULL);
	if (unlikely(ret))
		return ERR_PTR(ret);

	if (flags & OPEN_TREE_NAMESPACE)
		return open_new_namespace(&path, flags);

	if (flags & OPEN_TREE_CLONE)
		return open_detached_copy(&path, flags);

	return dentry_open(&path, O_PATH, current_cred());
}

SYSCALL_DEFINE3(open_tree, int, dfd, const char __user *, filename, unsigned, flags)
{
	return FD_ADD(flags, vfs_open_tree(dfd, filename, flags));
}

/*
 * Don't allow locked mount flags to be cleared.
 *
 * No locks need to be held here while testing the various MNT_LOCK
 * flags because those flags can never be cleared once they are set.
 */
static bool can_change_locked_flags(struct mount *mnt, unsigned int mnt_flags)
{
	unsigned int fl = mnt->mnt.mnt_flags;

	if ((fl & MNT_LOCK_READONLY) &&
	    !(mnt_flags & MNT_READONLY))
		return false;

	if ((fl & MNT_LOCK_NODEV) &&
	    !(mnt_flags & MNT_NODEV))
		return false;

	if ((fl & MNT_LOCK_NOSUID) &&
	    !(mnt_flags & MNT_NOSUID))
		return false;

	if ((fl & MNT_LOCK_NOEXEC) &&
	    !(mnt_flags & MNT_NOEXEC))
		return false;

	if ((fl & MNT_LOCK_ATIME) &&
	    ((fl & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK)))
		return false;

	return true;
}

static int change_mount_ro_state(struct mount *mnt, unsigned int mnt_flags)
{
	bool readonly_request = (mnt_flags & MNT_READONLY);

	if (readonly_request == __mnt_is_readonly(&mnt->mnt))
		return 0;

	if (readonly_request)
		return mnt_make_readonly(mnt);

	mnt->mnt.mnt_flags &= ~MNT_READONLY;
	return 0;
}

static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags)
{
	mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
	mnt->mnt.mnt_flags = mnt_flags;
	touch_mnt_namespace(mnt->mnt_ns);
}

static void mnt_warn_timestamp_expiry(const struct path *mountpoint,
				      struct vfsmount *mnt)
{
	struct super_block *sb = mnt->mnt_sb;

	if (!__mnt_is_readonly(mnt) &&
	   (!(sb->s_iflags & SB_I_TS_EXPIRY_WARNED)) &&
	   (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
		char *buf, *mntpath;

		buf = (char *)__get_free_page(GFP_KERNEL);
		if (buf)
			mntpath = d_path(mountpoint, buf, PAGE_SIZE);
		else
			mntpath = ERR_PTR(-ENOMEM);
		if (IS_ERR(mntpath))
			mntpath = "(unknown)";

		pr_warn("%s filesystem being %s at %s supports timestamps until %ptTd (0x%llx)\n",
			sb->s_type->name,
			is_mounted(mnt) ? "remounted" : "mounted",
			mntpath, &sb->s_time_max,
			(unsigned long long)sb->s_time_max);

		sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
		if (buf)
			free_page((unsigned long)buf);
	}
}

/*
 * Handle reconfiguration of the mountpoint only without alteration of the
 * superblock it refers to.  This is triggered by specifying MS_REMOUNT|MS_BIND
 * to mount(2).
 */
static int do_reconfigure_mnt(const struct path *path, unsigned int mnt_flags)
{
	struct super_block *sb = path->mnt->mnt_sb;
	struct mount *mnt = real_mount(path->mnt);
	int ret;

	if (!check_mnt(mnt))
		return -EINVAL;

	if (!path_mounted(path))
		return -EINVAL;

	if (!can_change_locked_flags(mnt, mnt_flags))
		return -EPERM;

	/*
	 * We're only checking whether the superblock is read-only not
	 * changing it, so only take down_read(&sb->s_umount).
	 */
	down_read(&sb->s_umount);
	lock_mount_hash();
	ret = change_mount_ro_state(mnt, mnt_flags);
	if (ret == 0)
		set_mount_attributes(mnt, mnt_flags);
	unlock_mount_hash();
	up_read(&sb->s_umount);

	mnt_warn_timestamp_expiry(path, &mnt->mnt);

	return ret;
}

/*
 * change filesystem flags. dir should be a physical root of filesystem.
 * If you've mounted a non-root directory somewhere and want to do remount
 * on it - tough luck.
 */
static int do_remount(const struct path *path, int sb_flags,
		      int mnt_flags, void *data)
{
	int err;
	struct super_block *sb = path->mnt->mnt_sb;
	struct mount *mnt = real_mount(path->mnt);
	struct fs_context *fc;

	if (!check_mnt(mnt))
		return -EINVAL;

	if (!path_mounted(path))
		return -EINVAL;

	if (!can_change_locked_flags(mnt, mnt_flags))
		return -EPERM;

	fc = fs_context_for_reconfigure(path->dentry, sb_flags, MS_RMT_MASK);
	if (IS_ERR(fc))
		return PTR_ERR(fc);

	/*
	 * Indicate to the filesystem that the remount request is coming
	 * from the legacy mount system call.
	 */
	fc->oldapi = true;

	err = parse_monolithic_mount_data(fc, data);
	if (!err) {
		down_write(&sb->s_umount);
		err = -EPERM;
		if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
			err = reconfigure_super(fc);
			if (!err) {
				lock_mount_hash();
				set_mount_attributes(mnt, mnt_flags);
				unlock_mount_hash();
			}
		}
		up_write(&sb->s_umount);
	}

	mnt_warn_timestamp_expiry(path, &mnt->mnt);

	put_fs_context(fc);
	return err;
}

static inline int tree_contains_unbindable(struct mount *mnt)
{
	struct mount *p;
	for (p = mnt; p; p = next_mnt(p, mnt)) {
		if (IS_MNT_UNBINDABLE(p))
			return 1;
	}
	return 0;
}

static int do_set_group(const struct path *from_path, const struct path *to_path)
{
	struct mount *from = real_mount(from_path->mnt);
	struct mount *to = real_mount(to_path->mnt);
	int err;

	guard(namespace_excl)();

	err = may_change_propagation(from);
	if (err)
		return err;
	err = may_change_propagation(to);
	if (err)
		return err;

	/* To and From paths should be mount roots */
	if (!path_mounted(from_path))
		return -EINVAL;
	if (!path_mounted(to_path))
		return -EINVAL;

	/* Setting sharing groups is only allowed across same superblock */
	if (from->mnt.mnt_sb != to->mnt.mnt_sb)
		return -EINVAL;

	/* From mount root should be wider than To mount root */
	if (!is_subdir(to->mnt.mnt_root, from->mnt.mnt_root))
		return -EINVAL;

	/* From mount should not have locked children in place of To's root */
	if (__has_locked_children(from, to->mnt.mnt_root))
		return -EINVAL;

	/* Setting sharing groups is only allowed on private mounts */
	if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to))
		return -EINVAL;

	/* From should not be private */
	if (!IS_MNT_SHARED(from) && !IS_MNT_SLAVE(from))
		return -EINVAL;

	if (IS_MNT_SLAVE(from)) {
		hlist_add_behind(&to->mnt_slave, &from->mnt_slave);
		to->mnt_master = from->mnt_master;
	}

	if (IS_MNT_SHARED(from)) {
		to->mnt_group_id = from->mnt_group_id;
		list_add(&to->mnt_share, &from->mnt_share);
		set_mnt_shared(to);
	}
	return 0;
}

/**
 * path_overmounted - check if path is overmounted
 * @path: path to check
 *
 * Check if path is overmounted, i.e., if there's a mount on top of
 * @path->mnt with @path->dentry as mountpoint.
 *
 * Context: namespace_sem must be held at least shared.
 * MUST NOT be called under lock_mount_hash() (there one should just
 * call __lookup_mnt() and check if it returns NULL).
 * Return: If path is overmounted true is returned, false if not.
 */
static inline bool path_overmounted(const struct path *path)
{
	unsigned seq = read_seqbegin(&mount_lock);
	bool no_child;

	rcu_read_lock();
	no_child = !__lookup_mnt(path->mnt, path->dentry);
	rcu_read_unlock();
	if (need_seqretry(&mount_lock, seq)) {
		read_seqlock_excl(&mount_lock);
		no_child = !__lookup_mnt(path->mnt, path->dentry);
		read_sequnlock_excl(&mount_lock);
	}
	return unlikely(!no_child);
}

/*
 * Check if there is a possibly empty chain of descent from p1 to p2.
 * Locks: namespace_sem (shared) or mount_lock (read_seqlock_excl).
 */
static bool mount_is_ancestor(const struct mount *p1, const struct mount *p2)
{
	while (p2 != p1 && mnt_has_parent(p2))
		p2 = p2->mnt_parent;
	return p2 == p1;
}

/**
 * can_move_mount_beneath - check that we can mount beneath the top mount
 * @mnt_from: mount we are trying to move
 * @mnt_to:   mount under which to mount
 * @mp:   mountpoint of @mnt_to
 *
 * - Make sure that nothing can be mounted beneath the caller's current
 *   root or the rootfs of the namespace.
 * - Make sure that the caller can unmount the topmost mount ensuring
 *   that the caller could reveal the underlying mountpoint.
 * - Ensure that nothing has been mounted on top of @mnt_from before we
 *   grabbed @namespace_sem to avoid creating pointless shadow mounts.
 * - Prevent mounting beneath a mount if the propagation relationship
 *   between the source mount, parent mount, and top mount would lead to
 *   nonsensical mount trees.
 *
 * Context: This function expects namespace_lock() to be held.
 * Return: On success 0, and on error a negative error code is returned.
 */
static int can_move_mount_beneath(const struct mount *mnt_from,
				  const struct mount *mnt_to,
				  const struct mountpoint *mp)
{
	struct mount *parent_mnt_to = mnt_to->mnt_parent;

	if (IS_MNT_LOCKED(mnt_to))
		return -EINVAL;

	/* Avoid creating shadow mounts during mount propagation. */
	if (mnt_from->overmount)
		return -EINVAL;

	/*
	 * Mounting beneath the rootfs only makes sense when the
	 * semantics of pivot_root(".", ".") are used.
	 */
	if (&mnt_to->mnt == current->fs->root.mnt)
		return -EINVAL;
	if (parent_mnt_to == current->nsproxy->mnt_ns->root)
		return -EINVAL;

	if (mount_is_ancestor(mnt_to, mnt_from))
		return -EINVAL;

	/*
	 * If the parent mount propagates to the child mount this would
	 * mean mounting @mnt_from on @mnt_to->mnt_parent and then
	 * propagating a copy @c of @mnt_from on top of @mnt_to. This
	 * defeats the whole purpose of mounting beneath another mount.
	 */
	if (propagation_would_overmount(parent_mnt_to, mnt_to, mp))
		return -EINVAL;

	/*
	 * If @mnt_to->mnt_parent propagates to @mnt_from this would
	 * mean propagating a copy @c of @mnt_from on top of @mnt_from.
	 * Afterwards @mnt_from would be mounted on top of
	 * @mnt_to->mnt_parent and @mnt_to would be unmounted from
	 * @mnt->mnt_parent and remounted on @mnt_from. But since @c is
	 * already mounted on @mnt_from, @mnt_to would ultimately be
	 * remounted on top of @c. Afterwards, @mnt_from would be
	 * covered by a copy @c of @mnt_from and @c would be covered by
	 * @mnt_from itself. This defeats the whole purpose of mounting
	 * @mnt_from beneath @mnt_to.
	 */
	if (check_mnt(mnt_from) &&
	    propagation_would_overmount(parent_mnt_to, mnt_from, mp))
		return -EINVAL;

	return 0;
}

/* may_use_mount() - check if a mount tree can be used
 * @mnt: vfsmount to be used
 *
 * This helper checks if the caller may use the mount tree starting
 * from @path->mnt. The caller may use the mount tree under the
 * following circumstances:
 *
 * (1) The caller is located in the mount namespace of the mount tree.
 *     This also implies that the mount does not belong to an anonymous
 *     mount namespace.
 * (2) The caller is trying to use a mount tree that belongs to an
 *     anonymous mount namespace.
 *
 *     For that to be safe, this helper enforces that the origin mount
 *     namespace the anonymous mount namespace was created from is the
 *     same as the caller's mount namespace by comparing the sequence
 *     numbers.
 *
 *     The ownership of a non-anonymous mount namespace such as the
 *     caller's cannot change.
 *     => We know that the caller's mount namespace is stable.
 *
 *     If the origin sequence number of the anonymous mount namespace is
 *     the same as the sequence number of the caller's mount namespace.
 *     => The owning namespaces are the same.
 *
 *     ==> The earlier capability check on the owning namespace of the
 *         caller's mount namespace ensures that the caller has the
 *         ability to use the mount tree.
 *
 * Returns true if the mount tree can be used, false otherwise.
 */
static inline bool may_use_mount(struct mount *mnt)
{
	if (check_mnt(mnt))
		return true;

	/*
	 * Make sure that noone unmounted the target path or somehow
	 * managed to get their hands on something purely kernel
	 * internal.
	 */
	if (!is_mounted(&mnt->mnt))
		return false;

	return check_anonymous_mnt(mnt);
}

static int do_move_mount(const struct path *old_path,
			 const struct path *new_path,
			 enum mnt_tree_flags_t flags)
{
	struct mount *old = real_mount(old_path->mnt);
	int err;
	bool beneath = flags & MNT_TREE_BENEATH;

	if (!path_mounted(old_path))
		return -EINVAL;

	if (d_is_dir(new_path->dentry) != d_is_dir(old_path->dentry))
		return -EINVAL;

	LOCK_MOUNT_MAYBE_BENEATH(mp, new_path, beneath);
	if (IS_ERR(mp.parent))
		return PTR_ERR(mp.parent);

	if (check_mnt(old)) {
		/* if the source is in our namespace... */
		/* ... it should be detachable from parent */
		if (!mnt_has_parent(old) || IS_MNT_LOCKED(old))
			return -EINVAL;
		/* ... which should not be shared */
		if (IS_MNT_SHARED(old->mnt_parent))
			return -EINVAL;
		/* ... and the target should be in our namespace */
		if (!check_mnt(mp.parent))
			return -EINVAL;
	} else {
		/*
		 * otherwise the source must be the root of some anon namespace.
		 */
		if (!anon_ns_root(old))
			return -EINVAL;
		/*
		 * Bail out early if the target is within the same namespace -
		 * subsequent checks would've rejected that, but they lose
		 * some corner cases if we check it early.
		 */
		if (old->mnt_ns == mp.parent->mnt_ns)
			return -EINVAL;
		/*
		 * Target should be either in our namespace or in an acceptable
		 * anon namespace, sensu check_anonymous_mnt().
		 */
		if (!may_use_mount(mp.parent))
			return -EINVAL;
	}

	if (beneath) {
		struct mount *over = real_mount(new_path->mnt);

		if (mp.parent != over->mnt_parent)
			over = mp.parent->overmount;
		err = can_move_mount_beneath(old, over, mp.mp);
		if (err)
			return err;
	}

	/*
	 * Don't move a mount tree containing unbindable mounts to a destination
	 * mount which is shared.
	 */
	if (IS_MNT_SHARED(mp.parent) && tree_contains_unbindable(old))
		return -EINVAL;
	if (!check_for_nsfs_mounts(old))
		return -ELOOP;
	if (mount_is_ancestor(old, mp.parent))
		return -ELOOP;

	return attach_recursive_mnt(old, &mp);
}

static int do_move_mount_old(const struct path *path, const char *old_name)
{
	struct path old_path __free(path_put) = {};
	int err;

	if (!old_name || !*old_name)
		return -EINVAL;

	err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
	if (err)
		return err;

	return do_move_mount(&old_path, path, 0);
}

/*
 * add a mount into a namespace's mount tree
 */
static int do_add_mount(struct mount *newmnt, const struct pinned_mountpoint *mp,
			int mnt_flags)
{
	struct mount *parent = mp->parent;

	if (IS_ERR(parent))
		return PTR_ERR(parent);

	mnt_flags &= ~MNT_INTERNAL_FLAGS;

	if (unlikely(!check_mnt(parent))) {
		/* that's acceptable only for automounts done in private ns */
		if (!(mnt_flags & MNT_SHRINKABLE))
			return -EINVAL;
		/* ... and for those we'd better have mountpoint still alive */
		if (!parent->mnt_ns)
			return -EINVAL;
	}

	/* Refuse the same filesystem on the same mount point */
	if (parent->mnt.mnt_sb == newmnt->mnt.mnt_sb &&
	    parent->mnt.mnt_root == mp->mp->m_dentry)
		return -EBUSY;

	if (d_is_symlink(newmnt->mnt.mnt_root))
		return -EINVAL;

	newmnt->mnt.mnt_flags = mnt_flags;
	return graft_tree(newmnt, mp);
}

static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags);

/*
 * Create a new mount using a superblock configuration and request it
 * be added to the namespace tree.
 */
static int do_new_mount_fc(struct fs_context *fc, const struct path *mountpoint,
			   unsigned int mnt_flags)
{
	struct super_block *sb;
	struct vfsmount *mnt __free(mntput) = fc_mount(fc);
	int error;

	if (IS_ERR(mnt))
		return PTR_ERR(mnt);

	sb = fc->root->d_sb;
	error = security_sb_kern_mount(sb);
	if (unlikely(error))
		return error;

	if (unlikely(mount_too_revealing(sb, &mnt_flags))) {
		errorfcp(fc, "VFS", "Mount too revealing");
		return -EPERM;
	}

	mnt_warn_timestamp_expiry(mountpoint, mnt);

	LOCK_MOUNT(mp, mountpoint);
	error = do_add_mount(real_mount(mnt), &mp, mnt_flags);
	if (!error)
		retain_and_null_ptr(mnt); // consumed on success
	return error;
}

/*
 * create a new mount for userspace and request it to be added into the
 * namespace's tree
 */
static int do_new_mount(const struct path *path, const char *fstype,
			int sb_flags, int mnt_flags,
			const char *name, void *data)
{
	struct file_system_type *type;
	struct fs_context *fc;
	const char *subtype = NULL;
	int err = 0;

	if (!fstype)
		return -EINVAL;

	type = get_fs_type(fstype);
	if (!type)
		return -ENODEV;

	if (type->fs_flags & FS_HAS_SUBTYPE) {
		subtype = strchr(fstype, '.');
		if (subtype) {
			subtype++;
			if (!*subtype) {
				put_filesystem(type);
				return -EINVAL;
			}
		}
	}

	fc = fs_context_for_mount(type, sb_flags);
	put_filesystem(type);
	if (IS_ERR(fc))
		return PTR_ERR(fc);

	/*
	 * Indicate to the filesystem that the mount request is coming
	 * from the legacy mount system call.
	 */
	fc->oldapi = true;

	if (subtype)
		err = vfs_parse_fs_string(fc, "subtype", subtype);
	if (!err && name)
		err = vfs_parse_fs_string(fc, "source", name);
	if (!err)
		err = parse_monolithic_mount_data(fc, data);
	if (!err && !mount_capable(fc))
		err = -EPERM;
	if (!err)
		err = do_new_mount_fc(fc, path, mnt_flags);

	put_fs_context(fc);
	return err;
}

static void lock_mount_exact(const struct path *path,
			     struct pinned_mountpoint *mp, bool copy_mount,
			     unsigned int copy_flags)
{
	struct dentry *dentry = path->dentry;
	int err;

	/* Assert that inode_lock() locked the correct inode. */
	VFS_WARN_ON_ONCE(copy_mount && !path_mounted(path));

	inode_lock(dentry->d_inode);
	namespace_lock();
	if (unlikely(cant_mount(dentry)))
		err = -ENOENT;
	else if (!copy_mount && path_overmounted(path))
		err = -EBUSY;
	else
		err = get_mountpoint(dentry, mp);
	if (unlikely(err)) {
		namespace_unlock();
		inode_unlock(dentry->d_inode);
		mp->parent = ERR_PTR(err);
		return;
	}

	if (copy_mount)
		mp->parent = clone_mnt(real_mount(path->mnt), dentry, copy_flags);
	else
		mp->parent = real_mount(path->mnt);
	if (unlikely(IS_ERR(mp->parent)))
		__unlock_mount(mp);
}

int finish_automount(struct vfsmount *__m, const struct path *path)
{
	struct vfsmount *m __free(mntput) = __m;
	struct mount *mnt;
	int err;

	if (!m)
		return 0;
	if (IS_ERR(m))
		return PTR_ERR(m);

	mnt = real_mount(m);

	if (m->mnt_root == path->dentry)
		return -ELOOP;

	/*
	 * we don't want to use LOCK_MOUNT() - in this case finding something
	 * that overmounts our mountpoint to be means "quitely drop what we've
	 * got", not "try to mount it on top".
	 */
	LOCK_MOUNT_EXACT(mp, path);
	if (mp.parent == ERR_PTR(-EBUSY))
		return 0;

	err = do_add_mount(mnt, &mp, path->mnt->mnt_flags | MNT_SHRINKABLE);
	if (likely(!err))
		retain_and_null_ptr(m);
	return err;
}

/**
 * mnt_set_expiry - Put a mount on an expiration list
 * @mnt: The mount to list.
 * @expiry_list: The list to add the mount to.
 */
void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list)
{
	guard(mount_locked_reader)();
	list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list);
}
EXPORT_SYMBOL(mnt_set_expiry);

/*
 * process a list of expirable mountpoints with the intent of discarding any
 * mountpoints that aren't in use and haven't been touched since last we came
 * here
 */
void mark_mounts_for_expiry(struct list_head *mounts)
{
	struct mount *mnt, *next;
	LIST_HEAD(graveyard);

	if (list_empty(mounts))
		return;

	guard(namespace_excl)();
	guard(mount_writer)();

	/* extract from the expiration list every vfsmount that matches the
	 * following criteria:
	 * - already mounted
	 * - only referenced by its parent vfsmount
	 * - still marked for expiry (marked on the last call here; marks are
	 *   cleared by mntput())
	 */
	list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
		if (!is_mounted(&mnt->mnt))
			continue;
		if (!xchg(&mnt->mnt_expiry_mark, 1) ||
			propagate_mount_busy(mnt, 1))
			continue;
		list_move(&mnt->mnt_expire, &graveyard);
	}
	while (!list_empty(&graveyard)) {
		mnt = list_first_entry(&graveyard, struct mount, mnt_expire);
		touch_mnt_namespace(mnt->mnt_ns);
		umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
	}
}

EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);

/*
 * Ripoff of 'select_parent()'
 *
 * search the list of submounts for a given mountpoint, and move any
 * shrinkable submounts to the 'graveyard' list.
 */
static int select_submounts(struct mount *parent, struct list_head *graveyard)
{
	struct mount *this_parent = parent;
	struct list_head *next;
	int found = 0;

repeat:
	next = this_parent->mnt_mounts.next;
resume:
	while (next != &this_parent->mnt_mounts) {
		struct list_head *tmp = next;
		struct mount *mnt = list_entry(tmp, struct mount, mnt_child);

		next = tmp->next;
		if (!(mnt->mnt.mnt_flags & MNT_SHRINKABLE))
			continue;
		/*
		 * Descend a level if the d_mounts list is non-empty.
		 */
		if (!list_empty(&mnt->mnt_mounts)) {
			this_parent = mnt;
			goto repeat;
		}

		if (!propagate_mount_busy(mnt, 1)) {
			list_move_tail(&mnt->mnt_expire, graveyard);
			found++;
		}
	}
	/*
	 * All done at this level ... ascend and resume the search
	 */
	if (this_parent != parent) {
		next = this_parent->mnt_child.next;
		this_parent = this_parent->mnt_parent;
		goto resume;
	}
	return found;
}

/*
 * process a list of expirable mountpoints with the intent of discarding any
 * submounts of a specific parent mountpoint
 *
 * mount_lock must be held for write
 */
static void shrink_submounts(struct mount *mnt)
{
	LIST_HEAD(graveyard);
	struct mount *m;

	/* extract submounts of 'mountpoint' from the expiration list */
	while (select_submounts(mnt, &graveyard)) {
		while (!list_empty(&graveyard)) {
			m = list_first_entry(&graveyard, struct mount,
						mnt_expire);
			touch_mnt_namespace(m->mnt_ns);
			umount_tree(m, UMOUNT_PROPAGATE|UMOUNT_SYNC);
		}
	}
}

static void *copy_mount_options(const void __user * data)
{
	char *copy;
	unsigned left, offset;

	if (!data)
		return NULL;

	copy = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!copy)
		return ERR_PTR(-ENOMEM);

	left = copy_from_user(copy, data, PAGE_SIZE);

	/*
	 * Not all architectures have an exact copy_from_user(). Resort to
	 * byte at a time.
	 */
	offset = PAGE_SIZE - left;
	while (left) {
		char c;
		if (get_user(c, (const char __user *)data + offset))
			break;
		copy[offset] = c;
		left--;
		offset++;
	}

	if (left == PAGE_SIZE) {
		kfree(copy);
		return ERR_PTR(-EFAULT);
	}

	return copy;
}

static char *copy_mount_string(const void __user *data)
{
	return data ? strndup_user(data, PATH_MAX) : NULL;
}

/*
 * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
 * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
 *
 * data is a (void *) that can point to any structure up to
 * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
 * information (or be NULL).
 *
 * Pre-0.97 versions of mount() didn't have a flags word.
 * When the flags word was introduced its top half was required
 * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
 * Therefore, if this magic number is present, it carries no information
 * and must be discarded.
 */
int path_mount(const char *dev_name, const struct path *path,
		const char *type_page, unsigned long flags, void *data_page)
{
	unsigned int mnt_flags = 0, sb_flags;
	int ret;

	/* Discard magic */
	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
		flags &= ~MS_MGC_MSK;

	/* Basic sanity checks */
	if (data_page)
		((char *)data_page)[PAGE_SIZE - 1] = 0;

	if (flags & MS_NOUSER)
		return -EINVAL;

	ret = security_sb_mount(dev_name, path, type_page, flags, data_page);
	if (ret)
		return ret;
	if (!may_mount())
		return -EPERM;
	if (flags & SB_MANDLOCK)
		warn_mandlock();

	/* Default to relatime unless overriden */
	if (!(flags & MS_NOATIME))
		mnt_flags |= MNT_RELATIME;

	/* Separate the per-mountpoint flags */
	if (flags & MS_NOSUID)
		mnt_flags |= MNT_NOSUID;
	if (flags & MS_NODEV)
		mnt_flags |= MNT_NODEV;
	if (flags & MS_NOEXEC)
		mnt_flags |= MNT_NOEXEC;
	if (flags & MS_NOATIME)
		mnt_flags |= MNT_NOATIME;
	if (flags & MS_NODIRATIME)
		mnt_flags |= MNT_NODIRATIME;
	if (flags & MS_STRICTATIME)
		mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
	if (flags & MS_RDONLY)
		mnt_flags |= MNT_READONLY;
	if (flags & MS_NOSYMFOLLOW)
		mnt_flags |= MNT_NOSYMFOLLOW;

	/* The default atime for remount is preservation */
	if ((flags & MS_REMOUNT) &&
	    ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME |
		       MS_STRICTATIME)) == 0)) {
		mnt_flags &= ~MNT_ATIME_MASK;
		mnt_flags |= path->mnt->mnt_flags & MNT_ATIME_MASK;
	}

	sb_flags = flags & (SB_RDONLY |
			    SB_SYNCHRONOUS |
			    SB_MANDLOCK |
			    SB_DIRSYNC |
			    SB_SILENT |
			    SB_POSIXACL |
			    SB_LAZYTIME |
			    SB_I_VERSION);

	if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND))
		return do_reconfigure_mnt(path, mnt_flags);
	if (flags & MS_REMOUNT)
		return do_remount(path, sb_flags, mnt_flags, data_page);
	if (flags & MS_BIND)
		return do_loopback(path, dev_name, flags & MS_REC);
	if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
		return do_change_type(path, flags);
	if (flags & MS_MOVE)
		return do_move_mount_old(path, dev_name);

	return do_new_mount(path, type_page, sb_flags, mnt_flags, dev_name,
			    data_page);
}

int do_mount(const char *dev_name, const char __user *dir_name,
		const char *type_page, unsigned long flags, void *data_page)
{
	struct path path __free(path_put) = {};
	int ret;

	ret = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);
	if (ret)
		return ret;
	return path_mount(dev_name, &path, type_page, flags, data_page);
}

static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
{
	return inc_ucount(ns, current_euid(), UCOUNT_MNT_NAMESPACES);
}

static void dec_mnt_namespaces(struct ucounts *ucounts)
{
	dec_ucount(ucounts, UCOUNT_MNT_NAMESPACES);
}

static void free_mnt_ns(struct mnt_namespace *ns)
{
	if (!is_anon_ns(ns))
		ns_common_free(ns);
	dec_mnt_namespaces(ns->ucounts);
	mnt_ns_tree_remove(ns);
}

static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool anon)
{
	struct mnt_namespace *new_ns;
	struct ucounts *ucounts;
	int ret;

	ucounts = inc_mnt_namespaces(user_ns);
	if (!ucounts)
		return ERR_PTR(-ENOSPC);

	new_ns = kzalloc_obj(struct mnt_namespace, GFP_KERNEL_ACCOUNT);
	if (!new_ns) {
		dec_mnt_namespaces(ucounts);
		return ERR_PTR(-ENOMEM);
	}

	if (anon)
		ret = ns_common_init_inum(new_ns, MNT_NS_ANON_INO);
	else
		ret = ns_common_init(new_ns);
	if (ret) {
		kfree(new_ns);
		dec_mnt_namespaces(ucounts);
		return ERR_PTR(ret);
	}
	ns_tree_gen_id(new_ns);

	new_ns->is_anon = anon;
	refcount_set(&new_ns->passive, 1);
	new_ns->mounts = RB_ROOT;
	init_waitqueue_head(&new_ns->poll);
	new_ns->user_ns = get_user_ns(user_ns);
	new_ns->ucounts = ucounts;
	return new_ns;
}

__latent_entropy
struct mnt_namespace *copy_mnt_ns(u64 flags, struct mnt_namespace *ns,
		struct user_namespace *user_ns, struct fs_struct *new_fs)
{
	struct mnt_namespace *new_ns;
	struct vfsmount *rootmnt __free(mntput) = NULL;
	struct vfsmount *pwdmnt __free(mntput) = NULL;
	struct mount *p, *q;
	struct mount *old;
	struct mount *new;
	int copy_flags;

	BUG_ON(!ns);

	if (likely(!(flags & CLONE_NEWNS))) {
		get_mnt_ns(ns);
		return ns;
	}

	old = ns->root;

	new_ns = alloc_mnt_ns(user_ns, false);
	if (IS_ERR(new_ns))
		return new_ns;

	guard(namespace_excl)();
	/* First pass: copy the tree topology */
	copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
	if (user_ns != ns->user_ns)
		copy_flags |= CL_SLAVE;
	new = copy_tree(old, old->mnt.mnt_root, copy_flags);
	if (IS_ERR(new)) {
		emptied_ns = new_ns;
		return ERR_CAST(new);
	}
	if (user_ns != ns->user_ns) {
		guard(mount_writer)();
		lock_mnt_tree(new);
	}
	new_ns->root = new;

	/*
	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
	 * as belonging to new namespace.  We have already acquired a private
	 * fs_struct, so tsk->fs->lock is not needed.
	 */
	p = old;
	q = new;
	while (p) {
		mnt_add_to_ns(new_ns, q);
		new_ns->nr_mounts++;
		if (new_fs) {
			if (&p->mnt == new_fs->root.mnt) {
				new_fs->root.mnt = mntget(&q->mnt);
				rootmnt = &p->mnt;
			}
			if (&p->mnt == new_fs->pwd.mnt) {
				new_fs->pwd.mnt = mntget(&q->mnt);
				pwdmnt = &p->mnt;
			}
		}
		p = next_mnt(p, old);
		q = next_mnt(q, new);
		if (!q)
			break;
		// an mntns binding we'd skipped?
		while (p->mnt.mnt_root != q->mnt.mnt_root)
			p = next_mnt(skip_mnt_tree(p), old);
	}
	ns_tree_add_raw(new_ns);
	return new_ns;
}

struct dentry *mount_subtree(struct vfsmount *m, const char *name)
{
	struct mount *mnt = real_mount(m);
	struct mnt_namespace *ns;
	struct super_block *s;
	struct path path;
	int err;

	ns = alloc_mnt_ns(&init_user_ns, true);
	if (IS_ERR(ns)) {
		mntput(m);
		return ERR_CAST(ns);
	}
	ns->root = mnt;
	ns->nr_mounts++;
	mnt_add_to_ns(ns, mnt);

	err = vfs_path_lookup(m->mnt_root, m,
			name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);

	put_mnt_ns(ns);

	if (err)
		return ERR_PTR(err);

	/* trade a vfsmount reference for active sb one */
	s = path.mnt->mnt_sb;
	atomic_inc(&s->s_active);
	mntput(path.mnt);
	/* lock the sucker */
	down_write(&s->s_umount);
	/* ... and return the root of (sub)tree on it */
	return path.dentry;
}
EXPORT_SYMBOL(mount_subtree);

SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
		char __user *, type, unsigned long, flags, void __user *, data)
{
	int ret;
	char *kernel_type;
	char *kernel_dev;
	void *options;

	kernel_type = copy_mount_string(type);
	ret = PTR_ERR(kernel_type);
	if (IS_ERR(kernel_type))
		goto out_type;

	kernel_dev = copy_mount_string(dev_name);
	ret = PTR_ERR(kernel_dev);
	if (IS_ERR(kernel_dev))
		goto out_dev;

	options = copy_mount_options(data);
	ret = PTR_ERR(options);
	if (IS_ERR(options))
		goto out_data;

	ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);

	kfree(options);
out_data:
	kfree(kernel_dev);
out_dev:
	kfree(kernel_type);
out_type:
	return ret;
}

#define FSMOUNT_VALID_FLAGS                                                    \
	(MOUNT_ATTR_RDONLY | MOUNT_ATTR_NOSUID | MOUNT_ATTR_NODEV |            \
	 MOUNT_ATTR_NOEXEC | MOUNT_ATTR__ATIME | MOUNT_ATTR_NODIRATIME |       \
	 MOUNT_ATTR_NOSYMFOLLOW)

#define MOUNT_SETATTR_VALID_FLAGS (FSMOUNT_VALID_FLAGS | MOUNT_ATTR_IDMAP)

#define MOUNT_SETATTR_PROPAGATION_FLAGS \
	(MS_UNBINDABLE | MS_PRIVATE | MS_SLAVE | MS_SHARED)

static unsigned int attr_flags_to_mnt_flags(u64 attr_flags)
{
	unsigned int mnt_flags = 0;

	if (attr_flags & MOUNT_ATTR_RDONLY)
		mnt_flags |= MNT_READONLY;
	if (attr_flags & MOUNT_ATTR_NOSUID)
		mnt_flags |= MNT_NOSUID;
	if (attr_flags & MOUNT_ATTR_NODEV)
		mnt_flags |= MNT_NODEV;
	if (attr_flags & MOUNT_ATTR_NOEXEC)
		mnt_flags |= MNT_NOEXEC;
	if (attr_flags & MOUNT_ATTR_NODIRATIME)
		mnt_flags |= MNT_NODIRATIME;
	if (attr_flags & MOUNT_ATTR_NOSYMFOLLOW)
		mnt_flags |= MNT_NOSYMFOLLOW;

	return mnt_flags;
}

/*
 * Create a kernel mount representation for a new, prepared superblock
 * (specified by fs_fd) and attach to an open_tree-like file descriptor.
 */
SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags,
		unsigned int, attr_flags)
{
	struct path new_path __free(path_put) = {};
	struct mnt_namespace *ns;
	struct fs_context *fc;
	struct vfsmount *new_mnt;
	struct mount *mnt;
	unsigned int mnt_flags = 0;
	long ret;

	if (!may_mount())
		return -EPERM;

	if ((flags & ~(FSMOUNT_CLOEXEC)) != 0)
		return -EINVAL;

	if (attr_flags & ~FSMOUNT_VALID_FLAGS)
		return -EINVAL;

	mnt_flags = attr_flags_to_mnt_flags(attr_flags);

	switch (attr_flags & MOUNT_ATTR__ATIME) {
	case MOUNT_ATTR_STRICTATIME:
		break;
	case MOUNT_ATTR_NOATIME:
		mnt_flags |= MNT_NOATIME;
		break;
	case MOUNT_ATTR_RELATIME:
		mnt_flags |= MNT_RELATIME;
		break;
	default:
		return -EINVAL;
	}

	CLASS(fd, f)(fs_fd);
	if (fd_empty(f))
		return -EBADF;

	if (fd_file(f)->f_op != &fscontext_fops)
		return -EINVAL;

	fc = fd_file(f)->private_data;

	ACQUIRE(mutex_intr, uapi_mutex)(&fc->uapi_mutex);
	ret = ACQUIRE_ERR(mutex_intr, &uapi_mutex);
	if (ret)
		return ret;

	/* There must be a valid superblock or we can't mount it */
	ret = -EINVAL;
	if (!fc->root)
		return ret;

	ret = -EPERM;
	if (mount_too_revealing(fc->root->d_sb, &mnt_flags)) {
		errorfcp(fc, "VFS", "Mount too revealing");
		return ret;
	}

	ret = -EBUSY;
	if (fc->phase != FS_CONTEXT_AWAITING_MOUNT)
		return ret;

	if (fc->sb_flags & SB_MANDLOCK)
		warn_mandlock();

	new_mnt = vfs_create_mount(fc);
	if (IS_ERR(new_mnt))
		return PTR_ERR(new_mnt);
	new_mnt->mnt_flags = mnt_flags;

	new_path.dentry = dget(fc->root);
	new_path.mnt = new_mnt;

	/* We've done the mount bit - now move the file context into more or
	 * less the same state as if we'd done an fspick().  We don't want to
	 * do any memory allocation or anything like that at this point as we
	 * don't want to have to handle any errors incurred.
	 */
	vfs_clean_context(fc);

	ns = alloc_mnt_ns(current->nsproxy->mnt_ns->user_ns, true);
	if (IS_ERR(ns))
		return PTR_ERR(ns);
	mnt = real_mount(new_path.mnt);
	ns->root = mnt;
	ns->nr_mounts = 1;
	mnt_add_to_ns(ns, mnt);
	mntget(new_path.mnt);

	FD_PREPARE(fdf, (flags & FSMOUNT_CLOEXEC) ? O_CLOEXEC : 0,
		   dentry_open(&new_path, O_PATH, fc->cred));
	if (fdf.err) {
		dissolve_on_fput(new_path.mnt);
		return fdf.err;
	}

	/*
	 * Attach to an apparent O_PATH fd with a note that we
	 * need to unmount it, not just simply put it.
	 */
	fd_prepare_file(fdf)->f_mode |= FMODE_NEED_UNMOUNT;
	return fd_publish(fdf);
}

static inline int vfs_move_mount(const struct path *from_path,
				 const struct path *to_path,
				 enum mnt_tree_flags_t mflags)
{
	int ret;

	ret = security_move_mount(from_path, to_path);
	if (ret)
		return ret;

	if (mflags & MNT_TREE_PROPAGATION)
		return do_set_group(from_path, to_path);

	return do_move_mount(from_path, to_path, mflags);
}

/*
 * Move a mount from one place to another.  In combination with
 * fsopen()/fsmount() this is used to install a new mount and in combination
 * with open_tree(OPEN_TREE_CLONE [| AT_RECURSIVE]) it can be used to copy
 * a mount subtree.
 *
 * Note the flags value is a combination of MOVE_MOUNT_* flags.
 */
SYSCALL_DEFINE5(move_mount,
		int, from_dfd, const char __user *, from_pathname,
		int, to_dfd, const char __user *, to_pathname,
		unsigned int, flags)
{
	struct path to_path __free(path_put) = {};
	struct path from_path __free(path_put) = {};
	unsigned int lflags, uflags;
	enum mnt_tree_flags_t mflags = 0;
	int ret = 0;

	if (!may_mount())
		return -EPERM;

	if (flags & ~MOVE_MOUNT__MASK)
		return -EINVAL;

	if ((flags & (MOVE_MOUNT_BENEATH | MOVE_MOUNT_SET_GROUP)) ==
	    (MOVE_MOUNT_BENEATH | MOVE_MOUNT_SET_GROUP))
		return -EINVAL;

	if (flags & MOVE_MOUNT_SET_GROUP)	mflags |= MNT_TREE_PROPAGATION;
	if (flags & MOVE_MOUNT_BENEATH)		mflags |= MNT_TREE_BENEATH;

	uflags = 0;
	if (flags & MOVE_MOUNT_T_EMPTY_PATH)
		uflags = AT_EMPTY_PATH;

	CLASS(filename_maybe_null,to_name)(to_pathname, uflags);
	if (!to_name && to_dfd >= 0) {
		CLASS(fd_raw, f_to)(to_dfd);
		if (fd_empty(f_to))
			return -EBADF;

		to_path = fd_file(f_to)->f_path;
		path_get(&to_path);
	} else {
		lflags = 0;
		if (flags & MOVE_MOUNT_T_SYMLINKS)
			lflags |= LOOKUP_FOLLOW;
		if (flags & MOVE_MOUNT_T_AUTOMOUNTS)
			lflags |= LOOKUP_AUTOMOUNT;
		ret = filename_lookup(to_dfd, to_name, lflags, &to_path, NULL);
		if (ret)
			return ret;
	}

	uflags = 0;
	if (flags & MOVE_MOUNT_F_EMPTY_PATH)
		uflags = AT_EMPTY_PATH;

	CLASS(filename_maybe_null,from_name)(from_pathname, uflags);
	if (!from_name && from_dfd >= 0) {
		CLASS(fd_raw, f_from)(from_dfd);
		if (fd_empty(f_from))
			return -EBADF;

		return vfs_move_mount(&fd_file(f_from)->f_path, &to_path, mflags);
	}

	lflags = 0;
	if (flags & MOVE_MOUNT_F_SYMLINKS)
		lflags |= LOOKUP_FOLLOW;
	if (flags & MOVE_MOUNT_F_AUTOMOUNTS)
		lflags |= LOOKUP_AUTOMOUNT;
	ret = filename_lookup(from_dfd, from_name, lflags, &from_path, NULL);
	if (ret)
		return ret;

	return vfs_move_mount(&from_path, &to_path, mflags);
}

/*
 * Return true if path is reachable from root
 *
 * locks: mount_locked_reader || namespace_shared && is_mounted(mnt)
 */
bool is_path_reachable(struct mount *mnt, struct dentry *dentry,
			 const struct path *root)
{
	while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) {
		dentry = mnt->mnt_mountpoint;
		mnt = mnt->mnt_parent;
	}
	return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);
}

bool path_is_under(const struct path *path1, const struct path *path2)
{
	guard(mount_locked_reader)();
	return is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);
}
EXPORT_SYMBOL(path_is_under);

int path_pivot_root(struct path *new, struct path *old)
{
	struct path root __free(path_put) = {};
	struct mount *new_mnt, *root_mnt, *old_mnt, *root_parent, *ex_parent;
	int error;

	if (!may_mount())
		return -EPERM;

	error = security_sb_pivotroot(old, new);
	if (error)
		return error;

	get_fs_root(current->fs, &root);

	LOCK_MOUNT(old_mp, old);
	old_mnt = old_mp.parent;
	if (IS_ERR(old_mnt))
		return PTR_ERR(old_mnt);

	new_mnt = real_mount(new->mnt);
	root_mnt = real_mount(root.mnt);
	ex_parent = new_mnt->mnt_parent;
	root_parent = root_mnt->mnt_parent;
	if (IS_MNT_SHARED(old_mnt) ||
		IS_MNT_SHARED(ex_parent) ||
		IS_MNT_SHARED(root_parent))
		return -EINVAL;
	if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
		return -EINVAL;
	if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
		return -EINVAL;
	if (d_unlinked(new->dentry))
		return -ENOENT;
	if (new_mnt == root_mnt || old_mnt == root_mnt)
		return -EBUSY; /* loop, on the same file system  */
	if (!path_mounted(&root))
		return -EINVAL; /* not a mountpoint */
	if (!mnt_has_parent(root_mnt))
		return -EINVAL; /* absolute root */
	if (!path_mounted(new))
		return -EINVAL; /* not a mountpoint */
	if (!mnt_has_parent(new_mnt))
		return -EINVAL; /* absolute root */
	/* make sure we can reach put_old from new_root */
	if (!is_path_reachable(old_mnt, old_mp.mp->m_dentry, new))
		return -EINVAL;
	/* make certain new is below the root */
	if (!is_path_reachable(new_mnt, new->dentry, &root))
		return -EINVAL;
	lock_mount_hash();
	umount_mnt(new_mnt);
	if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
		new_mnt->mnt.mnt_flags |= MNT_LOCKED;
		root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
	}
	/* mount new_root on / */
	attach_mnt(new_mnt, root_parent, root_mnt->mnt_mp);
	umount_mnt(root_mnt);
	/* mount old root on put_old */
	attach_mnt(root_mnt, old_mnt, old_mp.mp);
	touch_mnt_namespace(current->nsproxy->mnt_ns);
	/* A moved mount should not expire automatically */
	list_del_init(&new_mnt->mnt_expire);
	unlock_mount_hash();
	mnt_notify_add(root_mnt);
	mnt_notify_add(new_mnt);
	chroot_fs_refs(&root, new);
	return 0;
}

/*
 * pivot_root Semantics:
 * Moves the root file system of the current process to the directory put_old,
 * makes new_root as the new root file system of the current process, and sets
 * root/cwd of all processes which had them on the current root to new_root.
 *
 * Restrictions:
 * The new_root and put_old must be directories, and  must not be on the
 * same file  system as the current process root. The put_old  must  be
 * underneath new_root,  i.e. adding a non-zero number of /.. to the string
 * pointed to by put_old must yield the same directory as new_root. No other
 * file system may be mounted on put_old. After all, new_root is a mountpoint.
 *
 * The immutable nullfs filesystem is mounted as the true root of the VFS
 * hierarchy. The mutable rootfs (tmpfs/ramfs) is layered on top of this,
 * allowing pivot_root() to work normally from initramfs.
 *
 * Notes:
 *  - we don't move root/cwd if they are not at the root (reason: if something
 *    cared enough to change them, it's probably wrong to force them elsewhere)
 *  - it's okay to pick a root that isn't the root of a file system, e.g.
 *    /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
 *    though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
 *    first.
 */
SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
		const char __user *, put_old)
{
	struct path new __free(path_put) = {};
	struct path old __free(path_put) = {};
	int error;

	error = user_path_at(AT_FDCWD, new_root,
			     LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &new);
	if (error)
		return error;

	error = user_path_at(AT_FDCWD, put_old,
			     LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old);
	if (error)
		return error;

	return path_pivot_root(&new, &old);
}

static unsigned int recalc_flags(struct mount_kattr *kattr, struct mount *mnt)
{
	unsigned int flags = mnt->mnt.mnt_flags;

	/*  flags to clear */
	flags &= ~kattr->attr_clr;
	/* flags to raise */
	flags |= kattr->attr_set;

	return flags;
}

static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt)
{
	struct vfsmount *m = &mnt->mnt;
	struct user_namespace *fs_userns = m->mnt_sb->s_user_ns;

	if (!kattr->mnt_idmap)
		return 0;

	/*
	 * Creating an idmapped mount with the filesystem wide idmapping
	 * doesn't make sense so block that. We don't allow mushy semantics.
	 */
	if (kattr->mnt_userns == m->mnt_sb->s_user_ns)
		return -EINVAL;

	/*
	 * We only allow an mount to change it's idmapping if it has
	 * never been accessible to userspace.
	 */
	if (!(kattr->kflags & MOUNT_KATTR_IDMAP_REPLACE) && is_idmapped_mnt(m))
		return -EPERM;

	/* The underlying filesystem doesn't support idmapped mounts yet. */
	if (!(m->mnt_sb->s_type->fs_flags & FS_ALLOW_IDMAP))
		return -EINVAL;

	/* The filesystem has turned off idmapped mounts. */
	if (m->mnt_sb->s_iflags & SB_I_NOIDMAP)
		return -EINVAL;

	/* We're not controlling the superblock. */
	if (!ns_capable(fs_userns, CAP_SYS_ADMIN))
		return -EPERM;

	/* Mount has already been visible in the filesystem hierarchy. */
	if (!is_anon_ns(mnt->mnt_ns))
		return -EINVAL;

	return 0;
}

/**
 * mnt_allow_writers() - check whether the attribute change allows writers
 * @kattr: the new mount attributes
 * @mnt: the mount to which @kattr will be applied
 *
 * Check whether thew new mount attributes in @kattr allow concurrent writers.
 *
 * Return: true if writers need to be held, false if not
 */
static inline bool mnt_allow_writers(const struct mount_kattr *kattr,
				     const struct mount *mnt)
{
	return (!(kattr->attr_set & MNT_READONLY) ||
		(mnt->mnt.mnt_flags & MNT_READONLY)) &&
	       !kattr->mnt_idmap;
}

static int mount_setattr_prepare(struct mount_kattr *kattr, struct mount *mnt)
{
	struct mount *m;
	int err;

	for (m = mnt; m; m = next_mnt(m, mnt)) {
		if (!can_change_locked_flags(m, recalc_flags(kattr, m))) {
			err = -EPERM;
			break;
		}

		err = can_idmap_mount(kattr, m);
		if (err)
			break;

		if (!mnt_allow_writers(kattr, m)) {
			err = mnt_hold_writers(m);
			if (err) {
				m = next_mnt(m, mnt);
				break;
			}
		}

		if (!(kattr->kflags & MOUNT_KATTR_RECURSE))
			return 0;
	}

	if (err) {
		/* undo all mnt_hold_writers() we'd done */
		for (struct mount *p = mnt; p != m; p = next_mnt(p, mnt))
			mnt_unhold_writers(p);
	}
	return err;
}

static void do_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt)
{
	struct mnt_idmap *old_idmap;

	if (!kattr->mnt_idmap)
		return;

	old_idmap = mnt_idmap(&mnt->mnt);

	/* Pairs with smp_load_acquire() in mnt_idmap(). */
	smp_store_release(&mnt->mnt.mnt_idmap, mnt_idmap_get(kattr->mnt_idmap));
	mnt_idmap_put(old_idmap);
}

static void mount_setattr_commit(struct mount_kattr *kattr, struct mount *mnt)
{
	struct mount *m;

	for (m = mnt; m; m = next_mnt(m, mnt)) {
		unsigned int flags;

		do_idmap_mount(kattr, m);
		flags = recalc_flags(kattr, m);
		WRITE_ONCE(m->mnt.mnt_flags, flags);

		/* If we had to hold writers unblock them. */
		mnt_unhold_writers(m);

		if (kattr->propagation)
			change_mnt_propagation(m, kattr->propagation);
		if (!(kattr->kflags & MOUNT_KATTR_RECURSE))
			break;
	}
	touch_mnt_namespace(mnt->mnt_ns);
}

static int do_mount_setattr(const struct path *path, struct mount_kattr *kattr)
{
	struct mount *mnt = real_mount(path->mnt);
	int err = 0;

	if (!path_mounted(path))
		return -EINVAL;

	if (kattr->mnt_userns) {
		struct mnt_idmap *mnt_idmap;

		mnt_idmap = alloc_mnt_idmap(kattr->mnt_userns);
		if (IS_ERR(mnt_idmap))
			return PTR_ERR(mnt_idmap);
		kattr->mnt_idmap = mnt_idmap;
	}

	if (kattr->propagation) {
		/*
		 * Only take namespace_lock() if we're actually changing
		 * propagation.
		 */
		namespace_lock();
		if (kattr->propagation == MS_SHARED) {
			err = invent_group_ids(mnt, kattr->kflags & MOUNT_KATTR_RECURSE);
			if (err) {
				namespace_unlock();
				return err;
			}
		}
	}

	err = -EINVAL;
	lock_mount_hash();

	if (!anon_ns_root(mnt) && !check_mnt(mnt))
		goto out;

	/*
	 * First, we get the mount tree in a shape where we can change mount
	 * properties without failure. If we succeeded to do so we commit all
	 * changes and if we failed we clean up.
	 */
	err = mount_setattr_prepare(kattr, mnt);
	if (!err)
		mount_setattr_commit(kattr, mnt);

out:
	unlock_mount_hash();

	if (kattr->propagation) {
		if (err)
			cleanup_group_ids(mnt, NULL);
		namespace_unlock();
	}

	return err;
}

static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
				struct mount_kattr *kattr)
{
	struct ns_common *ns;
	struct user_namespace *mnt_userns;

	if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP))
		return 0;

	if (attr->attr_clr & MOUNT_ATTR_IDMAP) {
		/*
		 * We can only remove an idmapping if it's never been
		 * exposed to userspace.
		 */
		if (!(kattr->kflags & MOUNT_KATTR_IDMAP_REPLACE))
			return -EINVAL;

		/*
		 * Removal of idmappings is equivalent to setting
		 * nop_mnt_idmap.
		 */
		if (!(attr->attr_set & MOUNT_ATTR_IDMAP)) {
			kattr->mnt_idmap = &nop_mnt_idmap;
			return 0;
		}
	}

	if (attr->userns_fd > INT_MAX)
		return -EINVAL;

	CLASS(fd, f)(attr->userns_fd);
	if (fd_empty(f))
		return -EBADF;

	if (!proc_ns_file(fd_file(f)))
		return -EINVAL;

	ns = get_proc_ns(file_inode(fd_file(f)));
	if (ns->ns_type != CLONE_NEWUSER)
		return -EINVAL;

	/*
	 * The initial idmapping cannot be used to create an idmapped
	 * mount. We use the initial idmapping as an indicator of a mount
	 * that is not idmapped. It can simply be passed into helpers that
	 * are aware of idmapped mounts as a convenient shortcut. A user
	 * can just create a dedicated identity mapping to achieve the same
	 * result.
	 */
	mnt_userns = container_of(ns, struct user_namespace, ns);
	if (mnt_userns == &init_user_ns)
		return -EPERM;

	/* We're not controlling the target namespace. */
	if (!ns_capable(mnt_userns, CAP_SYS_ADMIN))
		return -EPERM;

	kattr->mnt_userns = get_user_ns(mnt_userns);
	return 0;
}

static int build_mount_kattr(const struct mount_attr *attr, size_t usize,
			     struct mount_kattr *kattr)
{
	if (attr->propagation & ~MOUNT_SETATTR_PROPAGATION_FLAGS)
		return -EINVAL;
	if (hweight32(attr->propagation & MOUNT_SETATTR_PROPAGATION_FLAGS) > 1)
		return -EINVAL;
	kattr->propagation = attr->propagation;

	if ((attr->attr_set | attr->attr_clr) & ~MOUNT_SETATTR_VALID_FLAGS)
		return -EINVAL;

	kattr->attr_set = attr_flags_to_mnt_flags(attr->attr_set);
	kattr->attr_clr = attr_flags_to_mnt_flags(attr->attr_clr);

	/*
	 * Since the MOUNT_ATTR_<atime> values are an enum, not a bitmap,
	 * users wanting to transition to a different atime setting cannot
	 * simply specify the atime setting in @attr_set, but must also
	 * specify MOUNT_ATTR__ATIME in the @attr_clr field.
	 * So ensure that MOUNT_ATTR__ATIME can't be partially set in
	 * @attr_clr and that @attr_set can't have any atime bits set if
	 * MOUNT_ATTR__ATIME isn't set in @attr_clr.
	 */
	if (attr->attr_clr & MOUNT_ATTR__ATIME) {
		if ((attr->attr_clr & MOUNT_ATTR__ATIME) != MOUNT_ATTR__ATIME)
			return -EINVAL;

		/*
		 * Clear all previous time settings as they are mutually
		 * exclusive.
		 */
		kattr->attr_clr |= MNT_RELATIME | MNT_NOATIME;
		switch (attr->attr_set & MOUNT_ATTR__ATIME) {
		case MOUNT_ATTR_RELATIME:
			kattr->attr_set |= MNT_RELATIME;
			break;
		case MOUNT_ATTR_NOATIME:
			kattr->attr_set |= MNT_NOATIME;
			break;
		case MOUNT_ATTR_STRICTATIME:
			break;
		default:
			return -EINVAL;
		}
	} else {
		if (attr->attr_set & MOUNT_ATTR__ATIME)
			return -EINVAL;
	}

	return build_mount_idmapped(attr, usize, kattr);
}

static void finish_mount_kattr(struct mount_kattr *kattr)
{
	if (kattr->mnt_userns) {
		put_user_ns(kattr->mnt_userns);
		kattr->mnt_userns = NULL;
	}

	if (kattr->mnt_idmap)
		mnt_idmap_put(kattr->mnt_idmap);
}

static int wants_mount_setattr(struct mount_attr __user *uattr, size_t usize,
			       struct mount_kattr *kattr)
{
	int ret;
	struct mount_attr attr;

	BUILD_BUG_ON(sizeof(struct mount_attr) != MOUNT_ATTR_SIZE_VER0);

	if (unlikely(usize > PAGE_SIZE))
		return -E2BIG;
	if (unlikely(usize < MOUNT_ATTR_SIZE_VER0))
		return -EINVAL;

	if (!may_mount())
		return -EPERM;

	ret = copy_struct_from_user(&attr, sizeof(attr), uattr, usize);
	if (ret)
		return ret;

	/* Don't bother walking through the mounts if this is a nop. */
	if (attr.attr_set == 0 &&
	    attr.attr_clr == 0 &&
	    attr.propagation == 0)
		return 0; /* Tell caller to not bother. */

	ret = build_mount_kattr(&attr, usize, kattr);
	if (ret < 0)
		return ret;

	return 1;
}

SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path,
		unsigned int, flags, struct mount_attr __user *, uattr,
		size_t, usize)
{
	int err;
	struct path target;
	struct mount_kattr kattr;
	unsigned int lookup_flags = LOOKUP_AUTOMOUNT | LOOKUP_FOLLOW;

	if (flags & ~(AT_EMPTY_PATH |
		      AT_RECURSIVE |
		      AT_SYMLINK_NOFOLLOW |
		      AT_NO_AUTOMOUNT))
		return -EINVAL;

	if (flags & AT_NO_AUTOMOUNT)
		lookup_flags &= ~LOOKUP_AUTOMOUNT;
	if (flags & AT_SYMLINK_NOFOLLOW)
		lookup_flags &= ~LOOKUP_FOLLOW;

	kattr = (struct mount_kattr) {
		.lookup_flags	= lookup_flags,
	};

	if (flags & AT_RECURSIVE)
		kattr.kflags |= MOUNT_KATTR_RECURSE;

	err = wants_mount_setattr(uattr, usize, &kattr);
	if (err <= 0)
		return err;

	CLASS(filename_uflags, name)(path, flags);
	err = filename_lookup(dfd, name, kattr.lookup_flags, &target, NULL);
	if (!err) {
		err = do_mount_setattr(&target, &kattr);
		path_put(&target);
	}
	finish_mount_kattr(&kattr);
	return err;
}

SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename,
		unsigned, flags, struct mount_attr __user *, uattr,
		size_t, usize)
{
	if (!uattr && usize)
		return -EINVAL;

	FD_PREPARE(fdf, flags, vfs_open_tree(dfd, filename, flags));
	if (fdf.err)
		return fdf.err;

	if (uattr) {
		struct mount_kattr kattr = {};
		struct file *file = fd_prepare_file(fdf);
		int ret;

		if (flags & OPEN_TREE_CLONE)
			kattr.kflags = MOUNT_KATTR_IDMAP_REPLACE;
		if (flags & AT_RECURSIVE)
			kattr.kflags |= MOUNT_KATTR_RECURSE;

		ret = wants_mount_setattr(uattr, usize, &kattr);
		if (ret > 0) {
			ret = do_mount_setattr(&file->f_path, &kattr);
			finish_mount_kattr(&kattr);
		}
		if (ret)
			return ret;
	}

	return fd_publish(fdf);
}

int show_path(struct seq_file *m, struct dentry *root)
{
	if (root->d_sb->s_op->show_path)
		return root->d_sb->s_op->show_path(m, root);

	seq_dentry(m, root, " \t\n\\");
	return 0;
}

static struct vfsmount *lookup_mnt_in_ns(u64 id, struct mnt_namespace *ns)
{
	struct mount *mnt = mnt_find_id_at(ns, id);

	if (!mnt || mnt->mnt_id_unique != id)
		return NULL;

	return &mnt->mnt;
}

struct kstatmount {
	struct statmount __user *buf;
	size_t bufsize;
	struct vfsmount *mnt;
	struct mnt_idmap *idmap;
	u64 mask;
	struct path root;
	struct seq_file seq;

	/* Must be last --ends in a flexible-array member. */
	struct statmount sm;
};

static u64 mnt_to_attr_flags(struct vfsmount *mnt)
{
	unsigned int mnt_flags = READ_ONCE(mnt->mnt_flags);
	u64 attr_flags = 0;

	if (mnt_flags & MNT_READONLY)
		attr_flags |= MOUNT_ATTR_RDONLY;
	if (mnt_flags & MNT_NOSUID)
		attr_flags |= MOUNT_ATTR_NOSUID;
	if (mnt_flags & MNT_NODEV)
		attr_flags |= MOUNT_ATTR_NODEV;
	if (mnt_flags & MNT_NOEXEC)
		attr_flags |= MOUNT_ATTR_NOEXEC;
	if (mnt_flags & MNT_NODIRATIME)
		attr_flags |= MOUNT_ATTR_NODIRATIME;
	if (mnt_flags & MNT_NOSYMFOLLOW)
		attr_flags |= MOUNT_ATTR_NOSYMFOLLOW;

	if (mnt_flags & MNT_NOATIME)
		attr_flags |= MOUNT_ATTR_NOATIME;
	else if (mnt_flags & MNT_RELATIME)
		attr_flags |= MOUNT_ATTR_RELATIME;
	else
		attr_flags |= MOUNT_ATTR_STRICTATIME;

	if (is_idmapped_mnt(mnt))
		attr_flags |= MOUNT_ATTR_IDMAP;

	return attr_flags;
}

static u64 mnt_to_propagation_flags(struct mount *m)
{
	u64 propagation = 0;

	if (IS_MNT_SHARED(m))
		propagation |= MS_SHARED;
	if (IS_MNT_SLAVE(m))
		propagation |= MS_SLAVE;
	if (IS_MNT_UNBINDABLE(m))
		propagation |= MS_UNBINDABLE;
	if (!propagation)
		propagation |= MS_PRIVATE;

	return propagation;
}

u64 vfsmount_to_propagation_flags(struct vfsmount *mnt)
{
	return mnt_to_propagation_flags(real_mount(mnt));
}
EXPORT_SYMBOL_GPL(vfsmount_to_propagation_flags);

static void statmount_sb_basic(struct kstatmount *s)
{
	struct super_block *sb = s->mnt->mnt_sb;

	s->sm.mask |= STATMOUNT_SB_BASIC;
	s->sm.sb_dev_major = MAJOR(sb->s_dev);
	s->sm.sb_dev_minor = MINOR(sb->s_dev);
	s->sm.sb_magic = sb->s_magic;
	s->sm.sb_flags = sb->s_flags & (SB_RDONLY|SB_SYNCHRONOUS|SB_DIRSYNC|SB_LAZYTIME);
}

static void statmount_mnt_basic(struct kstatmount *s)
{
	struct mount *m = real_mount(s->mnt);

	s->sm.mask |= STATMOUNT_MNT_BASIC;
	s->sm.mnt_id = m->mnt_id_unique;
	s->sm.mnt_parent_id = m->mnt_parent->mnt_id_unique;
	s->sm.mnt_id_old = m->mnt_id;
	s->sm.mnt_parent_id_old = m->mnt_parent->mnt_id;
	s->sm.mnt_attr = mnt_to_attr_flags(&m->mnt);
	s->sm.mnt_propagation = mnt_to_propagation_flags(m);
	s->sm.mnt_peer_group = m->mnt_group_id;
	s->sm.mnt_master = IS_MNT_SLAVE(m) ? m->mnt_master->mnt_group_id : 0;
}

static void statmount_propagate_from(struct kstatmount *s)
{
	struct mount *m = real_mount(s->mnt);

	s->sm.mask |= STATMOUNT_PROPAGATE_FROM;
	if (IS_MNT_SLAVE(m))
		s->sm.propagate_from = get_dominating_id(m, &current->fs->root);
}

static int statmount_mnt_root(struct kstatmount *s, struct seq_file *seq)
{
	int ret;
	size_t start = seq->count;

	ret = show_path(seq, s->mnt->mnt_root);
	if (ret)
		return ret;

	if (unlikely(seq_has_overflowed(seq)))
		return -EAGAIN;

	/*
         * Unescape the result. It would be better if supplied string was not
         * escaped in the first place, but that's a pretty invasive change.
         */
	seq->buf[seq->count] = '\0';
	seq->count = start;
	seq_commit(seq, string_unescape_inplace(seq->buf + start, UNESCAPE_OCTAL));
	return 0;
}

static int statmount_mnt_point(struct kstatmount *s, struct seq_file *seq)
{
	struct vfsmount *mnt = s->mnt;
	struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt };
	int err;

	err = seq_path_root(seq, &mnt_path, &s->root, "");
	return err == SEQ_SKIP ? 0 : err;
}

static int statmount_fs_type(struct kstatmount *s, struct seq_file *seq)
{
	struct super_block *sb = s->mnt->mnt_sb;

	seq_puts(seq, sb->s_type->name);
	return 0;
}

static void statmount_fs_subtype(struct kstatmount *s, struct seq_file *seq)
{
	struct super_block *sb = s->mnt->mnt_sb;

	if (sb->s_subtype)
		seq_puts(seq, sb->s_subtype);
}

static int statmount_sb_source(struct kstatmount *s, struct seq_file *seq)
{
	struct super_block *sb = s->mnt->mnt_sb;
	struct mount *r = real_mount(s->mnt);

	if (sb->s_op->show_devname) {
		size_t start = seq->count;
		int ret;

		ret = sb->s_op->show_devname(seq, s->mnt->mnt_root);
		if (ret)
			return ret;

		if (unlikely(seq_has_overflowed(seq)))
			return -EAGAIN;

		/* Unescape the result */
		seq->buf[seq->count] = '\0';
		seq->count = start;
		seq_commit(seq, string_unescape_inplace(seq->buf + start, UNESCAPE_OCTAL));
	} else {
		seq_puts(seq, r->mnt_devname);
	}
	return 0;
}

static void statmount_mnt_ns_id(struct kstatmount *s, struct mnt_namespace *ns)
{
	s->sm.mask |= STATMOUNT_MNT_NS_ID;
	s->sm.mnt_ns_id = ns->ns.ns_id;
}

static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq)
{
	struct vfsmount *mnt = s->mnt;
	struct super_block *sb = mnt->mnt_sb;
	size_t start = seq->count;
	int err;

	err = security_sb_show_options(seq, sb);
	if (err)
		return err;

	if (sb->s_op->show_options) {
		err = sb->s_op->show_options(seq, mnt->mnt_root);
		if (err)
			return err;
	}

	if (unlikely(seq_has_overflowed(seq)))
		return -EAGAIN;

	if (seq->count == start)
		return 0;

	/* skip leading comma */
	memmove(seq->buf + start, seq->buf + start + 1,
		seq->count - start - 1);
	seq->count--;

	return 0;
}

static inline int statmount_opt_process(struct seq_file *seq, size_t start)
{
	char *buf_end, *opt_end, *src, *dst;
	int count = 0;

	if (unlikely(seq_has_overflowed(seq)))
		return -EAGAIN;

	buf_end = seq->buf + seq->count;
	dst = seq->buf + start;
	src = dst + 1;	/* skip initial comma */

	if (src >= buf_end) {
		seq->count = start;
		return 0;
	}

	*buf_end = '\0';
	for (; src < buf_end; src = opt_end + 1) {
		opt_end = strchrnul(src, ',');
		*opt_end = '\0';
		dst += string_unescape(src, dst, 0, UNESCAPE_OCTAL) + 1;
		if (WARN_ON_ONCE(++count == INT_MAX))
			return -EOVERFLOW;
	}
	seq->count = dst - 1 - seq->buf;
	return count;
}

static int statmount_opt_array(struct kstatmount *s, struct seq_file *seq)
{
	struct vfsmount *mnt = s->mnt;
	struct super_block *sb = mnt->mnt_sb;
	size_t start = seq->count;
	int err;

	if (!sb->s_op->show_options)
		return 0;

	err = sb->s_op->show_options(seq, mnt->mnt_root);
	if (err)
		return err;

	err = statmount_opt_process(seq, start);
	if (err < 0)
		return err;

	s->sm.opt_num = err;
	return 0;
}

static int statmount_opt_sec_array(struct kstatmount *s, struct seq_file *seq)
{
	struct vfsmount *mnt = s->mnt;
	struct super_block *sb = mnt->mnt_sb;
	size_t start = seq->count;
	int err;

	err = security_sb_show_options(seq, sb);
	if (err)
		return err;

	err = statmount_opt_process(seq, start);
	if (err < 0)
		return err;

	s->sm.opt_sec_num = err;
	return 0;
}

static inline int statmount_mnt_uidmap(struct kstatmount *s, struct seq_file *seq)
{
	int ret;

	ret = statmount_mnt_idmap(s->idmap, seq, true);
	if (ret < 0)
		return ret;

	s->sm.mnt_uidmap_num = ret;
	/*
	 * Always raise STATMOUNT_MNT_UIDMAP even if there are no valid
	 * mappings. This allows userspace to distinguish between a
	 * non-idmapped mount and an idmapped mount where none of the
	 * individual mappings are valid in the caller's idmapping.
	 */
	if (is_valid_mnt_idmap(s->idmap))
		s->sm.mask |= STATMOUNT_MNT_UIDMAP;
	return 0;
}

static inline int statmount_mnt_gidmap(struct kstatmount *s, struct seq_file *seq)
{
	int ret;

	ret = statmount_mnt_idmap(s->idmap, seq, false);
	if (ret < 0)
		return ret;

	s->sm.mnt_gidmap_num = ret;
	/*
	 * Always raise STATMOUNT_MNT_GIDMAP even if there are no valid
	 * mappings. This allows userspace to distinguish between a
	 * non-idmapped mount and an idmapped mount where none of the
	 * individual mappings are valid in the caller's idmapping.
	 */
	if (is_valid_mnt_idmap(s->idmap))
		s->sm.mask |= STATMOUNT_MNT_GIDMAP;
	return 0;
}

static int statmount_string(struct kstatmount *s, u64 flag)
{
	int ret = 0;
	size_t kbufsize;
	struct seq_file *seq = &s->seq;
	struct statmount *sm = &s->sm;
	u32 start, *offp;

	/* Reserve an empty string at the beginning for any unset offsets */
	if (!seq->count)
		seq_putc(seq, 0);

	start = seq->count;

	switch (flag) {
	case STATMOUNT_FS_TYPE:
		offp = &sm->fs_type;
		ret = statmount_fs_type(s, seq);
		break;
	case STATMOUNT_MNT_ROOT:
		offp = &sm->mnt_root;
		ret = statmount_mnt_root(s, seq);
		break;
	case STATMOUNT_MNT_POINT:
		offp = &sm->mnt_point;
		ret = statmount_mnt_point(s, seq);
		break;
	case STATMOUNT_MNT_OPTS:
		offp = &sm->mnt_opts;
		ret = statmount_mnt_opts(s, seq);
		break;
	case STATMOUNT_OPT_ARRAY:
		offp = &sm->opt_array;
		ret = statmount_opt_array(s, seq);
		break;
	case STATMOUNT_OPT_SEC_ARRAY:
		offp = &sm->opt_sec_array;
		ret = statmount_opt_sec_array(s, seq);
		break;
	case STATMOUNT_FS_SUBTYPE:
		offp = &sm->fs_subtype;
		statmount_fs_subtype(s, seq);
		break;
	case STATMOUNT_SB_SOURCE:
		offp = &sm->sb_source;
		ret = statmount_sb_source(s, seq);
		break;
	case STATMOUNT_MNT_UIDMAP:
		offp = &sm->mnt_uidmap;
		ret = statmount_mnt_uidmap(s, seq);
		break;
	case STATMOUNT_MNT_GIDMAP:
		offp = &sm->mnt_gidmap;
		ret = statmount_mnt_gidmap(s, seq);
		break;
	default:
		WARN_ON_ONCE(true);
		return -EINVAL;
	}

	/*
	 * If nothing was emitted, return to avoid setting the flag
	 * and terminating the buffer.
	 */
	if (seq->count == start)
		return ret;
	if (unlikely(check_add_overflow(sizeof(*sm), seq->count, &kbufsize)))
		return -EOVERFLOW;
	if (kbufsize >= s->bufsize)
		return -EOVERFLOW;

	/* signal a retry */
	if (unlikely(seq_has_overflowed(seq)))
		return -EAGAIN;

	if (ret)
		return ret;

	seq->buf[seq->count++] = '\0';
	sm->mask |= flag;
	*offp = start;
	return 0;
}

static int copy_statmount_to_user(struct kstatmount *s)
{
	struct statmount *sm = &s->sm;
	struct seq_file *seq = &s->seq;
	char __user *str = ((char __user *)s->buf) + sizeof(*sm);
	size_t copysize = min_t(size_t, s->bufsize, sizeof(*sm));

	if (seq->count && copy_to_user(str, seq->buf, seq->count))
		return -EFAULT;

	/* Return the number of bytes copied to the buffer */
	sm->size = copysize + seq->count;
	if (copy_to_user(s->buf, sm, copysize))
		return -EFAULT;

	return 0;
}

static struct mount *listmnt_next(struct mount *curr, bool reverse)
{
	struct rb_node *node;

	if (reverse)
		node = rb_prev(&curr->mnt_node);
	else
		node = rb_next(&curr->mnt_node);

	return node_to_mount(node);
}

static int grab_requested_root(struct mnt_namespace *ns, struct path *root)
{
	struct mount *first, *child;

	rwsem_assert_held(&namespace_sem);

	/* We're looking at our own ns, just use get_fs_root. */
	if (ns == current->nsproxy->mnt_ns) {
		get_fs_root(current->fs, root);
		return 0;
	}

	/*
	 * We have to find the first mount in our ns and use that, however it
	 * may not exist, so handle that properly.
	 */
	if (mnt_ns_empty(ns))
		return -ENOENT;

	first = child = ns->root;
	for (;;) {
		child = listmnt_next(child, false);
		if (!child)
			return -ENOENT;
		if (child->mnt_parent == first)
			break;
	}

	root->mnt = mntget(&child->mnt);
	root->dentry = dget(root->mnt->mnt_root);
	return 0;
}

/* This must be updated whenever a new flag is added */
#define STATMOUNT_SUPPORTED (STATMOUNT_SB_BASIC | \
			     STATMOUNT_MNT_BASIC | \
			     STATMOUNT_PROPAGATE_FROM | \
			     STATMOUNT_MNT_ROOT | \
			     STATMOUNT_MNT_POINT | \
			     STATMOUNT_FS_TYPE | \
			     STATMOUNT_MNT_NS_ID | \
			     STATMOUNT_MNT_OPTS | \
			     STATMOUNT_FS_SUBTYPE | \
			     STATMOUNT_SB_SOURCE | \
			     STATMOUNT_OPT_ARRAY | \
			     STATMOUNT_OPT_SEC_ARRAY | \
			     STATMOUNT_SUPPORTED_MASK | \
			     STATMOUNT_MNT_UIDMAP | \
			     STATMOUNT_MNT_GIDMAP)

/* locks: namespace_shared */
static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
                        struct file *mnt_file, struct mnt_namespace *ns)
{
	int err;

	if (mnt_file) {
		WARN_ON_ONCE(ns != NULL);

		s->mnt = mnt_file->f_path.mnt;
		ns = real_mount(s->mnt)->mnt_ns;
		if (IS_ERR(ns))
			return PTR_ERR(ns);
		if (!ns)
			/*
			 * We can't set mount point and mnt_ns_id since we don't have a
			 * ns for the mount. This can happen if the mount is unmounted
			 * with MNT_DETACH.
			 */
			s->mask &= ~(STATMOUNT_MNT_POINT | STATMOUNT_MNT_NS_ID);
	} else {
		/* Has the namespace already been emptied? */
		if (mnt_ns_id && mnt_ns_empty(ns))
			return -ENOENT;

		s->mnt = lookup_mnt_in_ns(mnt_id, ns);
		if (!s->mnt)
			return -ENOENT;
	}

	if (ns) {
		err = grab_requested_root(ns, &s->root);
		if (err)
			return err;

		if (!mnt_file) {
			struct mount *m;
			/*
			 * Don't trigger audit denials. We just want to determine what
			 * mounts to show users.
			 */
			m = real_mount(s->mnt);
			if (!is_path_reachable(m, m->mnt.mnt_root, &s->root) &&
			    !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))
				return -EPERM;
		}
	}

	err = security_sb_statfs(s->mnt->mnt_root);
	if (err)
		return err;

	/*
	 * Note that mount properties in mnt->mnt_flags, mnt->mnt_idmap
	 * can change concurrently as we only hold the read-side of the
	 * namespace semaphore and mount properties may change with only
	 * the mount lock held.
	 *
	 * We could sample the mount lock sequence counter to detect
	 * those changes and retry. But it's not worth it. Worst that
	 * happens is that the mnt->mnt_idmap pointer is already changed
	 * while mnt->mnt_flags isn't or vica versa. So what.
	 *
	 * Both mnt->mnt_flags and mnt->mnt_idmap are set and retrieved
	 * via READ_ONCE()/WRITE_ONCE() and guard against theoretical
	 * torn read/write. That's all we care about right now.
	 */
	s->idmap = mnt_idmap(s->mnt);
	if (s->mask & STATMOUNT_MNT_BASIC)
		statmount_mnt_basic(s);

	if (s->mask & STATMOUNT_SB_BASIC)
		statmount_sb_basic(s);

	if (s->mask & STATMOUNT_PROPAGATE_FROM)
		statmount_propagate_from(s);

	if (s->mask & STATMOUNT_FS_TYPE)
		err = statmount_string(s, STATMOUNT_FS_TYPE);

	if (!err && s->mask & STATMOUNT_MNT_ROOT)
		err = statmount_string(s, STATMOUNT_MNT_ROOT);

	if (!err && s->mask & STATMOUNT_MNT_POINT)
		err = statmount_string(s, STATMOUNT_MNT_POINT);

	if (!err && s->mask & STATMOUNT_MNT_OPTS)
		err = statmount_string(s, STATMOUNT_MNT_OPTS);

	if (!err && s->mask & STATMOUNT_OPT_ARRAY)
		err = statmount_string(s, STATMOUNT_OPT_ARRAY);

	if (!err && s->mask & STATMOUNT_OPT_SEC_ARRAY)
		err = statmount_string(s, STATMOUNT_OPT_SEC_ARRAY);

	if (!err && s->mask & STATMOUNT_FS_SUBTYPE)
		err = statmount_string(s, STATMOUNT_FS_SUBTYPE);

	if (!err && s->mask & STATMOUNT_SB_SOURCE)
		err = statmount_string(s, STATMOUNT_SB_SOURCE);

	if (!err && s->mask & STATMOUNT_MNT_UIDMAP)
		err = statmount_string(s, STATMOUNT_MNT_UIDMAP);

	if (!err && s->mask & STATMOUNT_MNT_GIDMAP)
		err = statmount_string(s, STATMOUNT_MNT_GIDMAP);

	if (!err && s->mask & STATMOUNT_MNT_NS_ID)
		statmount_mnt_ns_id(s, ns);

	if (!err && s->mask & STATMOUNT_SUPPORTED_MASK) {
		s->sm.mask |= STATMOUNT_SUPPORTED_MASK;
		s->sm.supported_mask = STATMOUNT_SUPPORTED;
	}

	if (err)
		return err;

	/* Are there bits in the return mask not present in STATMOUNT_SUPPORTED? */
	WARN_ON_ONCE(~STATMOUNT_SUPPORTED & s->sm.mask);

	return 0;
}

static inline bool retry_statmount(const long ret, size_t *seq_size)
{
	if (likely(ret != -EAGAIN))
		return false;
	if (unlikely(check_mul_overflow(*seq_size, 2, seq_size)))
		return false;
	if (unlikely(*seq_size > MAX_RW_COUNT))
		return false;
	return true;
}

#define STATMOUNT_STRING_REQ (STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT | \
			      STATMOUNT_FS_TYPE | STATMOUNT_MNT_OPTS | \
			      STATMOUNT_FS_SUBTYPE | STATMOUNT_SB_SOURCE | \
			      STATMOUNT_OPT_ARRAY | STATMOUNT_OPT_SEC_ARRAY | \
			      STATMOUNT_MNT_UIDMAP | STATMOUNT_MNT_GIDMAP)

static int prepare_kstatmount(struct kstatmount *ks, struct mnt_id_req *kreq,
			      struct statmount __user *buf, size_t bufsize,
			      size_t seq_size)
{
	if (!access_ok(buf, bufsize))
		return -EFAULT;

	memset(ks, 0, sizeof(*ks));
	ks->mask = kreq->param;
	ks->buf = buf;
	ks->bufsize = bufsize;

	if (ks->mask & STATMOUNT_STRING_REQ) {
		if (bufsize == sizeof(ks->sm))
			return -EOVERFLOW;

		ks->seq.buf = kvmalloc(seq_size, GFP_KERNEL_ACCOUNT);
		if (!ks->seq.buf)
			return -ENOMEM;

		ks->seq.size = seq_size;
	}

	return 0;
}

static int copy_mnt_id_req(const struct mnt_id_req __user *req,
			   struct mnt_id_req *kreq, unsigned int flags)
{
	int ret;
	size_t usize;

	BUILD_BUG_ON(sizeof(struct mnt_id_req) != MNT_ID_REQ_SIZE_VER1);

	ret = get_user(usize, &req->size);
	if (ret)
		return -EFAULT;
	if (unlikely(usize > PAGE_SIZE))
		return -E2BIG;
	if (unlikely(usize < MNT_ID_REQ_SIZE_VER0))
		return -EINVAL;
	memset(kreq, 0, sizeof(*kreq));
	ret = copy_struct_from_user(kreq, sizeof(*kreq), req, usize);
	if (ret)
		return ret;

	if (flags & STATMOUNT_BY_FD) {
		if (kreq->mnt_id || kreq->mnt_ns_id)
			return -EINVAL;
	} else {
		if (kreq->mnt_ns_fd != 0 && kreq->mnt_ns_id)
			return -EINVAL;
		/* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */
		if (kreq->mnt_id <= MNT_UNIQUE_ID_OFFSET)
			return -EINVAL;
	}
	return 0;
}

/*
 * If the user requested a specific mount namespace id, look that up and return
 * that, or if not simply grab a passive reference on our mount namespace and
 * return that.
 */
static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq)
{
	struct mnt_namespace *mnt_ns;

	if (kreq->mnt_ns_id) {
		mnt_ns = lookup_mnt_ns(kreq->mnt_ns_id);
		if (!mnt_ns)
			return ERR_PTR(-ENOENT);
	} else if (kreq->mnt_ns_fd) {
		struct ns_common *ns;

		CLASS(fd, f)(kreq->mnt_ns_fd);
		if (fd_empty(f))
			return ERR_PTR(-EBADF);

		if (!proc_ns_file(fd_file(f)))
			return ERR_PTR(-EINVAL);

		ns = get_proc_ns(file_inode(fd_file(f)));
		if (ns->ns_type != CLONE_NEWNS)
			return ERR_PTR(-EINVAL);

		mnt_ns = to_mnt_ns(ns);
		refcount_inc(&mnt_ns->passive);
	} else {
		mnt_ns = current->nsproxy->mnt_ns;
		refcount_inc(&mnt_ns->passive);
	}

	return mnt_ns;
}

SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
		struct statmount __user *, buf, size_t, bufsize,
		unsigned int, flags)
{
	struct mnt_namespace *ns __free(mnt_ns_release) = NULL;
	struct kstatmount *ks __free(kfree) = NULL;
	struct file *mnt_file __free(fput) = NULL;
	struct mnt_id_req kreq;
	/* We currently support retrieval of 3 strings. */
	size_t seq_size = 3 * PATH_MAX;
	int ret;

	if (flags & ~STATMOUNT_BY_FD)
		return -EINVAL;

	ret = copy_mnt_id_req(req, &kreq, flags);
	if (ret)
		return ret;

	if (flags & STATMOUNT_BY_FD) {
		mnt_file = fget_raw(kreq.mnt_fd);
		if (!mnt_file)
			return -EBADF;
		/* do_statmount sets ns in case of STATMOUNT_BY_FD */
	} else {
		ns = grab_requested_mnt_ns(&kreq);
		if (IS_ERR(ns))
			return PTR_ERR(ns);

		if (kreq.mnt_ns_id && (ns != current->nsproxy->mnt_ns) &&
		    !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))
			return -EPERM;
	}

	ks = kmalloc(sizeof(*ks), GFP_KERNEL_ACCOUNT);
	if (!ks)
		return -ENOMEM;

retry:
	ret = prepare_kstatmount(ks, &kreq, buf, bufsize, seq_size);
	if (ret)
		return ret;

	scoped_guard(namespace_shared)
		ret = do_statmount(ks, kreq.mnt_id, kreq.mnt_ns_id, mnt_file, ns);

	if (!ret)
		ret = copy_statmount_to_user(ks);
	kvfree(ks->seq.buf);
	path_put(&ks->root);
	if (retry_statmount(ret, &seq_size))
		goto retry;
	return ret;
}

struct klistmount {
	u64 last_mnt_id;
	u64 mnt_parent_id;
	u64 *kmnt_ids;
	u32 nr_mnt_ids;
	struct mnt_namespace *ns;
	struct path root;
};

/* locks: namespace_shared */
static ssize_t do_listmount(struct klistmount *kls, bool reverse)
{
	struct mnt_namespace *ns = kls->ns;
	u64 mnt_parent_id = kls->mnt_parent_id;
	u64 last_mnt_id = kls->last_mnt_id;
	u64 *mnt_ids = kls->kmnt_ids;
	size_t nr_mnt_ids = kls->nr_mnt_ids;
	struct path orig;
	struct mount *r, *first;
	ssize_t ret;

	rwsem_assert_held(&namespace_sem);

	ret = grab_requested_root(ns, &kls->root);
	if (ret)
		return ret;

	if (mnt_parent_id == LSMT_ROOT) {
		orig = kls->root;
	} else {
		orig.mnt = lookup_mnt_in_ns(mnt_parent_id, ns);
		if (!orig.mnt)
			return -ENOENT;
		orig.dentry = orig.mnt->mnt_root;
	}

	/*
	 * Don't trigger audit denials. We just want to determine what
	 * mounts to show users.
	 */
	if (!is_path_reachable(real_mount(orig.mnt), orig.dentry, &kls->root) &&
	    !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))
		return -EPERM;

	ret = security_sb_statfs(orig.dentry);
	if (ret)
		return ret;

	if (!last_mnt_id) {
		if (reverse)
			first = node_to_mount(ns->mnt_last_node);
		else
			first = node_to_mount(ns->mnt_first_node);
	} else {
		if (reverse)
			first = mnt_find_id_at_reverse(ns, last_mnt_id - 1);
		else
			first = mnt_find_id_at(ns, last_mnt_id + 1);
	}

	for (ret = 0, r = first; r && nr_mnt_ids; r = listmnt_next(r, reverse)) {
		if (r->mnt_id_unique == mnt_parent_id)
			continue;
		if (!is_path_reachable(r, r->mnt.mnt_root, &orig))
			continue;
		*mnt_ids = r->mnt_id_unique;
		mnt_ids++;
		nr_mnt_ids--;
		ret++;
	}
	return ret;
}

static void __free_klistmount_free(const struct klistmount *kls)
{
	path_put(&kls->root);
	kvfree(kls->kmnt_ids);
	mnt_ns_release(kls->ns);
}

static inline int prepare_klistmount(struct klistmount *kls, struct mnt_id_req *kreq,
				     size_t nr_mnt_ids)
{
	u64 last_mnt_id = kreq->param;
	struct mnt_namespace *ns;

	/* The first valid unique mount id is MNT_UNIQUE_ID_OFFSET + 1. */
	if (last_mnt_id != 0 && last_mnt_id <= MNT_UNIQUE_ID_OFFSET)
		return -EINVAL;

	kls->last_mnt_id = last_mnt_id;

	kls->nr_mnt_ids = nr_mnt_ids;
	kls->kmnt_ids = kvmalloc_array(nr_mnt_ids, sizeof(*kls->kmnt_ids),
				       GFP_KERNEL_ACCOUNT);
	if (!kls->kmnt_ids)
		return -ENOMEM;

	ns = grab_requested_mnt_ns(kreq);
	if (IS_ERR(ns))
		return PTR_ERR(ns);
	kls->ns = ns;

	kls->mnt_parent_id = kreq->mnt_id;
	return 0;
}

SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req,
		u64 __user *, mnt_ids, size_t, nr_mnt_ids, unsigned int, flags)
{
	struct klistmount kls __free(klistmount_free) = {};
	const size_t maxcount = 1000000;
	struct mnt_id_req kreq;
	ssize_t ret;

	if (flags & ~LISTMOUNT_REVERSE)
		return -EINVAL;

	/*
	 * If the mount namespace really has more than 1 million mounts the
	 * caller must iterate over the mount namespace (and reconsider their
	 * system design...).
	 */
	if (unlikely(nr_mnt_ids > maxcount))
		return -EOVERFLOW;

	if (!access_ok(mnt_ids, nr_mnt_ids * sizeof(*mnt_ids)))
		return -EFAULT;

	ret = copy_mnt_id_req(req, &kreq, 0);
	if (ret)
		return ret;

	ret = prepare_klistmount(&kls, &kreq, nr_mnt_ids);
	if (ret)
		return ret;

	if (kreq.mnt_ns_id && (kls.ns != current->nsproxy->mnt_ns) &&
	    !ns_capable_noaudit(kls.ns->user_ns, CAP_SYS_ADMIN))
		return -ENOENT;

	/*
	 * We only need to guard against mount topology changes as
	 * listmount() doesn't care about any mount properties.
	 */
	scoped_guard(namespace_shared)
		ret = do_listmount(&kls, (flags & LISTMOUNT_REVERSE));
	if (ret <= 0)
		return ret;

	if (copy_to_user(mnt_ids, kls.kmnt_ids, ret * sizeof(*mnt_ids)))
		return -EFAULT;

	return ret;
}

struct mnt_namespace init_mnt_ns = {
	.ns		= NS_COMMON_INIT(init_mnt_ns),
	.user_ns	= &init_user_ns,
	.passive	= REFCOUNT_INIT(1),
	.mounts		= RB_ROOT,
	.poll		= __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll),
};

static void __init init_mount_tree(void)
{
	struct vfsmount *mnt, *nullfs_mnt;
	struct mount *mnt_root;
	struct path root;

	/*
	 * We create two mounts:
	 *
	 * (1) nullfs with mount id 1
	 * (2) mutable rootfs with mount id 2
	 *
	 * with (2) mounted on top of (1).
	 */
	nullfs_mnt = vfs_kern_mount(&nullfs_fs_type, 0, "nullfs", NULL);
	if (IS_ERR(nullfs_mnt))
		panic("VFS: Failed to create nullfs");

	mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", initramfs_options);
	if (IS_ERR(mnt))
		panic("Can't create rootfs");

	VFS_WARN_ON_ONCE(real_mount(nullfs_mnt)->mnt_id != 1);
	VFS_WARN_ON_ONCE(real_mount(mnt)->mnt_id != 2);

	/* The namespace root is the nullfs mnt. */
	mnt_root		= real_mount(nullfs_mnt);
	init_mnt_ns.root	= mnt_root;

	/* Mount mutable rootfs on top of nullfs. */
	root.mnt		= nullfs_mnt;
	root.dentry		= nullfs_mnt->mnt_root;

	LOCK_MOUNT_EXACT(mp, &root);
	if (unlikely(IS_ERR(mp.parent)))
		panic("VFS: Failed to mount rootfs on nullfs");
	scoped_guard(mount_writer)
		attach_mnt(real_mount(mnt), mp.parent, mp.mp);

	pr_info("VFS: Finished mounting rootfs on nullfs\n");

	/*
	 * We've dropped all locks here but that's fine. Not just are we
	 * the only task that's running, there's no other mount
	 * namespace in existence and the initial mount namespace is
	 * completely empty until we add the mounts we just created.
	 */
	for (struct mount *p = mnt_root; p; p = next_mnt(p, mnt_root)) {
		mnt_add_to_ns(&init_mnt_ns, p);
		init_mnt_ns.nr_mounts++;
	}

	init_task.nsproxy->mnt_ns = &init_mnt_ns;
	get_mnt_ns(&init_mnt_ns);

	/* The root and pwd always point to the mutable rootfs. */
	root.mnt	= mnt;
	root.dentry	= mnt->mnt_root;
	set_fs_pwd(current->fs, &root);
	set_fs_root(current->fs, &root);

	ns_tree_add(&init_mnt_ns);
}

void __init mnt_init(void)
{
	int err;

	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
			0, SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL);

	mount_hashtable = alloc_large_system_hash("Mount-cache",
				sizeof(struct hlist_head),
				mhash_entries, 19,
				HASH_ZERO,
				&m_hash_shift, &m_hash_mask, 0, 0);
	mountpoint_hashtable = alloc_large_system_hash("Mountpoint-cache",
				sizeof(struct hlist_head),
				mphash_entries, 19,
				HASH_ZERO,
				&mp_hash_shift, &mp_hash_mask, 0, 0);

	if (!mount_hashtable || !mountpoint_hashtable)
		panic("Failed to allocate mount hash table\n");

	kernfs_init();

	err = sysfs_init();
	if (err)
		printk(KERN_WARNING "%s: sysfs_init error: %d\n",
			__func__, err);
	fs_kobj = kobject_create_and_add("fs", NULL);
	if (!fs_kobj)
		printk(KERN_WARNING "%s: kobj create error\n", __func__);
	shmem_init();
	init_rootfs();
	init_mount_tree();
}

void put_mnt_ns(struct mnt_namespace *ns)
{
	if (!ns_ref_put(ns))
		return;
	guard(namespace_excl)();
	emptied_ns = ns;
	guard(mount_writer)();
	umount_tree(ns->root, 0);
}

struct vfsmount *kern_mount(struct file_system_type *type)
{
	struct vfsmount *mnt;
	mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, NULL);
	if (!IS_ERR(mnt)) {
		/*
		 * it is a longterm mount, don't release mnt until
		 * we unmount before file sys is unregistered
		*/
		real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
	}
	return mnt;
}
EXPORT_SYMBOL_GPL(kern_mount);

void kern_unmount(struct vfsmount *mnt)
{
	/* release long term mount so mount point can be released */
	if (!IS_ERR(mnt)) {
		mnt_make_shortterm(mnt);
		synchronize_rcu();	/* yecchhh... */
		mntput(mnt);
	}
}
EXPORT_SYMBOL(kern_unmount);

void kern_unmount_array(struct vfsmount *mnt[], unsigned int num)
{
	unsigned int i;

	for (i = 0; i < num; i++)
		mnt_make_shortterm(mnt[i]);
	synchronize_rcu_expedited();
	for (i = 0; i < num; i++)
		mntput(mnt[i]);
}
EXPORT_SYMBOL(kern_unmount_array);

bool our_mnt(struct vfsmount *mnt)
{
	return check_mnt(real_mount(mnt));
}

bool current_chrooted(void)
{
	/* Does the current process have a non-standard root */
	struct path fs_root __free(path_put) = {};
	struct mount *root;

	get_fs_root(current->fs, &fs_root);

	/* Find the namespace root */

	guard(mount_locked_reader)();

	root = topmost_overmount(current->nsproxy->mnt_ns->root);

	return fs_root.mnt != &root->mnt || !path_mounted(&fs_root);
}

static bool mnt_already_visible(struct mnt_namespace *ns,
				const struct super_block *sb,
				int *new_mnt_flags)
{
	int new_flags = *new_mnt_flags;
	struct mount *mnt, *n;

	guard(namespace_shared)();
	rbtree_postorder_for_each_entry_safe(mnt, n, &ns->mounts, mnt_node) {
		struct mount *child;
		int mnt_flags;

		if (mnt->mnt.mnt_sb->s_type != sb->s_type)
			continue;

		/* This mount is not fully visible if it's root directory
		 * is not the root directory of the filesystem.
		 */
		if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
			continue;

		/* A local view of the mount flags */
		mnt_flags = mnt->mnt.mnt_flags;

		/* Don't miss readonly hidden in the superblock flags */
		if (sb_rdonly(mnt->mnt.mnt_sb))
			mnt_flags |= MNT_LOCK_READONLY;

		/* Verify the mount flags are equal to or more permissive
		 * than the proposed new mount.
		 */
		if ((mnt_flags & MNT_LOCK_READONLY) &&
		    !(new_flags & MNT_READONLY))
			continue;
		if ((mnt_flags & MNT_LOCK_ATIME) &&
		    ((mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
			continue;

		/* This mount is not fully visible if there are any
		 * locked child mounts that cover anything except for
		 * empty directories.
		 */
		list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
			struct inode *inode = child->mnt_mountpoint->d_inode;
			/* Only worry about locked mounts */
			if (!(child->mnt.mnt_flags & MNT_LOCKED))
				continue;
			/* Is the directory permanently empty? */
			if (!is_empty_dir_inode(inode))
				goto next;
		}
		/* Preserve the locked attributes */
		*new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \
					       MNT_LOCK_ATIME);
		return true;
	next:	;
	}
	return false;
}

static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags)
{
	const unsigned long required_iflags = SB_I_NOEXEC | SB_I_NODEV;
	struct mnt_namespace *ns = current->nsproxy->mnt_ns;
	unsigned long s_iflags;

	if (ns->user_ns == &init_user_ns)
		return false;

	/* Can this filesystem be too revealing? */
	s_iflags = sb->s_iflags;
	if (!(s_iflags & SB_I_USERNS_VISIBLE))
		return false;

	if ((s_iflags & required_iflags) != required_iflags) {
		WARN_ONCE(1, "Expected s_iflags to contain 0x%lx\n",
			  required_iflags);
		return true;
	}

	return !mnt_already_visible(ns, sb, new_mnt_flags);
}

bool mnt_may_suid(struct vfsmount *mnt)
{
	/*
	 * Foreign mounts (accessed via fchdir or through /proc
	 * symlinks) are always treated as if they are nosuid.  This
	 * prevents namespaces from trusting potentially unsafe
	 * suid/sgid bits, file caps, or security labels that originate
	 * in other namespaces.
	 */
	return !(mnt->mnt_flags & MNT_NOSUID) && check_mnt(real_mount(mnt)) &&
	       current_in_userns(mnt->mnt_sb->s_user_ns);
}

static struct ns_common *mntns_get(struct task_struct *task)
{
	struct ns_common *ns = NULL;
	struct nsproxy *nsproxy;

	task_lock(task);
	nsproxy = task->nsproxy;
	if (nsproxy) {
		ns = &nsproxy->mnt_ns->ns;
		get_mnt_ns(to_mnt_ns(ns));
	}
	task_unlock(task);

	return ns;
}

static void mntns_put(struct ns_common *ns)
{
	put_mnt_ns(to_mnt_ns(ns));
}

static int mntns_install(struct nsset *nsset, struct ns_common *ns)
{
	struct nsproxy *nsproxy = nsset->nsproxy;
	struct fs_struct *fs = nsset->fs;
	struct mnt_namespace *mnt_ns = to_mnt_ns(ns), *old_mnt_ns;
	struct user_namespace *user_ns = nsset->cred->user_ns;
	struct path root;
	int err;

	if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
	    !ns_capable(user_ns, CAP_SYS_CHROOT) ||
	    !ns_capable(user_ns, CAP_SYS_ADMIN))
		return -EPERM;

	if (is_anon_ns(mnt_ns))
		return -EINVAL;

	if (fs->users != 1)
		return -EINVAL;

	get_mnt_ns(mnt_ns);
	old_mnt_ns = nsproxy->mnt_ns;
	nsproxy->mnt_ns = mnt_ns;

	/* Find the root */
	err = vfs_path_lookup(mnt_ns->root->mnt.mnt_root, &mnt_ns->root->mnt,
				"/", LOOKUP_DOWN, &root);
	if (err) {
		/* revert to old namespace */
		nsproxy->mnt_ns = old_mnt_ns;
		put_mnt_ns(mnt_ns);
		return err;
	}

	put_mnt_ns(old_mnt_ns);

	/* Update the pwd and root */
	set_fs_pwd(fs, &root);
	set_fs_root(fs, &root);

	path_put(&root);
	return 0;
}

static struct user_namespace *mntns_owner(struct ns_common *ns)
{
	return to_mnt_ns(ns)->user_ns;
}

const struct proc_ns_operations mntns_operations = {
	.name		= "mnt",
	.get		= mntns_get,
	.put		= mntns_put,
	.install	= mntns_install,
	.owner		= mntns_owner,
};

#ifdef CONFIG_SYSCTL
static const struct ctl_table fs_namespace_sysctls[] = {
	{
		.procname	= "mount-max",
		.data		= &sysctl_mount_max,
		.maxlen		= sizeof(unsigned int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= SYSCTL_ONE,
	},
};

static int __init init_fs_namespace_sysctls(void)
{
	register_sysctl_init("fs", fs_namespace_sysctls);
	return 0;
}
fs_initcall(init_fs_namespace_sysctls);

#endif /* CONFIG_SYSCTL */
