From 4e770f7602fb2285f3106f98109d0685618ddc22 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 30 Dec 2010 13:11:21 -0300 Subject: [PATCH] [media] gspca_main: Locking fixes 1 The gspca_dev->streaming boolean is protected against multiple access through gspca_dev->queue_lock everywhere except for 2 places. This patch fixes this by bringing it under the lock in vidioc_streamoff. And by removing the check for gspca_dev->streaming in gspca_disconnect, the destroy_urbs call may be called multiple times (and is protected by the usb_lock) and calling wake_up_interruptible can also always be done safely. Signed-off-by: Hans de Goede Acked-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 442970073e8a..74626b6a9eb4 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1630,11 +1630,15 @@ static int vidioc_streamoff(struct file *file, void *priv, if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (!gspca_dev->streaming) - return 0; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; + if (!gspca_dev->streaming) { + ret = 0; + goto out; + } + /* check the capture file */ if (gspca_dev->capt_file != file) { ret = -EBUSY; @@ -2341,12 +2345,11 @@ void gspca_disconnect(struct usb_interface *intf) PDEBUG(D_PROBE, "%s disconnect", video_device_node_name(&gspca_dev->vdev)); mutex_lock(&gspca_dev->usb_lock); - gspca_dev->present = 0; - if (gspca_dev->streaming) { - destroy_urbs(gspca_dev); - wake_up_interruptible(&gspca_dev->wq); - } + gspca_dev->present = 0; + wake_up_interruptible(&gspca_dev->wq); + + destroy_urbs(gspca_dev); #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) gspca_input_destroy_urb(gspca_dev);