diff options
Diffstat (limited to 'include/linux/ns_common.h')
| -rw-r--r-- | include/linux/ns_common.h | 139 | 
1 files changed, 138 insertions, 1 deletions
diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 7d22ea50b098..f5b68b8abb54 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -3,14 +3,151 @@  #define _LINUX_NS_COMMON_H  #include <linux/refcount.h> +#include <linux/rbtree.h> +#include <uapi/linux/sched.h>  struct proc_ns_operations; +struct cgroup_namespace; +struct ipc_namespace; +struct mnt_namespace; +struct net; +struct pid_namespace; +struct time_namespace; +struct user_namespace; +struct uts_namespace; + +extern struct cgroup_namespace init_cgroup_ns; +extern struct ipc_namespace init_ipc_ns; +extern struct mnt_namespace init_mnt_ns; +extern struct net init_net; +extern struct pid_namespace init_pid_ns; +extern struct time_namespace init_time_ns; +extern struct user_namespace init_user_ns; +extern struct uts_namespace init_uts_ns; + +extern const struct proc_ns_operations netns_operations; +extern const struct proc_ns_operations utsns_operations; +extern const struct proc_ns_operations ipcns_operations; +extern const struct proc_ns_operations pidns_operations; +extern const struct proc_ns_operations pidns_for_children_operations; +extern const struct proc_ns_operations userns_operations; +extern const struct proc_ns_operations mntns_operations; +extern const struct proc_ns_operations cgroupns_operations; +extern const struct proc_ns_operations timens_operations; +extern const struct proc_ns_operations timens_for_children_operations; +  struct ns_common { +	u32 ns_type;  	struct dentry *stashed;  	const struct proc_ns_operations *ops;  	unsigned int inum; -	refcount_t count; +	refcount_t __ns_ref; /* do not use directly */ +	union { +		struct { +			u64 ns_id; +			struct rb_node ns_tree_node; +			struct list_head ns_list_node; +		}; +		struct rcu_head ns_rcu; +	};  }; +int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_operations *ops, int inum); +void __ns_common_free(struct ns_common *ns); + +#define to_ns_common(__ns)                                    \ +	_Generic((__ns),                                      \ +		struct cgroup_namespace *:       &(__ns)->ns, \ +		const struct cgroup_namespace *: &(__ns)->ns, \ +		struct ipc_namespace *:          &(__ns)->ns, \ +		const struct ipc_namespace *:    &(__ns)->ns, \ +		struct mnt_namespace *:          &(__ns)->ns, \ +		const struct mnt_namespace *:    &(__ns)->ns, \ +		struct net *:                    &(__ns)->ns, \ +		const struct net *:              &(__ns)->ns, \ +		struct pid_namespace *:          &(__ns)->ns, \ +		const struct pid_namespace *:    &(__ns)->ns, \ +		struct time_namespace *:         &(__ns)->ns, \ +		const struct time_namespace *:   &(__ns)->ns, \ +		struct user_namespace *:         &(__ns)->ns, \ +		const struct user_namespace *:   &(__ns)->ns, \ +		struct uts_namespace *:          &(__ns)->ns, \ +		const struct uts_namespace *:    &(__ns)->ns) + +#define ns_init_inum(__ns)                                     \ +	_Generic((__ns),                                       \ +		struct cgroup_namespace *: CGROUP_NS_INIT_INO, \ +		struct ipc_namespace *:    IPC_NS_INIT_INO,    \ +		struct mnt_namespace *:    MNT_NS_INIT_INO,    \ +		struct net *:              NET_NS_INIT_INO,    \ +		struct pid_namespace *:    PID_NS_INIT_INO,    \ +		struct time_namespace *:   TIME_NS_INIT_INO,   \ +		struct user_namespace *:   USER_NS_INIT_INO,   \ +		struct uts_namespace *:    UTS_NS_INIT_INO) + +#define ns_init_ns(__ns)                                    \ +	_Generic((__ns),                                    \ +		struct cgroup_namespace *: &init_cgroup_ns, \ +		struct ipc_namespace *:    &init_ipc_ns,    \ +		struct mnt_namespace *:    &init_mnt_ns,     \ +		struct net *:              &init_net,       \ +		struct pid_namespace *:    &init_pid_ns,    \ +		struct time_namespace *:   &init_time_ns,   \ +		struct user_namespace *:   &init_user_ns,   \ +		struct uts_namespace *:    &init_uts_ns) + +#define to_ns_operations(__ns)                                                                         \ +	_Generic((__ns),                                                                               \ +		struct cgroup_namespace *: (IS_ENABLED(CONFIG_CGROUPS) ? &cgroupns_operations : NULL), \ +		struct ipc_namespace *:    (IS_ENABLED(CONFIG_IPC_NS)  ? &ipcns_operations    : NULL), \ +		struct mnt_namespace *:    &mntns_operations,                                          \ +		struct net *:              (IS_ENABLED(CONFIG_NET_NS)  ? &netns_operations    : NULL), \ +		struct pid_namespace *:    (IS_ENABLED(CONFIG_PID_NS)  ? &pidns_operations    : NULL), \ +		struct time_namespace *:   (IS_ENABLED(CONFIG_TIME_NS) ? &timens_operations   : NULL), \ +		struct user_namespace *:   (IS_ENABLED(CONFIG_USER_NS) ? &userns_operations   : NULL), \ +		struct uts_namespace *:    (IS_ENABLED(CONFIG_UTS_NS)  ? &utsns_operations    : NULL)) + +#define ns_common_type(__ns)                                \ +	_Generic((__ns),                                    \ +		struct cgroup_namespace *: CLONE_NEWCGROUP, \ +		struct ipc_namespace *:    CLONE_NEWIPC,    \ +		struct mnt_namespace *:    CLONE_NEWNS,     \ +		struct net *:              CLONE_NEWNET,    \ +		struct pid_namespace *:    CLONE_NEWPID,    \ +		struct time_namespace *:   CLONE_NEWTIME,   \ +		struct user_namespace *:   CLONE_NEWUSER,   \ +		struct uts_namespace *:    CLONE_NEWUTS) + +#define ns_common_init(__ns)                     \ +	__ns_common_init(to_ns_common(__ns),     \ +			 ns_common_type(__ns),   \ +			 to_ns_operations(__ns), \ +			 (((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0)) + +#define ns_common_init_inum(__ns, __inum)        \ +	__ns_common_init(to_ns_common(__ns),     \ +			 ns_common_type(__ns),   \ +			 to_ns_operations(__ns), \ +			 __inum) + +#define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns))) + +static __always_inline __must_check bool __ns_ref_put(struct ns_common *ns) +{ +	return refcount_dec_and_test(&ns->__ns_ref); +} + +static __always_inline __must_check bool __ns_ref_get(struct ns_common *ns) +{ +	return refcount_inc_not_zero(&ns->__ns_ref); +} + +#define ns_ref_read(__ns) refcount_read(&to_ns_common((__ns))->__ns_ref) +#define ns_ref_inc(__ns) refcount_inc(&to_ns_common((__ns))->__ns_ref) +#define ns_ref_get(__ns) __ns_ref_get(to_ns_common((__ns))) +#define ns_ref_put(__ns) __ns_ref_put(to_ns_common((__ns))) +#define ns_ref_put_and_lock(__ns, __lock) \ +	refcount_dec_and_lock(&to_ns_common((__ns))->__ns_ref, (__lock)) +  #endif  | 
