diff options
author | Ian Abbott | 2013-11-08 16:03:32 +0100 |
---|---|---|
committer | Greg Kroah-Hartman | 2013-11-12 01:16:44 +0100 |
commit | 5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540 (patch) | |
tree | 0bfade11593603377f28228a2db2ed13cdaa7b7a /drivers | |
parent | staging: comedi: protect against detach during read operation (diff) | |
download | kernel-qcow2-linux-5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540.tar.gz kernel-qcow2-linux-5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540.tar.xz kernel-qcow2-linux-5b13ed94a7d24fdc8abbac81e7e4d30ab22c6540.zip |
staging: comedi: add a kref to comedi device
Add a `struct kref refcount` member to `struct comedi_device` to allow
safe destruction of the comedi device. Only free the comedi device via
the 'release' callback `kref_put()`. Currently, nothing calls
`kref_put()`, so the safe destruction is ineffective, but this will be
addressed by later patches.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 22 | ||||
-rw-r--r-- | drivers/staging/comedi/comedidev.h | 2 |
2 files changed, 21 insertions, 3 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index fa8da20df753..403324c895b1 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -89,12 +89,29 @@ static struct cdev comedi_cdev; static void comedi_device_init(struct comedi_device *dev) { + kref_init(&dev->refcount); spin_lock_init(&dev->spinlock); mutex_init(&dev->mutex); init_rwsem(&dev->attach_lock); dev->minor = -1; } +static void comedi_dev_kref_release(struct kref *kref) +{ + struct comedi_device *dev = + container_of(kref, struct comedi_device, refcount); + + mutex_destroy(&dev->mutex); + kfree(dev); +} + +int comedi_dev_put(struct comedi_device *dev) +{ + if (dev) + return kref_put(&dev->refcount, comedi_dev_kref_release); + return 1; +} + static void comedi_device_cleanup(struct comedi_device *dev) { struct module *driver_module = NULL; @@ -112,7 +129,6 @@ static void comedi_device_cleanup(struct comedi_device *dev) dev->use_count--; } mutex_unlock(&dev->mutex); - mutex_destroy(&dev->mutex); } static bool comedi_clear_board_dev(struct comedi_device *dev) @@ -148,7 +164,7 @@ static void comedi_free_board_dev(struct comedi_device *dev) MKDEV(COMEDI_MAJOR, dev->minor)); } comedi_device_cleanup(dev); - kfree(dev); + comedi_dev_put(dev); } } @@ -2494,7 +2510,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) if (i == COMEDI_NUM_BOARD_MINORS) { mutex_unlock(&dev->mutex); comedi_device_cleanup(dev); - kfree(dev); + comedi_dev_put(dev); pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return ERR_PTR(-EBUSY); } diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 05cc8dbcd515..08652dfa8c03 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -23,6 +23,7 @@ #include <linux/mutex.h> #include <linux/spinlock_types.h> #include <linux/rwsem.h> +#include <linux/kref.h> #include "comedi.h" @@ -187,6 +188,7 @@ struct comedi_device { spinlock_t spinlock; struct mutex mutex; struct rw_semaphore attach_lock; + struct kref refcount; int n_subdevices; struct comedi_subdevice *subdevices; |