mirror of https://gitee.com/openkylin/qemu.git
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: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
9b4abb4677
5
block.c
5
block.c
|
@ -1358,11 +1358,12 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state)
|
||||||
|
|
||||||
void bdrv_close(BlockDriverState *bs)
|
void bdrv_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
bdrv_flush(bs);
|
|
||||||
if (bs->job) {
|
if (bs->job) {
|
||||||
block_job_cancel_sync(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);
|
notifier_list_notify(&bs->close_notifiers, bs);
|
||||||
|
|
||||||
if (bs->drv) {
|
if (bs->drv) {
|
||||||
|
|
24
block/curl.c
24
block/curl.c
|
@ -81,6 +81,7 @@ typedef struct BDRVCURLState {
|
||||||
CURLState states[CURL_NUM_STATES];
|
CURLState states[CURL_NUM_STATES];
|
||||||
char *url;
|
char *url;
|
||||||
size_t readahead_size;
|
size_t readahead_size;
|
||||||
|
bool accept_range;
|
||||||
} BDRVCURLState;
|
} BDRVCURLState;
|
||||||
|
|
||||||
static void curl_clean_state(CURLState *s);
|
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;
|
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 realsize = size * nmemb;
|
||||||
size_t fsize;
|
const char *accept_line = "Accept-Ranges: bytes";
|
||||||
|
|
||||||
if(sscanf(ptr, "Content-Length: %zd", &fsize) == 1) {
|
if (realsize >= strlen(accept_line)
|
||||||
s->s->len = fsize;
|
&& strncmp((char *)ptr, accept_line, strlen(accept_line)) == 0) {
|
||||||
|
s->accept_range = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return realsize;
|
return realsize;
|
||||||
|
@ -447,8 +449,11 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags)
|
||||||
|
|
||||||
// Get file size
|
// Get file size
|
||||||
|
|
||||||
|
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_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))
|
if (curl_easy_perform(state->curl))
|
||||||
goto out;
|
goto out;
|
||||||
curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
|
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;
|
s->len = (size_t)d;
|
||||||
else if(!s->len)
|
else if(!s->len)
|
||||||
goto out;
|
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);
|
DPRINTF("CURL: Size = %zd\n", s->len);
|
||||||
|
|
||||||
curl_clean_state(state);
|
curl_clean_state(state);
|
||||||
|
|
18
block/vmdk.c
18
block/vmdk.c
|
@ -1724,6 +1724,23 @@ static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
|
||||||
return ret;
|
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[] = {
|
static QEMUOptionParameter vmdk_create_options[] = {
|
||||||
{
|
{
|
||||||
.name = BLOCK_OPT_SIZE,
|
.name = BLOCK_OPT_SIZE,
|
||||||
|
@ -1775,6 +1792,7 @@ static BlockDriver bdrv_vmdk = {
|
||||||
.bdrv_co_flush_to_disk = vmdk_co_flush,
|
.bdrv_co_flush_to_disk = vmdk_co_flush,
|
||||||
.bdrv_co_is_allocated = vmdk_co_is_allocated,
|
.bdrv_co_is_allocated = vmdk_co_is_allocated,
|
||||||
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
|
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
|
||||||
|
.bdrv_has_zero_init = vmdk_has_zero_init,
|
||||||
|
|
||||||
.create_options = vmdk_create_options,
|
.create_options = vmdk_create_options,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue