Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at ee9dce44362b2d8132c32964656ab6dff7dfbc6a 152 lines 4.7 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _LINUX_NS_COMMON_H 3#define _LINUX_NS_COMMON_H 4 5#include <linux/ns/ns_common_types.h> 6#include <linux/refcount.h> 7#include <linux/vfsdebug.h> 8#include <uapi/linux/sched.h> 9#include <uapi/linux/nsfs.h> 10 11bool is_current_namespace(struct ns_common *ns); 12int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_operations *ops, int inum); 13void __ns_common_free(struct ns_common *ns); 14struct ns_common *__must_check ns_owner(struct ns_common *ns); 15 16static __always_inline bool is_ns_init_inum(const struct ns_common *ns) 17{ 18 VFS_WARN_ON_ONCE(ns->inum == 0); 19 return unlikely(in_range(ns->inum, MNT_NS_INIT_INO, 20 IPC_NS_INIT_INO - MNT_NS_INIT_INO + 1)); 21} 22 23static __always_inline bool is_ns_init_id(const struct ns_common *ns) 24{ 25 VFS_WARN_ON_ONCE(ns->ns_id == 0); 26 return ns->ns_id <= NS_LAST_INIT_ID; 27} 28 29#define NS_COMMON_INIT(nsname) \ 30{ \ 31 .ns_type = ns_common_type(&nsname), \ 32 .ns_id = ns_init_id(&nsname), \ 33 .inum = ns_init_inum(&nsname), \ 34 .ops = to_ns_operations(&nsname), \ 35 .stashed = NULL, \ 36 .__ns_ref = REFCOUNT_INIT(1), \ 37 .__ns_ref_active = ATOMIC_INIT(1), \ 38 .ns_unified_node.ns_list_entry = LIST_HEAD_INIT(nsname.ns.ns_unified_node.ns_list_entry), \ 39 .ns_tree_node.ns_list_entry = LIST_HEAD_INIT(nsname.ns.ns_tree_node.ns_list_entry), \ 40 .ns_owner_node.ns_list_entry = LIST_HEAD_INIT(nsname.ns.ns_owner_node.ns_list_entry), \ 41 .ns_owner_root.ns_list_head = LIST_HEAD_INIT(nsname.ns.ns_owner_root.ns_list_head), \ 42} 43 44#define ns_common_init(__ns) \ 45 __ns_common_init(to_ns_common(__ns), \ 46 ns_common_type(__ns), \ 47 to_ns_operations(__ns), \ 48 (((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0)) 49 50#define ns_common_init_inum(__ns, __inum) \ 51 __ns_common_init(to_ns_common(__ns), \ 52 ns_common_type(__ns), \ 53 to_ns_operations(__ns), \ 54 __inum) 55 56#define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns))) 57 58bool may_see_all_namespaces(void); 59 60static __always_inline __must_check int __ns_ref_active_read(const struct ns_common *ns) 61{ 62 return atomic_read(&ns->__ns_ref_active); 63} 64 65static __always_inline __must_check int __ns_ref_read(const struct ns_common *ns) 66{ 67 return refcount_read(&ns->__ns_ref); 68} 69 70static __always_inline __must_check bool __ns_ref_put(struct ns_common *ns) 71{ 72 if (is_ns_init_id(ns)) { 73 VFS_WARN_ON_ONCE(__ns_ref_read(ns) != 1); 74 VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) != 1); 75 return false; 76 } 77 if (refcount_dec_and_test(&ns->__ns_ref)) { 78 VFS_WARN_ON_ONCE(__ns_ref_active_read(ns)); 79 return true; 80 } 81 return false; 82} 83 84static __always_inline __must_check bool __ns_ref_get(struct ns_common *ns) 85{ 86 if (is_ns_init_id(ns)) { 87 VFS_WARN_ON_ONCE(__ns_ref_read(ns) != 1); 88 VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) != 1); 89 return true; 90 } 91 if (refcount_inc_not_zero(&ns->__ns_ref)) 92 return true; 93 VFS_WARN_ON_ONCE(__ns_ref_active_read(ns)); 94 return false; 95} 96 97static __always_inline void __ns_ref_inc(struct ns_common *ns) 98{ 99 if (is_ns_init_id(ns)) { 100 VFS_WARN_ON_ONCE(__ns_ref_read(ns) != 1); 101 VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) != 1); 102 return; 103 } 104 refcount_inc(&ns->__ns_ref); 105} 106 107static __always_inline __must_check bool __ns_ref_dec_and_lock(struct ns_common *ns, 108 spinlock_t *ns_lock) 109{ 110 if (is_ns_init_id(ns)) { 111 VFS_WARN_ON_ONCE(__ns_ref_read(ns) != 1); 112 VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) != 1); 113 return false; 114 } 115 return refcount_dec_and_lock(&ns->__ns_ref, ns_lock); 116} 117 118#define ns_ref_read(__ns) __ns_ref_read(to_ns_common((__ns))) 119#define ns_ref_inc(__ns) \ 120 do { if (__ns) __ns_ref_inc(to_ns_common((__ns))); } while (0) 121#define ns_ref_get(__ns) \ 122 ((__ns) ? __ns_ref_get(to_ns_common((__ns))) : false) 123#define ns_ref_put(__ns) \ 124 ((__ns) ? __ns_ref_put(to_ns_common((__ns))) : false) 125#define ns_ref_put_and_lock(__ns, __ns_lock) \ 126 ((__ns) ? __ns_ref_dec_and_lock(to_ns_common((__ns)), __ns_lock) : false) 127 128#define ns_ref_active_read(__ns) \ 129 ((__ns) ? __ns_ref_active_read(to_ns_common(__ns)) : 0) 130 131void __ns_ref_active_put(struct ns_common *ns); 132 133#define ns_ref_active_put(__ns) \ 134 do { if (__ns) __ns_ref_active_put(to_ns_common(__ns)); } while (0) 135 136static __always_inline struct ns_common *__must_check ns_get_unless_inactive(struct ns_common *ns) 137{ 138 if (!__ns_ref_active_read(ns)) { 139 VFS_WARN_ON_ONCE(is_ns_init_id(ns)); 140 return NULL; 141 } 142 if (!__ns_ref_get(ns)) 143 return NULL; 144 return ns; 145} 146 147void __ns_ref_active_get(struct ns_common *ns); 148 149#define ns_ref_active_get(__ns) \ 150 do { if (__ns) __ns_ref_active_get(to_ns_common(__ns)); } while (0) 151 152#endif