fs/namespace.c

Source file repositories/reference/linux-study-clean/fs/namespace.c

File Facts

System
Linux kernel
Corpus path
fs/namespace.c
Extension
.c
Size
169311 bytes
Lines
6556
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: syscall or user/kernel boundary
Status
core implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

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,

Annotation

Implementation Notes