瀏覽代碼

V4L/DVB (7491): vivi: make vivi openable only once

vivi currently doesn't have the infrastructure to handle being opened more than
one time and will crash if it is.  So, make it openable only once.

Signed-off-by: Brandon Philips <bphilips@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Brandon Philips 17 年之前
父節點
當前提交
aa9dbac426
共有 1 個文件被更改,包括 18 次插入2 次删除
  1. 18 2
      drivers/media/video/vivi.c

+ 18 - 2
drivers/media/video/vivi.c

@@ -164,6 +164,7 @@ struct vivi_dev {
 
 
 	struct mutex               lock;
 	struct mutex               lock;
 	spinlock_t                 slock;
 	spinlock_t                 slock;
+	struct mutex		   mutex;
 
 
 	int                        users;
 	int                        users;
 
 
@@ -1036,6 +1037,7 @@ static int vivi_open(struct inode *inode, struct file *file)
 	struct vivi_dev *dev;
 	struct vivi_dev *dev;
 	struct vivi_fh *fh;
 	struct vivi_fh *fh;
 	int i;
 	int i;
+	int retval = 0;
 
 
 	printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
 	printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
 
 
@@ -1045,9 +1047,15 @@ static int vivi_open(struct inode *inode, struct file *file)
 	return -ENODEV;
 	return -ENODEV;
 
 
 found:
 found:
-	/* If more than one user, mutex should be added */
+	mutex_lock(&dev->mutex);
 	dev->users++;
 	dev->users++;
 
 
+	if (dev->users > 1) {
+		dev->users--;
+		retval = -EBUSY;
+		goto unlock;
+	}
+
 	dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
 	dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
 		v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
 		v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
 
 
@@ -1055,8 +1063,13 @@ found:
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
 	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
 	if (NULL == fh) {
 	if (NULL == fh) {
 		dev->users--;
 		dev->users--;
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto unlock;
 	}
 	}
+unlock:
+	mutex_unlock(&dev->mutex);
+	if (retval)
+		return retval;
 
 
 	file->private_data = fh;
 	file->private_data = fh;
 	fh->dev      = dev;
 	fh->dev      = dev;
@@ -1128,7 +1141,9 @@ static int vivi_close(struct inode *inode, struct file *file)
 
 
 	kfree(fh);
 	kfree(fh);
 
 
+	mutex_lock(&dev->mutex);
 	dev->users--;
 	dev->users--;
+	mutex_unlock(&dev->mutex);
 
 
 	dprintk(dev, 1, "close called (minor=%d, users=%d)\n",
 	dprintk(dev, 1, "close called (minor=%d, users=%d)\n",
 		minor, dev->users);
 		minor, dev->users);
@@ -1243,6 +1258,7 @@ static int __init vivi_init(void)
 		/* initialize locks */
 		/* initialize locks */
 		mutex_init(&dev->lock);
 		mutex_init(&dev->lock);
 		spin_lock_init(&dev->slock);
 		spin_lock_init(&dev->slock);
+		mutex_init(&dev->mutex);
 
 
 		dev->vidq.timeout.function = vivi_vid_timeout;
 		dev->vidq.timeout.function = vivi_vid_timeout;
 		dev->vidq.timeout.data     = (unsigned long)dev;
 		dev->vidq.timeout.data     = (unsigned long)dev;