diff options
Diffstat (limited to 'lib/kobject.c')
| -rw-r--r-- | lib/kobject.c | 115 | 
1 files changed, 115 insertions, 0 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index 8115eb1bbf4d..f07c57252e82 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -850,6 +850,121 @@ struct kset *kset_create_and_add(const char *name,  }  EXPORT_SYMBOL_GPL(kset_create_and_add); + +static DEFINE_SPINLOCK(kobj_ns_type_lock); +static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES]; + +int kobj_ns_type_register(const struct kobj_ns_type_operations *ops) +{ +	enum kobj_ns_type type = ops->type; +	int error; + +	spin_lock(&kobj_ns_type_lock); + +	error = -EINVAL; +	if (type >= KOBJ_NS_TYPES) +		goto out; + +	error = -EINVAL; +	if (type <= KOBJ_NS_TYPE_NONE) +		goto out; + +	error = -EBUSY; +	if (kobj_ns_ops_tbl[type]) +		goto out; + +	error = 0; +	kobj_ns_ops_tbl[type] = ops; + +out: +	spin_unlock(&kobj_ns_type_lock); +	return error; +} + +int kobj_ns_type_registered(enum kobj_ns_type type) +{ +	int registered = 0; + +	spin_lock(&kobj_ns_type_lock); +	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES)) +		registered = kobj_ns_ops_tbl[type] != NULL; +	spin_unlock(&kobj_ns_type_lock); + +	return registered; +} + +const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent) +{ +	const struct kobj_ns_type_operations *ops = NULL; + +	if (parent && parent->ktype->child_ns_type) +		ops = parent->ktype->child_ns_type(parent); + +	return ops; +} + +const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj) +{ +	return kobj_child_ns_ops(kobj->parent); +} + + +const void *kobj_ns_current(enum kobj_ns_type type) +{ +	const void *ns = NULL; + +	spin_lock(&kobj_ns_type_lock); +	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && +	    kobj_ns_ops_tbl[type]) +		ns = kobj_ns_ops_tbl[type]->current_ns(); +	spin_unlock(&kobj_ns_type_lock); + +	return ns; +} + +const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk) +{ +	const void *ns = NULL; + +	spin_lock(&kobj_ns_type_lock); +	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && +	    kobj_ns_ops_tbl[type]) +		ns = kobj_ns_ops_tbl[type]->netlink_ns(sk); +	spin_unlock(&kobj_ns_type_lock); + +	return ns; +} + +const void *kobj_ns_initial(enum kobj_ns_type type) +{ +	const void *ns = NULL; + +	spin_lock(&kobj_ns_type_lock); +	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && +	    kobj_ns_ops_tbl[type]) +		ns = kobj_ns_ops_tbl[type]->initial_ns(); +	spin_unlock(&kobj_ns_type_lock); + +	return ns; +} + +/* + * kobj_ns_exit - invalidate a namespace tag + * + * @type: the namespace type (i.e. KOBJ_NS_TYPE_NET) + * @ns: the actual namespace being invalidated + * + * This is called when a tag is no longer valid.  For instance, + * when a network namespace exits, it uses this helper to + * make sure no sb's sysfs_info points to the now-invalidated + * netns. + */ +void kobj_ns_exit(enum kobj_ns_type type, const void *ns) +{ +	sysfs_exit_ns(type, ns); +} + +  EXPORT_SYMBOL(kobject_get);  EXPORT_SYMBOL(kobject_put);  EXPORT_SYMBOL(kobject_del);  | 
