[RFC PATCH 06/26] tm6000: remove V4L2_FL_LOCK_ALL_FOPS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hans Verkuil <hans.verkuil@xxxxxxxxx>

Add proper locking to the file operations, allowing for the removal
of the V4L2_FL_LOCK_ALL_FOPS flag.

Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
---
 drivers/media/video/tm6000/tm6000-video.c |   52 ++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 9 deletions(-)

diff --git a/drivers/media/video/tm6000/tm6000-video.c b/drivers/media/video/tm6000/tm6000-video.c
index f7034df..45ed59c 100644
--- a/drivers/media/video/tm6000/tm6000-video.c
+++ b/drivers/media/video/tm6000/tm6000-video.c
@@ -1448,7 +1448,7 @@ static int radio_queryctrl(struct file *file, void *priv,
 	File operations for the device
    ------------------------------------------------------------------*/
 
-static int tm6000_open(struct file *file)
+static int __tm6000_open(struct file *file)
 {
 	struct video_device *vdev = video_devdata(file);
 	struct tm6000_core *dev = video_drvdata(file);
@@ -1540,23 +1540,41 @@ static int tm6000_open(struct file *file)
 	return 0;
 }
 
+static int tm6000_open(struct file *file)
+{
+	struct video_device *vdev = video_devdata(file);
+	int res;
+
+	mutex_lock(vdev->lock);
+	res = __tm6000_open(file);
+	mutex_unlock(vdev->lock);
+	return res;
+}
+
 static ssize_t
 tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos)
 {
-	struct tm6000_fh        *fh = file->private_data;
+	struct tm6000_fh *fh = file->private_data;
+	struct tm6000_core *dev = fh->dev;
 
 	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		int res;
+
 		if (!res_get(fh->dev, fh, true))
 			return -EBUSY;
 
-		return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
+		if (mutex_lock_interruptible(&dev->lock))
+			return -ERESTARTSYS;
+		res = videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0,
 					file->f_flags & O_NONBLOCK);
+		mutex_unlock(&dev->lock);
+		return res;
 	}
 	return 0;
 }
 
 static unsigned int
-tm6000_poll(struct file *file, struct poll_table_struct *wait)
+__tm6000_poll(struct file *file, struct poll_table_struct *wait)
 {
 	struct tm6000_fh        *fh = file->private_data;
 	struct tm6000_buffer    *buf;
@@ -1583,6 +1601,18 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait)
 	return 0;
 }
 
+static unsigned int tm6000_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct tm6000_fh *fh = file->private_data;
+	struct tm6000_core *dev = fh->dev;
+	unsigned int res;
+
+	mutex_lock(&dev->lock);
+	res = __tm6000_poll(file, wait);
+	mutex_unlock(&dev->lock);
+	return res;
+}
+
 static int tm6000_release(struct file *file)
 {
 	struct tm6000_fh         *fh = file->private_data;
@@ -1592,6 +1622,7 @@ static int tm6000_release(struct file *file)
 	dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: close called (dev=%s, users=%d)\n",
 		video_device_node_name(vdev), dev->users);
 
+	mutex_lock(&dev->lock);
 	dev->users--;
 
 	res_free(dev, fh);
@@ -1619,6 +1650,7 @@ static int tm6000_release(struct file *file)
 	}
 
 	kfree(fh);
+	mutex_unlock(&dev->lock);
 
 	return 0;
 }
@@ -1626,8 +1658,14 @@ static int tm6000_release(struct file *file)
 static int tm6000_mmap(struct file *file, struct vm_area_struct * vma)
 {
 	struct tm6000_fh *fh = file->private_data;
+	struct tm6000_core *dev = fh->dev;
+	int res;
 
-	return videobuf_mmap_mapper(&fh->vb_vidq, vma);
+	if (mutex_lock_interruptible(&dev->lock))
+		return -ERESTARTSYS;
+	res = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+	mutex_unlock(&dev->lock);
+	return res;
 }
 
 static struct v4l2_file_operations tm6000_fops = {
@@ -1724,10 +1762,6 @@ static struct video_device *vdev_init(struct tm6000_core *dev,
 	vfd->release = video_device_release;
 	vfd->debug = tm6000_debug;
 	vfd->lock = &dev->lock;
-	/* Locking in file operations other than ioctl should be done
-	   by the driver, not the V4L2 core.
-	   This driver needs auditing so that this flag can be removed. */
-	set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
 
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
 
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux