|  | /* SPDX-License-Identifier: GPL-2.0 */ | 
|  | #ifndef _LINUX_NSPROXY_H | 
|  | #define _LINUX_NSPROXY_H | 
|  |  | 
|  | #include <linux/spinlock.h> | 
|  | #include <linux/sched.h> | 
|  |  | 
|  | struct mnt_namespace; | 
|  | struct uts_namespace; | 
|  | struct ipc_namespace; | 
|  | struct pid_namespace; | 
|  | struct cgroup_namespace; | 
|  | struct fs_struct; | 
|  |  | 
|  | /* | 
|  | * A structure to contain pointers to all per-process | 
|  | * namespaces - fs (mount), uts, network, sysvipc, etc. | 
|  | * | 
|  | * The pid namespace is an exception -- it's accessed using | 
|  | * task_active_pid_ns.  The pid namespace here is the | 
|  | * namespace that children will use. | 
|  | * | 
|  | * 'count' is the number of tasks holding a reference. | 
|  | * The count for each namespace, then, will be the number | 
|  | * of nsproxies pointing to it, not the number of tasks. | 
|  | * | 
|  | * The nsproxy is shared by tasks which share all namespaces. | 
|  | * As soon as a single namespace is cloned or unshared, the | 
|  | * nsproxy is copied. | 
|  | */ | 
|  | struct nsproxy { | 
|  | atomic_t count; | 
|  | struct uts_namespace *uts_ns; | 
|  | struct ipc_namespace *ipc_ns; | 
|  | struct mnt_namespace *mnt_ns; | 
|  | struct pid_namespace *pid_ns_for_children; | 
|  | struct net 	     *net_ns; | 
|  | struct cgroup_namespace *cgroup_ns; | 
|  | }; | 
|  | extern struct nsproxy init_nsproxy; | 
|  |  | 
|  | /* | 
|  | * the namespaces access rules are: | 
|  | * | 
|  | *  1. only current task is allowed to change tsk->nsproxy pointer or | 
|  | *     any pointer on the nsproxy itself.  Current must hold the task_lock | 
|  | *     when changing tsk->nsproxy. | 
|  | * | 
|  | *  2. when accessing (i.e. reading) current task's namespaces - no | 
|  | *     precautions should be taken - just dereference the pointers | 
|  | * | 
|  | *  3. the access to other task namespaces is performed like this | 
|  | *     task_lock(task); | 
|  | *     nsproxy = task->nsproxy; | 
|  | *     if (nsproxy != NULL) { | 
|  | *             / * | 
|  | *               * work with the namespaces here | 
|  | *               * e.g. get the reference on one of them | 
|  | *               * / | 
|  | *     } / * | 
|  | *         * NULL task->nsproxy means that this task is | 
|  | *         * almost dead (zombie) | 
|  | *         * / | 
|  | *     task_unlock(task); | 
|  | * | 
|  | */ | 
|  |  | 
|  | int copy_namespaces(unsigned long flags, struct task_struct *tsk); | 
|  | void exit_task_namespaces(struct task_struct *tsk); | 
|  | void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new); | 
|  | void free_nsproxy(struct nsproxy *ns); | 
|  | int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **, | 
|  | struct cred *, struct fs_struct *); | 
|  | int __init nsproxy_cache_init(void); | 
|  |  | 
|  | static inline void put_nsproxy(struct nsproxy *ns) | 
|  | { | 
|  | if (atomic_dec_and_test(&ns->count)) { | 
|  | free_nsproxy(ns); | 
|  | } | 
|  | } | 
|  |  | 
|  | static inline void get_nsproxy(struct nsproxy *ns) | 
|  | { | 
|  | atomic_inc(&ns->count); | 
|  | } | 
|  |  | 
|  | #endif |