From: Laurent Pinchart <laurent.pinch...@ideasonboard.com>

The ivtv driver has a structure named ivtv_open_id that models an open
file handle for the device. It embeds a v4l2_fh instance for file
handles that correspond to a V4L2 video device, and stores a pointer to
that v4l2_fh in struct ivtv_stream to identify which open file handle
owns a particular stream.

In addition to video devices, streams can be owned by ALSA PCM devices.
Those devices do not make use of the v4l2_fh instance for obvious
reasons, but the snd_ivtv_pcm_capture_open() function still initializes
a "fake" v4l2_fh for the sole purpose of using it as an open file handle
identifier. The v4l2_fh is not properly destroyed when the ALSA PCM
device is closed, leading to possible resource leaks.

Fortunately, the v4l2_fh instance pointed to by ivtv_stream is not
accessed, only the pointer value is used for comparison. Replace it with
a pointer to the ivtv_open_id structure that embeds the v4l2_fh, and
don't initialize the v4l2_fh for ALSA PCM devices.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo.mo...@ideasonboard.com>
---
 drivers/media/pci/ivtv/ivtv-alsa-pcm.c |  2 --
 drivers/media/pci/ivtv/ivtv-driver.h   |  3 ++-
 drivers/media/pci/ivtv/ivtv-fileops.c  | 18 +++++++++---------
 drivers/media/pci/ivtv/ivtv-irq.c      |  4 ++--
 4 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c 
b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
index 
8f346d7da9c8defb12191c3addb12a118547b9a0..269a799ec046c67265484945acf89a5fbd40a3f4
 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.c
@@ -148,14 +148,12 @@ static int snd_ivtv_pcm_capture_open(struct 
snd_pcm_substream *substream)
 
        s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
 
-       v4l2_fh_init(&item.fh, &s->vdev);
        item.itv = itv;
        item.type = s->type;
 
        /* See if the stream is available */
        if (ivtv_claim_stream(&item, item.type)) {
                /* No, it's already in use */
-               v4l2_fh_exit(&item.fh);
                snd_ivtv_unlock(itvsc);
                return -EBUSY;
        }
diff --git a/drivers/media/pci/ivtv/ivtv-driver.h 
b/drivers/media/pci/ivtv/ivtv-driver.h
index 
cad548b28e360ecfe2bcb9fcb5d12cd8823c3727..38c4ceb04cf834906ed877b57c20fcbdb390da13
 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.h
+++ b/drivers/media/pci/ivtv/ivtv-driver.h
@@ -322,6 +322,7 @@ struct ivtv_queue {
 };
 
 struct ivtv;                           /* forward reference */
+struct ivtv_open_id;
 
 struct ivtv_stream {
        /* These first four fields are always set, even if the stream
@@ -331,7 +332,7 @@ struct ivtv_stream {
        const char *name;               /* name of the stream */
        int type;                       /* stream type */
 
-       struct v4l2_fh *fh;             /* pointer to the streaming filehandle 
*/
+       struct ivtv_open_id *id;        /* pointer to the streaming 
ivtv_open_id */
        spinlock_t qlock;               /* locks access to the queues */
        unsigned long s_flags;          /* status flags, see above */
        int dma;                        /* can be PCI_DMA_TODEVICE, 
PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c 
b/drivers/media/pci/ivtv/ivtv-fileops.c
index 
cc91695a5b7605dcd964bd2c68bb12f645dc302f..67964a3c382c6627a7b3ce6380a2da97dcc47c3d
 100644
--- a/drivers/media/pci/ivtv/ivtv-fileops.c
+++ b/drivers/media/pci/ivtv/ivtv-fileops.c
@@ -39,16 +39,16 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
 
        if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
                /* someone already claimed this stream */
-               if (s->fh == &id->fh) {
+               if (s->id == id) {
                        /* yes, this file descriptor did. So that's OK. */
                        return 0;
                }
-               if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
+               if (s->id == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
                                         type == IVTV_ENC_STREAM_TYPE_VBI)) {
                        /* VBI is handled already internally, now also assign
                           the file descriptor to this stream for external
                           reading of the stream. */
-                       s->fh = &id->fh;
+                       s->id = id;
                        IVTV_DEBUG_INFO("Start Read VBI\n");
                        return 0;
                }
@@ -56,7 +56,7 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type)
                IVTV_DEBUG_INFO("Stream %d is busy\n", type);
                return -EBUSY;
        }
-       s->fh = &id->fh;
+       s->id = id;
        if (type == IVTV_DEC_STREAM_TYPE_VBI) {
                /* Enable reinsertion interrupt */
                ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
@@ -94,7 +94,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
        struct ivtv *itv = s->itv;
        struct ivtv_stream *s_vbi;
 
-       s->fh = NULL;
+       s->id = NULL;
        if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == 
IVTV_ENC_STREAM_TYPE_VBI) &&
                test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
                /* this stream is still in use internally */
@@ -126,7 +126,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
                /* was already cleared */
                return;
        }
-       if (s_vbi->fh) {
+       if (s_vbi->id) {
                /* VBI stream still claimed by a file descriptor */
                return;
        }
@@ -359,7 +359,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user 
*ubuf, size_t tot_co
        size_t tot_written = 0;
        int single_frame = 0;
 
-       if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
+       if (atomic_read(&itv->capturing) == 0 && s->id == NULL) {
                /* shouldn't happen */
                IVTV_DEBUG_WARN("Stream %s not initialized before read\n", 
s->name);
                return -EIO;
@@ -831,7 +831,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
                     id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
                    test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
                        /* Also used internally, don't stop capturing */
-                       s->fh = NULL;
+                       s->id = NULL;
                }
                else {
                        ivtv_stop_v4l2_encode_stream(s, gop_end);
@@ -915,7 +915,7 @@ int ivtv_v4l2_close(struct file *filp)
        v4l2_fh_exit(fh);
 
        /* Easy case first: this stream was never claimed by us */
-       if (s->fh != &id->fh)
+       if (s->id != id)
                goto close_done;
 
        /* 'Unclaim' this stream */
diff --git a/drivers/media/pci/ivtv/ivtv-irq.c 
b/drivers/media/pci/ivtv/ivtv-irq.c
index 
748c14e879632ae6f62c3cc1981a168b01ed060d..20ba5ae9c6d1d0e6e4d856d1f083e30a0f9be321
 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.c
+++ b/drivers/media/pci/ivtv/ivtv-irq.c
@@ -305,7 +305,7 @@ static void dma_post(struct ivtv_stream *s)
                        ivtv_process_vbi_data(itv, buf, 0, s->type);
                        s->q_dma.bytesused += buf->bytesused;
                }
-               if (s->fh == NULL) {
+               if (s->id == NULL) {
                        ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
                        return;
                }
@@ -330,7 +330,7 @@ static void dma_post(struct ivtv_stream *s)
                set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
        }
 
-       if (s->fh)
+       if (s->id)
                wake_up(&s->waitq);
 }
 

-- 
2.49.0



_______________________________________________
Mjpeg-users mailing list
Mjpeg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mjpeg-users

Reply via email to