From 2c4aaa1fffe8d01c621e2515cd5f290227949e71 Mon Sep 17 00:00:00 2001 From: Andrey Shvetsov Date: Fri, 7 Apr 2017 15:38:37 +0200 Subject: [PATCH] staging: most: destroy cdev when channel gets disconnected When a channel is being removed while an application holds the corresponding character device, this device is going to be destroyed only after the application closes the file descriptor and releases character device. In case the channel appears again before the application closes the file descriptor it holds, the channel cannot be linked. This patch changes the described behavior and destroys the character device at the time the channel get disconnected from the AIM. Signed-off-by: Andrey Shvetsov Signed-off-by: Christian Gromm Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/aim-cdev/cdev.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index 7f51024dc5eb..1e5cbc893496 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/aim-cdev/cdev.c @@ -99,11 +99,16 @@ static void destroy_cdev(struct aim_channel *c) device_destroy(aim_class, c->devno); cdev_del(&c->cdev); - kfifo_free(&c->fifo); spin_lock_irqsave(&ch_list_lock, flags); list_del(&c->list); spin_unlock_irqrestore(&ch_list_lock, flags); +} + +static void destroy_channel(struct aim_channel *c) +{ ida_simple_remove(&minor_id, MINOR(c->devno)); + kfifo_free(&c->fifo); + kfree(c); } /** @@ -170,9 +175,8 @@ static int aim_close(struct inode *inode, struct file *filp) stop_channel(c); mutex_unlock(&c->io_mutex); } else { - destroy_cdev(c); mutex_unlock(&c->io_mutex); - kfree(c); + destroy_channel(c); } return 0; } @@ -337,14 +341,14 @@ static int aim_disconnect_channel(struct most_interface *iface, int channel_id) spin_lock(&c->unlink); c->dev = NULL; spin_unlock(&c->unlink); + destroy_cdev(c); if (c->access_ref) { stop_channel(c); wake_up_interruptible(&c->wq); mutex_unlock(&c->io_mutex); } else { - destroy_cdev(c); mutex_unlock(&c->io_mutex); - kfree(c); + destroy_channel(c); } return 0; } @@ -546,7 +550,7 @@ static void __exit mod_exit(void) list_for_each_entry_safe(c, tmp, &channel_list, list) { destroy_cdev(c); - kfree(c); + destroy_channel(c); } class_destroy(aim_class); unregister_chrdev_region(aim_devno, 1); -- 2.20.1