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

# By Stefan Hajnoczi (14) and others
# Via Stefan Hajnoczi
* stefanha/block: (28 commits)
  blockdev: Fix up copyright and permission notice
  qemu-iotests: use -nographic in test case 007
  qemu-iotests: add tests for rebasing zero clusters
  dataplane: fix hang introduced by AioContext transition
  coroutine: use AioContext for CoQueue BH
  threadpool: drop global thread pool
  block: add bdrv_get_aio_context()
  aio: add a ThreadPool instance to AioContext
  threadpool: add thread_pool_new() and thread_pool_free()
  threadpool: move globals into struct ThreadPool
  main-loop: add qemu_get_aio_context()
  sheepdog: set io_flush handler in do_co_req
  sheepdog: use non-blocking fd in coroutine context
  qcow2: make is_allocated return true for zero clusters
  qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount()
  qcow2: drop flush in update_cluster_refcount()
  qcow2: flush in qcow2_update_snapshot_refcount()
  qcow2: set L2 cache dependency in qcow2_alloc_bytes()
  qcow2: flush refcount cache correctly in qcow2_write_snapshots()
  qcow2: flush refcount cache correctly in alloc_refcount_block()
  ...
This commit is contained in:
Anthony Liguori
2013-03-15 10:47:21 -05:00
49 changed files with 700 additions and 231 deletions
+11
View File
@@ -24,6 +24,7 @@
#include "qemu-common.h"
#include "block/aio.h"
#include "block/thread-pool.h"
#include "qemu/main-loop.h"
/***********************************************************/
@@ -172,6 +173,7 @@ aio_ctx_finalize(GSource *source)
{
AioContext *ctx = (AioContext *) source;
thread_pool_free(ctx->thread_pool);
aio_set_event_notifier(ctx, &ctx->notifier, NULL, NULL);
event_notifier_cleanup(&ctx->notifier);
g_array_free(ctx->pollfds, TRUE);
@@ -190,6 +192,14 @@ GSource *aio_get_g_source(AioContext *ctx)
return &ctx->source;
}
ThreadPool *aio_get_thread_pool(AioContext *ctx)
{
if (!ctx->thread_pool) {
ctx->thread_pool = thread_pool_new(ctx);
}
return ctx->thread_pool;
}
void aio_notify(AioContext *ctx)
{
event_notifier_set(&ctx->notifier);
@@ -200,6 +210,7 @@ AioContext *aio_context_new(void)
AioContext *ctx;
ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
ctx->thread_pool = NULL;
event_notifier_init(&ctx->notifier, false);
aio_set_event_notifier(ctx, &ctx->notifier,
(EventNotifierHandler *)
+68 -19
View File
@@ -665,15 +665,18 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
/*
* Common part for opening disk images and files
*
* Removes all processed options from *options.
*/
static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
const char *filename,
const char *filename, QDict *options,
int flags, BlockDriver *drv)
{
int ret, open_flags;
assert(drv != NULL);
assert(bs->file == NULL);
assert(options == NULL || bs->options != options);
trace_bdrv_open_common(bs, filename, flags, drv->format_name);
@@ -710,7 +713,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
} else {
assert(file != NULL);
bs->file = file;
ret = drv->bdrv_open(bs, open_flags);
ret = drv->bdrv_open(bs, options, open_flags);
}
if (ret < 0) {
@@ -752,7 +755,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
}
bs = bdrv_new("");
ret = bdrv_open_common(bs, NULL, filename, flags, drv);
ret = bdrv_open_common(bs, NULL, filename, NULL, flags, drv);
if (ret < 0) {
bdrv_delete(bs);
return ret;
@@ -788,7 +791,8 @@ int bdrv_open_backing_file(BlockDriverState *bs)
/* backing files always opened read-only */
back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT);
ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);
ret = bdrv_open(bs->backing_hd, backing_filename, NULL,
back_flags, back_drv);
if (ret < 0) {
bdrv_delete(bs->backing_hd);
bs->backing_hd = NULL;
@@ -800,15 +804,29 @@ int bdrv_open_backing_file(BlockDriverState *bs)
/*
* Opens a disk image (raw, qcow2, vmdk, ...)
*
* options is a QDict of options to pass to the block drivers, or NULL for an
* empty set of options. The reference to the QDict belongs to the block layer
* after the call (even on failure), so if the caller intends to reuse the
* dictionary, it needs to use QINCREF() before calling bdrv_open.
*/
int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
BlockDriver *drv)
int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
int flags, BlockDriver *drv)
{
int ret;
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char tmp_filename[PATH_MAX + 1];
BlockDriverState *file = NULL;
/* NULL means an empty set of options */
if (options == NULL) {
options = qdict_new();
}
bs->options = options;
options = qdict_clone_shallow(options);
/* For snapshot=on, create a temporary qcow2 overlay */
if (flags & BDRV_O_SNAPSHOT) {
BlockDriverState *bs1;
int64_t total_size;
@@ -822,10 +840,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
/* if there is a backing file, use it */
bs1 = bdrv_new("");
ret = bdrv_open(bs1, filename, 0, drv);
ret = bdrv_open(bs1, filename, NULL, 0, drv);
if (ret < 0) {
bdrv_delete(bs1);
return ret;
goto fail;
}
total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
@@ -836,15 +854,17 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
if (ret < 0) {
return ret;
goto fail;
}
/* Real path is meaningless for protocols */
if (is_protocol)
if (is_protocol) {
snprintf(backing_filename, sizeof(backing_filename),
"%s", filename);
else if (!realpath(filename, backing_filename))
return -errno;
} else if (!realpath(filename, backing_filename)) {
ret = -errno;
goto fail;
}
bdrv_qcow2 = bdrv_find_format("qcow2");
options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);
@@ -859,7 +879,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
ret = bdrv_create(bdrv_qcow2, tmp_filename, options);
free_option_parameters(options);
if (ret < 0) {
return ret;
goto fail;
}
filename = tmp_filename;
@@ -874,7 +894,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
ret = bdrv_file_open(&file, filename, bdrv_open_flags(bs, flags));
if (ret < 0) {
return ret;
goto fail;
}
/* Find the right image format driver */
@@ -887,7 +907,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
}
/* Open the image */
ret = bdrv_open_common(bs, file, filename, flags, drv);
ret = bdrv_open_common(bs, file, filename, options, flags, drv);
if (ret < 0) {
goto unlink_and_fail;
}
@@ -901,11 +921,22 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
if ((flags & BDRV_O_NO_BACKING) == 0) {
ret = bdrv_open_backing_file(bs);
if (ret < 0) {
bdrv_close(bs);
return ret;
goto close_and_fail;
}
}
/* Check if any unknown options were used */
if (qdict_size(options) != 0) {
const QDictEntry *entry = qdict_first(options);
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block format '%s' used by "
"device '%s' doesn't support the option '%s'",
drv->format_name, bs->device_name, entry->key);
ret = -EINVAL;
goto close_and_fail;
}
QDECREF(options);
if (!bdrv_key_required(bs)) {
bdrv_dev_change_media_cb(bs, true);
}
@@ -924,6 +955,15 @@ unlink_and_fail:
if (bs->is_temporary) {
unlink(filename);
}
fail:
QDECREF(bs->options);
QDECREF(options);
bs->options = NULL;
return ret;
close_and_fail:
bdrv_close(bs);
QDECREF(options);
return ret;
}
@@ -1193,6 +1233,8 @@ void bdrv_close(BlockDriverState *bs)
bs->valid_key = 0;
bs->sg = 0;
bs->growable = 0;
QDECREF(bs->options);
bs->options = NULL;
if (bs->file != NULL) {
bdrv_delete(bs->file);
@@ -3190,7 +3232,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
if (bs->file) {
drv->bdrv_close(bs);
ret = bdrv_snapshot_goto(bs->file, snapshot_id);
open_ret = drv->bdrv_open(bs, bs->open_flags);
open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);
if (open_ret < 0) {
bdrv_delete(bs->file);
bs->drv = NULL;
@@ -4594,7 +4636,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
bs = bdrv_new("");
ret = bdrv_open(bs, backing_file->value.s, back_flags, backing_drv);
ret = bdrv_open(bs, backing_file->value.s, NULL, back_flags,
backing_drv);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not open '%s'",
backing_file->value.s);
@@ -4638,3 +4681,9 @@ out:
bdrv_delete(bs);
}
}
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
{
/* Currently BlockDriverState always uses the main loop AioContext */
return qemu_get_aio_context();
}
+1 -1
View File
@@ -98,7 +98,7 @@ static int blkverify_open(BlockDriverState *bs, const char *filename, int flags)
/* Open the test file */
s->test_file = bdrv_new("");
ret = bdrv_open(s->test_file, filename, flags, NULL);
ret = bdrv_open(s->test_file, filename, NULL, flags, NULL);
if (ret < 0) {
bdrv_delete(s->test_file);
s->test_file = NULL;
+1 -1
View File
@@ -108,7 +108,7 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
return 0;
}
static int bochs_open(BlockDriverState *bs, int flags)
static int bochs_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVBochsState *s = bs->opaque;
int i;
+1 -1
View File
@@ -53,7 +53,7 @@ static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
return 0;
}
static int cloop_open(BlockDriverState *bs, int flags)
static int cloop_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVCloopState *s = bs->opaque;
uint32_t offsets_size, max_compressed_block_size = 1, i;
+1 -1
View File
@@ -58,7 +58,7 @@ static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
return 0;
}
static int cow_open(BlockDriverState *bs, int flags)
static int cow_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVCowState *s = bs->opaque;
struct cow_header_v2 cow_header;
+1 -1
View File
@@ -85,7 +85,7 @@ static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
return 0;
}
static int dmg_open(BlockDriverState *bs, int flags)
static int dmg_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVDMGState *s = bs->opaque;
uint64_t info_begin,info_end,last_in_offset,last_out_offset;
+1 -1
View File
@@ -68,7 +68,7 @@ static int parallels_probe(const uint8_t *buf, int buf_size, const char *filenam
return 0;
}
static int parallels_open(BlockDriverState *bs, int flags)
static int parallels_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVParallelsState *s = bs->opaque;
int i;
+1 -1
View File
@@ -92,7 +92,7 @@ static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
return 0;
}
static int qcow_open(BlockDriverState *bs, int flags)
static int qcow_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVQcowState *s = bs->opaque;
int len, i, shift, ret;
+4 -1
View File
@@ -454,6 +454,9 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
*cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK;
break;
case QCOW2_CLUSTER_ZERO:
if (s->qcow_version < 3) {
return -EIO;
}
c = count_contiguous_clusters(nb_clusters, s->cluster_size,
&l2_table[l2_index], 0,
QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
@@ -668,7 +671,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
}
/* Update L2 table. */
if (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS) {
if (s->use_lazy_refcounts) {
qcow2_mark_dirty(bs);
}
if (qcow2_need_accurate_refcounts(s)) {
+14 -10
View File
@@ -201,7 +201,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
*refcount_block = NULL;
/* We write to the refcount table, so we might depend on L2 tables */
qcow2_cache_flush(bs, s->l2_table_cache);
ret = qcow2_cache_flush(bs, s->l2_table_cache);
if (ret < 0) {
return ret;
}
/* Allocate the refcount block itself and mark it as used */
int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);
@@ -237,7 +240,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
goto fail_block;
}
bdrv_flush(bs->file);
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret < 0) {
goto fail_block;
}
/* Initialize the new refcount block only after updating its refcount,
* update_refcount uses the refcount cache itself */
@@ -526,8 +532,6 @@ static int update_cluster_refcount(BlockDriverState *bs,
return ret;
}
bdrv_flush(bs->file);
return get_refcount(bs, cluster_index);
}
@@ -663,7 +667,11 @@ int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
}
}
bdrv_flush(bs->file);
/* The cluster refcount was incremented, either by qcow2_alloc_clusters()
* or explicitly by update_cluster_refcount(). Refcount blocks must be
* flushed before the caller's L2 table updates.
*/
qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache);
return offset;
}
@@ -782,10 +790,6 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
if (ret < 0) {
goto fail;
}
/* TODO Flushing once for the whole function should
* be enough */
bdrv_flush(bs->file);
}
/* compressed clusters are never modified */
refcount = 2;
@@ -841,7 +845,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
}
}
ret = 0;
ret = bdrv_flush(bs);
fail:
if (l2_table) {
qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
+4 -6
View File
@@ -180,11 +180,14 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
/* Allocate space for the new snapshot list */
snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
bdrv_flush(bs->file);
offset = snapshots_offset;
if (offset < 0) {
return offset;
}
ret = bdrv_flush(bs);
if (ret < 0) {
return ret;
}
/* Write all snapshots to the new list */
for(i = 0; i < s->nb_snapshots; i++) {
@@ -378,11 +381,6 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto fail;
}
ret = bdrv_flush(bs);
if (ret < 0) {
goto fail;
}
/* Append the new snapshot to the snapshot list */
new_snapshot_list = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
if (s->snapshots) {
+41 -8
View File
@@ -285,11 +285,26 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
return ret;
}
static int qcow2_open(BlockDriverState *bs, int flags)
static QemuOptsList qcow2_runtime_opts = {
.name = "qcow2",
.head = QTAILQ_HEAD_INITIALIZER(qcow2_runtime_opts.head),
.desc = {
{
.name = "lazy_refcounts",
.type = QEMU_OPT_BOOL,
.help = "Postpone refcount updates",
},
{ /* end of list */ }
},
};
static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVQcowState *s = bs->opaque;
int len, i, ret = 0;
QCowHeader header;
QemuOpts *opts;
Error *local_err = NULL;
uint64_t ext_end;
ret = bdrv_pread(bs->file, 0, &header, sizeof(header));
@@ -495,6 +510,28 @@ static int qcow2_open(BlockDriverState *bs, int flags)
}
}
/* Enable lazy_refcounts according to image and command line options */
opts = qemu_opts_create_nofail(&qcow2_runtime_opts);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (error_is_set(&local_err)) {
qerror_report_err(local_err);
error_free(local_err);
ret = -EINVAL;
goto fail;
}
s->use_lazy_refcounts = qemu_opt_get_bool(opts, "lazy_refcounts",
(s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS));
qemu_opts_del(opts);
if (s->use_lazy_refcounts && s->qcow_version < 3) {
qerror_report(ERROR_CLASS_GENERIC_ERROR, "Lazy refcounts require "
"a qcow2 image with at least qemu 1.1 compatibility level");
ret = -EINVAL;
goto fail;
}
#ifdef DEBUG_ALLOC
{
BdrvCheckResult result = {0};
@@ -584,7 +621,7 @@ static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,
*pnum = 0;
}
return (cluster_offset != 0);
return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
}
/* handle reading after the end of the backing file */
@@ -665,10 +702,6 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
break;
case QCOW2_CLUSTER_ZERO:
if (s->qcow_version < 3) {
ret = -EIO;
goto fail;
}
qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);
break;
@@ -912,7 +945,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)
qcow2_close(bs);
memset(s, 0, sizeof(BDRVQcowState));
qcow2_open(bs, flags);
qcow2_open(bs, NULL, flags);
if (crypt_method) {
s->crypt_method = crypt_method;
@@ -1265,7 +1298,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
*/
BlockDriver* drv = bdrv_find_format("qcow2");
assert(drv != NULL);
ret = bdrv_open(bs, filename,
ret = bdrv_open(bs, filename, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv);
if (ret < 0) {
goto out;
+1
View File
@@ -173,6 +173,7 @@ typedef struct BDRVQcowState {
int flags;
int qcow_version;
bool use_lazy_refcounts;
uint64_t incompatible_features;
uint64_t compatible_features;
+2 -2
View File
@@ -373,7 +373,7 @@ static void bdrv_qed_rebind(BlockDriverState *bs)
s->bs = bs;
}
static int bdrv_qed_open(BlockDriverState *bs, int flags)
static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVQEDState *s = bs->opaque;
QEDHeader le_header;
@@ -1526,7 +1526,7 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs)
bdrv_qed_close(bs);
memset(s, 0, sizeof(BDRVQEDState));
bdrv_qed_open(bs, bs->open_flags);
bdrv_qed_open(bs, NULL, bs->open_flags);
}
static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
+6 -2
View File
@@ -750,6 +750,7 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
BlockDriverCompletionFunc *cb, void *opaque, int type)
{
RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);
ThreadPool *pool;
acb->bs = bs;
acb->aio_type = type;
@@ -763,7 +764,8 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,
acb->aio_offset = sector_num * 512;
trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
}
static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
@@ -1413,6 +1415,7 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
{
BDRVRawState *s = bs->opaque;
RawPosixAIOData *acb;
ThreadPool *pool;
if (fd_open(bs) < 0)
return NULL;
@@ -1424,7 +1427,8 @@ static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
acb->aio_offset = 0;
acb->aio_ioctl_buf = buf;
acb->aio_ioctl_cmd = req;
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
}
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+3 -1
View File
@@ -144,6 +144,7 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
BlockDriverCompletionFunc *cb, void *opaque, int type)
{
RawWin32AIOData *acb = g_slice_new(RawWin32AIOData);
ThreadPool *pool;
acb->bs = bs;
acb->hfile = hfile;
@@ -157,7 +158,8 @@ static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, HANDLE hfile,
acb->aio_offset = sector_num * 512;
trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);
return thread_pool_submit_aio(aio_worker, acb, cb, opaque);
pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);
}
int qemu_ftruncate64(int fd, int64_t length)
+1 -1
View File
@@ -3,7 +3,7 @@
#include "block/block_int.h"
#include "qemu/module.h"
static int raw_open(BlockDriverState *bs, int flags)
static int raw_open(BlockDriverState *bs, QDict *options, int flags)
{
bs->sg = bs->file->sg;
return 0;
+13 -6
View File
@@ -468,6 +468,8 @@ static int connect_to_sdog(BDRVSheepdogState *s)
if (err != NULL) {
qerror_report_err(err);
error_free(err);
} else {
socket_set_nonblock(fd);
}
return fd;
@@ -499,6 +501,13 @@ static void restart_co_req(void *opaque)
qemu_coroutine_enter(co, NULL);
}
static int have_co_req(void *opaque)
{
/* this handler is set only when there is a pending request, so
* always returns 1. */
return 1;
}
typedef struct SheepdogReqCo {
int sockfd;
SheepdogReq *hdr;
@@ -521,15 +530,14 @@ static coroutine_fn void do_co_req(void *opaque)
unsigned int *rlen = srco->rlen;
co = qemu_coroutine_self();
qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);
qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, have_co_req, co);
socket_set_block(sockfd);
ret = send_co_req(sockfd, hdr, data, wlen);
if (ret < 0) {
goto out;
}
qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, NULL, co);
qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, have_co_req, co);
ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
if (ret < sizeof(*hdr)) {
@@ -552,8 +560,9 @@ static coroutine_fn void do_co_req(void *opaque)
}
ret = 0;
out:
/* there is at most one request for this sockfd, so it is safe to
* set each handler to NULL. */
qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
socket_set_nonblock(sockfd);
srco->ret = ret;
srco->finished = true;
@@ -776,8 +785,6 @@ static int get_sheep_fd(BDRVSheepdogState *s)
return fd;
}
socket_set_nonblock(fd);
qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s);
return fd;
}
+1 -1
View File
@@ -364,7 +364,7 @@ static int vdi_probe(const uint8_t *buf, int buf_size, const char *filename)
return result;
}
static int vdi_open(BlockDriverState *bs, int flags)
static int vdi_open(BlockDriverState *bs, QDict *options, int flags)
{
BDRVVdiState *s = bs->opaque;
VdiHeader header;

Some files were not shown because too many files have changed in this diff Show More