Messages in this thread Patch in this message | | | Date | Thu, 20 Nov 2008 20:45:36 +0900 | From | Tejun Heo <> | Subject | [PATCH RESEND] char_dev: add cdev->release() and convert cdev_alloc() to use it |
| |
Add cdev->release() so that cdev can be considered in more involved object lifetime management. cdev_alloc() used a separate ktype for auto-free release(). This patch converts it to use cdev->release() so that there's no need for separate ktype and cdev_init() can be used for auto-free variant too.
Signed-off-by: Tejun Heo <tj@kernel.org> --- fs/char_dev.c | 30 +++++++++++++----------------- include/linux/cdev.h | 1 + 2 files changed, 14 insertions(+), 17 deletions(-)
Index: work/fs/char_dev.c =================================================================== --- work.orig/fs/char_dev.c +++ work/fs/char_dev.c @@ -482,26 +482,22 @@ void cdev_del(struct cdev *p) } -static void cdev_default_release(struct kobject *kobj) +static void cdev_release(struct kobject *kobj) { struct cdev *p = container_of(kobj, struct cdev, kobj); cdev_purge(p); + if (p->release) + p->release(p); } -static void cdev_dynamic_release(struct kobject *kobj) -{ - struct cdev *p = container_of(kobj, struct cdev, kobj); - cdev_purge(p); - kfree(p); -} - -static struct kobj_type ktype_cdev_default = { - .release = cdev_default_release, +static struct kobj_type cdev_ktype = { + .release = cdev_release, }; -static struct kobj_type ktype_cdev_dynamic = { - .release = cdev_dynamic_release, -}; +static void cdev_alloc_release(struct cdev *cdev) +{ + kfree(cdev); +} /** * cdev_alloc() - allocate a cdev structure @@ -510,10 +506,10 @@ static struct kobj_type ktype_cdev_dynam */ struct cdev *cdev_alloc(void) { - struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); + struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { - INIT_LIST_HEAD(&p->list); - kobject_init(&p->kobj, &ktype_cdev_dynamic); + cdev_init(p, NULL); + p->release = cdev_alloc_release; } return p; } @@ -530,7 +526,7 @@ void cdev_init(struct cdev *cdev, const { memset(cdev, 0, sizeof *cdev); INIT_LIST_HEAD(&cdev->list); - kobject_init(&cdev->kobj, &ktype_cdev_default); + kobject_init(&cdev->kobj, &cdev_ktype); cdev->ops = fops; } Index: work/include/linux/cdev.h =================================================================== --- work.orig/include/linux/cdev.h +++ work/include/linux/cdev.h @@ -16,6 +16,7 @@ struct cdev { struct list_head list; dev_t dev; unsigned int count; + void (*release)(struct cdev *); }; void cdev_init(struct cdev *, const struct file_operations *);
| |