diff options
author | Hans de Goede <hdegoede@redhat.com> | 2010-12-30 18:00:17 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-01-19 08:44:55 -0500 |
commit | 4a82bc60a9abbfca0c899366ff30c592e8020520 (patch) | |
tree | 3821b98f8a5b92d09b56f448ea33e195e19cbeeb /drivers/media | |
parent | 27074efa2ee8c1ef07dc5f644104e35d39e43322 (diff) |
[media] gspca_main: Update buffer flags even when user_copy fails
Before this patch dqbuf errors out on a failing user_copy (with user pointers)
before updating the buffer flags, causing a successsfully dequeued buffer
to still have the DONE flag, which means that it could no longer be
re-queueud (assuming the app somehow survives the segfault).
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 64ecf669d655..fbc5666ee29e 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -1912,6 +1912,11 @@ static int vidioc_dqbuf(struct file *file, void *priv, | |||
1912 | mutex_unlock(&gspca_dev->usb_lock); | 1912 | mutex_unlock(&gspca_dev->usb_lock); |
1913 | } | 1913 | } |
1914 | 1914 | ||
1915 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; | ||
1916 | memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); | ||
1917 | PDEBUG(D_FRAM, "dqbuf %d", j); | ||
1918 | ret = 0; | ||
1919 | |||
1915 | if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { | 1920 | if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { |
1916 | if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, | 1921 | if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, |
1917 | frame->data, | 1922 | frame->data, |
@@ -1919,13 +1924,8 @@ static int vidioc_dqbuf(struct file *file, void *priv, | |||
1919 | PDEBUG(D_ERR|D_STREAM, | 1924 | PDEBUG(D_ERR|D_STREAM, |
1920 | "dqbuf cp to user failed"); | 1925 | "dqbuf cp to user failed"); |
1921 | ret = -EFAULT; | 1926 | ret = -EFAULT; |
1922 | goto out; | ||
1923 | } | 1927 | } |
1924 | } | 1928 | } |
1925 | frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; | ||
1926 | memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); | ||
1927 | PDEBUG(D_FRAM, "dqbuf %d", j); | ||
1928 | ret = 0; | ||
1929 | out: | 1929 | out: |
1930 | mutex_unlock(&gspca_dev->queue_lock); | 1930 | mutex_unlock(&gspca_dev->queue_lock); |
1931 | return ret; | 1931 | return ret; |