SLUB: Fix sysfs refcounting

If CONFIG_SYSFS is set then free the kmem_cache structure when
sysfs tells us its okay.

Otherwise there is the danger (as pointed out by
Al Viro) that sysfs thinks the kobject still exists after
kmem_cache_destroy() removed it.

Signed-off-by: Christoph Lameter <clameter@sgi.com>
Reviewed-by: Pekka J Enberg <penberg@cs.helsinki.fi>
This commit is contained in:
Christoph Lameter 2008-01-07 22:29:05 -08:00
parent e374d48356
commit 151c602f79

View file

@ -247,7 +247,10 @@ static void sysfs_slab_remove(struct kmem_cache *);
static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; } static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; }
static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p) static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p)
{ return 0; } { return 0; }
static inline void sysfs_slab_remove(struct kmem_cache *s) {} static inline void sysfs_slab_remove(struct kmem_cache *s)
{
kfree(s);
}
#endif #endif
/******************************************************************** /********************************************************************
@ -2322,7 +2325,6 @@ void kmem_cache_destroy(struct kmem_cache *s)
if (kmem_cache_close(s)) if (kmem_cache_close(s))
WARN_ON(1); WARN_ON(1);
sysfs_slab_remove(s); sysfs_slab_remove(s);
kfree(s);
} else } else
up_write(&slub_lock); up_write(&slub_lock);
} }
@ -3937,6 +3939,13 @@ static ssize_t slab_attr_store(struct kobject *kobj,
return err; return err;
} }
static void kmem_cache_release(struct kobject *kobj)
{
struct kmem_cache *s = to_slab(kobj);
kfree(s);
}
static struct sysfs_ops slab_sysfs_ops = { static struct sysfs_ops slab_sysfs_ops = {
.show = slab_attr_show, .show = slab_attr_show,
.store = slab_attr_store, .store = slab_attr_store,
@ -3944,6 +3953,7 @@ static struct sysfs_ops slab_sysfs_ops = {
static struct kobj_type slab_ktype = { static struct kobj_type slab_ktype = {
.sysfs_ops = &slab_sysfs_ops, .sysfs_ops = &slab_sysfs_ops,
.release = kmem_cache_release
}; };
static int uevent_filter(struct kset *kset, struct kobject *kobj) static int uevent_filter(struct kset *kset, struct kobject *kobj)
@ -4045,6 +4055,7 @@ static void sysfs_slab_remove(struct kmem_cache *s)
{ {
kobject_uevent(&s->kobj, KOBJ_REMOVE); kobject_uevent(&s->kobj, KOBJ_REMOVE);
kobject_del(&s->kobj); kobject_del(&s->kobj);
kobject_put(&s->kobj);
} }
/* /*