aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2017-05-15 12:00:54 +0200
committerMichael Roth <mdroth@linux.vnet.ibm.com>2017-08-03 14:32:52 -0500
commit4b519b9fd7c5e3d0107243ff776c0b5086ff2f4f (patch)
tree12b4e6d2860b229c5bdec953c2e56550ccc35294 /block
parentf00c08cbac63f452cc0828f60345a62cc175daa2 (diff)
downloadqemu-4b519b9fd7c5e3d0107243ff776c0b5086ff2f4f.zip
qemu-4b519b9fd7c5e3d0107243ff776c0b5086ff2f4f.tar.gz
qemu-4b519b9fd7c5e3d0107243ff776c0b5086ff2f4f.tar.bz2
curl: never invoke callbacks with s->mutex held
All curl callbacks go through curl_multi_do, and hence are called with s->mutex held. Note that with comments, and make curl_read_cb drop the lock before invoking the callback. Likewise for curl_find_buf, where the callback can be invoked by the caller. Cc: qemu-stable@nongnu.org Reviewed-by: Jeff Cody <jcody@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Message-id: 20170515100059.15795-3-pbonzini@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com> (cherry picked from commit 34db05e7ffe8d61ca7288b9532ad6e8300853318) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'block')
-rw-r--r--block/curl.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/block/curl.c b/block/curl.c
index c6dc4c0..59e69c6 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -147,6 +147,7 @@ static void curl_multi_do(void *arg);
static void curl_multi_read(void *arg);
#ifdef NEED_CURL_TIMER_CALLBACK
+/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
{
BDRVCURLState *s = opaque;
@@ -163,6 +164,7 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
}
#endif
+/* Called from curl_multi_do_locked, with s->mutex held. */
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
void *userp, void *sp)
{
@@ -212,6 +214,7 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
return 0;
}
+/* Called from curl_multi_do_locked, with s->mutex held. */
static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
BDRVCURLState *s = opaque;
@@ -226,6 +229,7 @@ static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
return realsize;
}
+/* Called from curl_multi_do_locked, with s->mutex held. */
static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
CURLState *s = ((CURLState*)opaque);
@@ -264,7 +268,9 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
request_length - offset);
}
+ qemu_mutex_unlock(&s->s->mutex);
acb->common.cb(acb->common.opaque, 0);
+ qemu_mutex_lock(&s->s->mutex);
qemu_aio_unref(acb);
s->acb[i] = NULL;
}
@@ -305,8 +311,6 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, size_t 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;
}
@@ -832,8 +836,8 @@ static void curl_readv_bh_cb(void *p)
// we can just call the callback and be done.
switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
case FIND_RET_OK:
- qemu_aio_unref(acb);
- // fall through
+ ret = 0;
+ goto out;
case FIND_RET_WAIT:
goto out;
default: