Commit 9b4abb46 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

Merge remote-tracking branch 'stefanha/block' into staging



# By Fam Zheng (2) and Stefan Hajnoczi (1)
# Via Stefan Hajnoczi
* stefanha/block:
  block: fix bdrv_flush() ordering in bdrv_close()
  curl: refuse to open URL from HTTP server without range support
  vmdk: Implement .bdrv_has_zero_init

Message-id: 1373023972-3587-1-git-send-email-stefanha@redhat.com
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parents c3ab4c9c 58fda173
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -1358,11 +1358,12 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state)

void bdrv_close(BlockDriverState *bs)
{
    bdrv_flush(bs);
    if (bs->job) {
        block_job_cancel_sync(bs->job);
    }
    bdrv_drain_all();
    bdrv_drain_all(); /* complete I/O */
    bdrv_flush(bs);
    bdrv_drain_all(); /* in case flush left pending I/O */
    notifier_list_notify(&bs->close_notifiers, bs);

    if (bs->drv) {
+18 −6
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ typedef struct BDRVCURLState {
    CURLState states[CURL_NUM_STATES];
    char *url;
    size_t readahead_size;
    bool accept_range;
} BDRVCURLState;

static void curl_clean_state(CURLState *s);
@@ -110,14 +111,15 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
    return 0;
}

static size_t curl_size_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *opaque)
{
    CURLState *s = ((CURLState*)opaque);
    BDRVCURLState *s = opaque;
    size_t realsize = size * nmemb;
    size_t fsize;
    const char *accept_line = "Accept-Ranges: bytes";

    if(sscanf(ptr, "Content-Length: %zd", &fsize) == 1) {
        s->s->len = fsize;
    if (realsize >= strlen(accept_line)
        && strncmp((char *)ptr, accept_line, strlen(accept_line)) == 0) {
        s->accept_range = true;
    }

    return realsize;
@@ -447,8 +449,11 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags)

    // Get file size

    s->accept_range = false;
    curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
    curl_easy_setopt(state->curl, CURLOPT_WRITEFUNCTION, (void *)curl_size_cb);
    curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
                     curl_header_cb);
    curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s);
    if (curl_easy_perform(state->curl))
        goto out;
    curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
@@ -456,6 +461,13 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags)
        s->len = (size_t)d;
    else if(!s->len)
        goto out;
    if ((!strncasecmp(s->url, "http://", strlen("http://"))
        || !strncasecmp(s->url, "https://", strlen("https://")))
        && !s->accept_range) {
        pstrcpy(state->errmsg, CURL_ERROR_SIZE,
                "Server does not support 'range' (byte ranges).");
        goto out;
    }
    DPRINTF("CURL: Size = %zd\n", s->len);

    curl_clean_state(state);
+33 −15
Original line number Diff line number Diff line
@@ -1724,6 +1724,23 @@ static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
    return ret;
}

static int vmdk_has_zero_init(BlockDriverState *bs)
{
    int i;
    BDRVVmdkState *s = bs->opaque;

    /* If has a flat extent and its underlying storage doesn't have zero init,
     * return 0. */
    for (i = 0; i < s->num_extents; i++) {
        if (s->extents[i].flat) {
            if (!bdrv_has_zero_init(s->extents[i].file)) {
                return 0;
            }
        }
    }
    return 1;
}

static QEMUOptionParameter vmdk_create_options[] = {
    {
        .name = BLOCK_OPT_SIZE,
@@ -1775,6 +1792,7 @@ static BlockDriver bdrv_vmdk = {
    .bdrv_co_flush_to_disk        = vmdk_co_flush,
    .bdrv_co_is_allocated         = vmdk_co_is_allocated,
    .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
    .bdrv_has_zero_init           = vmdk_has_zero_init,

    .create_options               = vmdk_create_options,
};