Delay struct net freeing while there's a sysfs instance refering to it

* new refcount in struct net, controlling actual freeing of the memory
	* new method in kobj_ns_type_operations (->drop_ns())
	* ->current_ns() semantics change - it's supposed to be followed by
corresponding ->drop_ns().  For struct net in case of CONFIG_NET_NS it bumps
the new refcount; net_drop_ns() decrements it and calls net_free() if the
last reference has been dropped.  Method renamed to ->grab_current_ns().
	* old net_free() callers call net_drop_ns() instead.
	* sysfs_exit_ns() is gone, along with a large part of callchain
leading to it; now that the references stored in ->ns[...] stay valid we
do not need to hunt them down and replace them with NULL.  That fixes
problems in sysfs_lookup() and sysfs_readdir(), along with getting rid
of sb->s_instances abuse.

	Note that struct net *shutdown* logics has not changed - net_cleanup()
is called exactly when it used to be called.  The only thing postponed by
having a sysfs instance refering to that struct net is actual freeing of
memory occupied by struct net.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Этот коммит содержится в:
Al Viro
2011-06-08 21:13:01 -04:00
родитель dde194a64b
Коммит a685e08987
8 изменённых файлов: 55 добавлений и 72 удалений

Просмотреть файл

@@ -948,14 +948,14 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
}
const void *kobj_ns_current(enum kobj_ns_type type)
void *kobj_ns_grab_current(enum kobj_ns_type type)
{
const void *ns = NULL;
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();
ns = kobj_ns_ops_tbl[type]->grab_current_ns();
spin_unlock(&kobj_ns_type_lock);
return ns;
@@ -987,23 +987,15 @@ const void *kobj_ns_initial(enum kobj_ns_type type)
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)
void kobj_ns_drop(enum kobj_ns_type type, void *ns)
{
sysfs_exit_ns(type, ns);
spin_lock(&kobj_ns_type_lock);
if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns)
kobj_ns_ops_tbl[type]->drop_ns(ns);
spin_unlock(&kobj_ns_type_lock);
}
EXPORT_SYMBOL(kobject_get);
EXPORT_SYMBOL(kobject_put);
EXPORT_SYMBOL(kobject_del);