curl: split curl_find_state/curl_init_state
If curl_easy_init fails, a CURLState is left with s->in_use = 1. Split curl_init_state in two, so that we can distinguish the two failures and call curl_clean_state if needed. While at it, simplify curl_find_state, removing a dummy loop. The aio_poll loop is moved to the sole caller that needs it. 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-5-pbonzini@redhat.com Signed-off-by: Jeff Cody <jcody@redhat.com>
This commit is contained in:
parent
456af34629
commit
3ce6a729b5
52
block/curl.c
52
block/curl.c
@ -456,34 +456,27 @@ static void curl_multi_timeout_do(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Called with s->mutex held. */
|
/* Called with s->mutex held. */
|
||||||
static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
|
static CURLState *curl_find_state(BDRVCURLState *s)
|
||||||
{
|
{
|
||||||
CURLState *state = NULL;
|
CURLState *state = NULL;
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
do {
|
|
||||||
for (i=0; i<CURL_NUM_STATES; i++) {
|
|
||||||
for (j=0; j<CURL_NUM_ACB; j++)
|
|
||||||
if (s->states[i].acb[j])
|
|
||||||
continue;
|
|
||||||
if (s->states[i].in_use)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
for (i = 0; i < CURL_NUM_STATES; i++) {
|
||||||
|
if (!s->states[i].in_use) {
|
||||||
state = &s->states[i];
|
state = &s->states[i];
|
||||||
state->in_use = 1;
|
state->in_use = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!state) {
|
}
|
||||||
qemu_mutex_unlock(&s->mutex);
|
return state;
|
||||||
aio_poll(bdrv_get_aio_context(bs), true);
|
}
|
||||||
qemu_mutex_lock(&s->mutex);
|
|
||||||
}
|
|
||||||
} while(!state);
|
|
||||||
|
|
||||||
|
static int curl_init_state(BDRVCURLState *s, CURLState *state)
|
||||||
|
{
|
||||||
if (!state->curl) {
|
if (!state->curl) {
|
||||||
state->curl = curl_easy_init();
|
state->curl = curl_easy_init();
|
||||||
if (!state->curl) {
|
if (!state->curl) {
|
||||||
return NULL;
|
return -EIO;
|
||||||
}
|
}
|
||||||
curl_easy_setopt(state->curl, CURLOPT_URL, s->url);
|
curl_easy_setopt(state->curl, CURLOPT_URL, s->url);
|
||||||
curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER,
|
curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER,
|
||||||
@ -536,7 +529,7 @@ static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)
|
|||||||
QLIST_INIT(&state->sockets);
|
QLIST_INIT(&state->sockets);
|
||||||
state->s = s;
|
state->s = s;
|
||||||
|
|
||||||
return state;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with s->mutex held. */
|
/* Called with s->mutex held. */
|
||||||
@ -778,13 +771,18 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
s->aio_context = bdrv_get_aio_context(bs);
|
s->aio_context = bdrv_get_aio_context(bs);
|
||||||
s->url = g_strdup(file);
|
s->url = g_strdup(file);
|
||||||
qemu_mutex_lock(&s->mutex);
|
qemu_mutex_lock(&s->mutex);
|
||||||
state = curl_init_state(bs, s);
|
state = curl_find_state(s);
|
||||||
qemu_mutex_unlock(&s->mutex);
|
qemu_mutex_unlock(&s->mutex);
|
||||||
if (!state)
|
if (!state) {
|
||||||
goto out_noclean;
|
goto out_noclean;
|
||||||
|
}
|
||||||
|
|
||||||
// Get file size
|
// Get file size
|
||||||
|
|
||||||
|
if (curl_init_state(s, state) < 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
s->accept_range = false;
|
s->accept_range = false;
|
||||||
curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
|
curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
|
||||||
curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
|
curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
|
||||||
@ -879,8 +877,18 @@ static void curl_readv_bh_cb(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No cache found, so let's start a new request
|
// No cache found, so let's start a new request
|
||||||
state = curl_init_state(acb->common.bs, s);
|
for (;;) {
|
||||||
if (!state) {
|
state = curl_find_state(s);
|
||||||
|
if (state) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
qemu_mutex_unlock(&s->mutex);
|
||||||
|
aio_poll(bdrv_get_aio_context(bs), true);
|
||||||
|
qemu_mutex_lock(&s->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curl_init_state(s, state) < 0) {
|
||||||
|
curl_clean_state(state);
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user