qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Cody <jcody@redhat.com>
To: qemu-block@nongnu.org
Cc: peter.maydell@linaro.org, jcody@redhat.com,
	qemu-devel@nongnu.org, stefanha@redhat.com
Subject: [Qemu-devel] [PULL for-2.8 12/13] block/curl: Do not wait for data beyond EOF
Date: Mon, 14 Nov 2016 23:14:50 -0500	[thread overview]
Message-ID: <1479183291-14086-13-git-send-email-jcody@redhat.com> (raw)
In-Reply-To: <1479183291-14086-1-git-send-email-jcody@redhat.com>

From: Max Reitz <mreitz@redhat.com>

libcurl will only give us as much data as there is, not more. The block
layer will deny requests beyond the end of file for us; but since this
block driver is still using a sector-based interface, we can still get
in trouble if the file size is not a multiple of 512.

While we have already made sure not to attempt transfers beyond the end
of the file, we are currently still trying to receive data from there if
the original request exceeds the file size. This patch fixes this issue
and invokes qemu_iovec_memset() on the iovec's tail.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20161025025431.24714-5-mreitz@redhat.com
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 block/curl.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 273f329..0404c1b 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -252,8 +252,17 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
             continue;
 
         if ((s->buf_off >= acb->end)) {
+            size_t request_length = acb->nb_sectors * BDRV_SECTOR_SIZE;
+
             qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
                                 acb->end - acb->start);
+
+            if (acb->end - acb->start < request_length) {
+                size_t offset = acb->end - acb->start;
+                qemu_iovec_memset(acb->qiov, offset, 0,
+                                  request_length - offset);
+            }
+
             acb->common.cb(acb->common.opaque, 0);
             qemu_aio_unref(acb);
             s->acb[i] = NULL;
@@ -270,6 +279,8 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
 {
     int i;
     size_t end = start + len;
+    size_t clamped_end = MIN(end, s->len);
+    size_t clamped_len = clamped_end - start;
 
     for (i=0; i<CURL_NUM_STATES; i++) {
         CURLState *state = &s->states[i];
@@ -284,12 +295,15 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
         // Does the existing buffer cover our section?
         if ((start >= state->buf_start) &&
             (start <= buf_end) &&
-            (end >= state->buf_start) &&
-            (end <= buf_end))
+            (clamped_end >= state->buf_start) &&
+            (clamped_end <= buf_end))
         {
             char *buf = state->orig_buf + (start - state->buf_start);
 
-            qemu_iovec_from_buf(acb->qiov, 0, buf, len);
+            qemu_iovec_from_buf(acb->qiov, 0, buf, clamped_len);
+            if (clamped_len < len) {
+                qemu_iovec_memset(acb->qiov, clamped_len, 0, len - clamped_len);
+            }
             acb->common.cb(acb->common.opaque, 0);
 
             return FIND_RET_OK;
@@ -299,13 +313,13 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
         if (state->in_use &&
             (start >= state->buf_start) &&
             (start <= buf_fend) &&
-            (end >= state->buf_start) &&
-            (end <= buf_fend))
+            (clamped_end >= state->buf_start) &&
+            (clamped_end <= buf_fend))
         {
             int j;
 
             acb->start = start - state->buf_start;
-            acb->end = acb->start + len;
+            acb->end = acb->start + clamped_len;
 
             for (j=0; j<CURL_NUM_ACB; j++) {
                 if (!state->acb[j]) {
@@ -798,13 +812,13 @@ static void curl_readv_bh_cb(void *p)
     }
 
     acb->start = 0;
-    acb->end = (acb->nb_sectors * BDRV_SECTOR_SIZE);
+    acb->end = MIN(acb->nb_sectors * BDRV_SECTOR_SIZE, s->len - start);
 
     state->buf_off = 0;
     g_free(state->orig_buf);
     state->buf_start = start;
-    state->buf_len = acb->end + s->readahead_size;
-    end = MIN(start + state->buf_len, s->len) - 1;
+    state->buf_len = MIN(acb->end + s->readahead_size, s->len - start);
+    end = start + state->buf_len - 1;
     state->orig_buf = g_try_malloc(state->buf_len);
     if (state->buf_len && state->orig_buf == NULL) {
         curl_clean_state(state);
-- 
2.7.4

  parent reply	other threads:[~2016-11-15  4:15 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-15  4:14 [Qemu-devel] [PULL for-2.8 00/13] Block patches for 2.8 Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 01/13] blockjob: fix dead pointer in txn list Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 02/13] blockjob: add .clean property Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 03/13] blockjob: add .start field Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 04/13] blockjob: add block_job_start Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 05/13] blockjob: refactor backup_start as backup_job_create Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 06/13] iotests: add transactional failure race test Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 07/13] qemu-iotests: avoid spurious failure on test 109 Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 08/13] block/curl: Drop TFTP "support" Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 09/13] block/curl: Use BDRV_SECTOR_SIZE Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 10/13] block/curl: Fix return value from curl_read_cb Jeff Cody
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 11/13] block/curl: Remember all sockets Jeff Cody
2016-11-15  4:14 ` Jeff Cody [this message]
2016-11-15  4:14 ` [Qemu-devel] [PULL for-2.8 13/13] mirror: do not flush every time the disks are synced Jeff Cody
2016-11-15 11:20 ` [Qemu-devel] [Qemu-block] [PULL for-2.8 00/13] Block patches for 2.8 Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1479183291-14086-13-git-send-email-jcody@redhat.com \
    --to=jcody@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).