diff options
Diffstat (limited to 'lib/kobject.c')
| -rw-r--r-- | lib/kobject.c | 34 | 
1 files changed, 31 insertions, 3 deletions
| diff --git a/lib/kobject.c b/lib/kobject.c index 4a1f33d43548..669bf190d4fb 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -545,8 +545,8 @@ static void kobject_cleanup(struct kobject *kobj)  	struct kobj_type *t = get_ktype(kobj);  	const char *name = kobj->name; -	pr_debug("kobject: '%s' (%p): %s\n", -		 kobject_name(kobj), kobj, __func__); +	pr_debug("kobject: '%s' (%p): %s, parent %p\n", +		 kobject_name(kobj), kobj, __func__, kobj->parent);  	if (t && !t->release)  		pr_debug("kobject: '%s' (%p): does not have a release() " @@ -580,9 +580,25 @@ static void kobject_cleanup(struct kobject *kobj)  	}  } +#ifdef CONFIG_DEBUG_KOBJECT_RELEASE +static void kobject_delayed_cleanup(struct work_struct *work) +{ +	kobject_cleanup(container_of(to_delayed_work(work), +				     struct kobject, release)); +} +#endif +  static void kobject_release(struct kref *kref)  { -	kobject_cleanup(container_of(kref, struct kobject, kref)); +	struct kobject *kobj = container_of(kref, struct kobject, kref); +#ifdef CONFIG_DEBUG_KOBJECT_RELEASE +	pr_debug("kobject: '%s' (%p): %s, parent %p (delayed)\n", +		 kobject_name(kobj), kobj, __func__, kobj->parent); +	INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); +	schedule_delayed_work(&kobj->release, HZ); +#else +	kobject_cleanup(kobj); +#endif  }  /** @@ -915,6 +931,18 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)  	return kobj_child_ns_ops(kobj->parent);  } +bool kobj_ns_current_may_mount(enum kobj_ns_type type) +{ +	bool may_mount = true; + +	spin_lock(&kobj_ns_type_lock); +	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && +	    kobj_ns_ops_tbl[type]) +		may_mount = kobj_ns_ops_tbl[type]->current_may_mount(); +	spin_unlock(&kobj_ns_type_lock); + +	return may_mount; +}  void *kobj_ns_grab_current(enum kobj_ns_type type)  { | 
