The patch pertains to the source code of the video_open() function
in drivers/media/video/videodev.c in the linux 2.4.19 stable source.

In the original code of video_open() there are two small bugs:
(1) the counter of the module is not incremented _before_ the
    file->f_op->open(inode,file) function call, but only before
    the vfl->open() one.
(2) the increment of the variable vfl->users is incoherent with the
    decrement of the same variable in the function video_release().
    A brief analysis of the source code and of the patch reveals 
    that it is so, but i will not enter into details.

Since the bug was such that the author's intentions were 
incomprehensible, here are two alternative patches: either one or 
the other!

Infact, the bug (1) is fixed in the same way both in patch1 and 
in patch2, but there are two solutions of the bug (2):
a) patch1.diff: multiple video_open() of the same device are not 
   allowed.
b) patch2.diff: multiple opens are allowed when the new interface
   (struct file_operation*) is used; and multiple opens aren't 
   allowed when the old interface is used. See the comments.

The patches are given below (plain text, diff -u output).


Luca Risolia    <[EMAIL PROTECTED]>

 
******************* PATCH1.diff ***************************

--- drivers/media/video/videodev.c.orig Sat Nov  9 05:34:24 2002
+++ drivers/media/video/videodev.c      Sun Nov 10 12:52:30 2002
@@ -13,7 +13,9 @@
  *
  * Fixes:      20000516  Claudio Matsuoka <[EMAIL PROTECTED]>
  *             - Added procfs support
- */
+ *             20021109  Luca Risolia <[EMAIL PROTECTED]>
+ *             - Bug fix in video_open()
+*/
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -140,29 +142,38 @@
                        goto unlock_out;
                }
        }
+
+       /* Multiple opens are not allowed */
+       if(vfl->users) {
+               err = -EBUSY;
+               goto unlock_out;
+       }
+
+       if(vfl->owner)
+               __MOD_INC_USE_COUNT(vfl->owner);
+
+       /* In case every open call below sleep */
+       vfl->users++;
+
        if (vfl->fops) {
                struct file_
s = file->f_op;
                 file->f_op = fops_get(vfl->fops);
-                if(file->f_op->open)
+                if(file->f_op->open) {
                         err = file->f_op->open(inode,file);
-                if (err) {
-                        fops_put(file->f_op);
-                        file->f_op = fops_get(old_fops);
-                }
+                       if (err) {
+                               vfl->users--;
+                               if(vfl->owner)
+                                       __MOD_DEC_USE_COUNT(vfl->owner);
+                               fops_put(file->f_op);
+                               file->f_op = fops_get(old_fops);
+                       }
+               }
                 fops_put(old_fops);
                goto unlock_out;
        }
-       if(vfl->users) {
-               err = -EBUSY;
-               goto unlock_out;
-       }
-       vfl->users++;           /* In case vfl->open sleeps */
-       
-       if(vfl->owner)
-               __MOD_INC_USE_COUNT(vfl->owner);
-
+
        if (vfl->open) {
                err=vfl->open(vfl,0);   /* Tell the device it is open */
                if (err) {



********************* PATCH2.diff ***************************

--- drivers/media/video/videodev.c.orig Sat Nov  9 05:34:24 2002
+++ drivers/media/video/videodev.c      Sun Nov 10 12:52:56 2002
@@ -13,6 +13,8 @@
  *
  * Fixes:      20000516  Claudio Matsuoka <[EMAIL PROTECTED]>
  *             - Added procfs support
+ *             20021109  Luca Risolia <[EMAIL PROTECTED]>
+ *             - Bug fix in video_open()
  */

 #include <linux/config.h>
@@ -140,30 +142,39 @@
                        goto unlock_out;
                }
        }
+
+       if(vfl->owner)
+               __MOD_INC_USE_COUNT(vfl->owner);
+
+       /* New interface: multiple opens allowed */
        if (vfl->fops) {
                struct file_operations *old_fops;

                old_fops = file->f_op;
                 file->f_op = fops_get(vfl->fops);
-                if(file->f_op->open)
+                if(file->f_op->open) {
+                       vfl->users++;
                         err = file->f_op->open(inode,file);
-                if (err) {
-                        fops_put(file->f_op);
-                        file->f_op = fops_get(old_fops);
-                }
+                       if (err) {
+                               vfl->users-
OUNT(vfl->owner);
+                               fops_put(file->f_op);
+                               file->f_op = fops_get(old_fops);
+                       }
+               }
                 fops_put(old_fops);
                goto unlock_out;
        }
+
+       /* Old interface: just one open allowed */
        if(vfl->users) {
                err = -EBUSY;
                goto unlock_out;
        }
-       vfl->users++;           /* In case vfl->open sleeps */
-
-       if(vfl->owner)
-               __MOD_INC_USE_COUNT(vfl->owner);
-       
+
        if (vfl->open) {
+               vfl->users++;           /* In case vfl->open sleeps */
                err=vfl->open(vfl,0);   /* Tell the device it is open */
                if (err) {
                        vfl->users--;
@@ -173,7 +184,7 @@
                }
        }
        err = 0;
-
+
 unlock_out:
        up(&videodev_lock);
        return err;





--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@;redhat.com?subject=unsubscribe
https://listman.redhat.com/mailman/listinfo/video4linux-list

Reply via email to