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

# By Kevin Wolf (4) and others
# Via Stefan Hajnoczi
* stefanha/block:
  dataplane: support viostor virtio-pci status bit setting
  dataplane: avoid reentrancy during virtio_blk_data_plane_stop()
  win32-aio: use iov utility functions instead of open-coding them
  win32-aio: Fix memory leak
  win32-aio: Fix vectored reads
  aio: Fix return value of aio_poll()
  ide: Remove wrong assertion
  block: fix null-pointer bug on error case in block commit
This commit is contained in:
Anthony Liguori 2013-01-20 11:01:10 -06:00
commit 8b17ed4caa
9 changed files with 23 additions and 32 deletions

View File

@ -264,5 +264,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
}
}
return progress;
assert(progress || busy);
return true;
}

View File

@ -214,5 +214,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
events[ret - WAIT_OBJECT_0] = events[--count];
}
return progress;
assert(progress || busy);
return true;
}

View File

@ -65,7 +65,7 @@ static void coroutine_fn commit_run(void *opaque)
BlockDriverState *active = s->active;
BlockDriverState *top = s->top;
BlockDriverState *base = s->base;
BlockDriverState *overlay_bs = NULL;
BlockDriverState *overlay_bs;
int64_t sector_num, end;
int ret = 0;
int n = 0;
@ -92,8 +92,6 @@ static void coroutine_fn commit_run(void *opaque)
}
}
overlay_bs = bdrv_find_overlay(active, top);
end = s->common.len >> BDRV_SECTOR_BITS;
buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
@ -156,7 +154,8 @@ exit_restore_reopen:
if (s->base_flags != bdrv_get_flags(base)) {
bdrv_reopen(base, s->base_flags, NULL);
}
if (s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
overlay_bs = bdrv_find_overlay(active, top);
if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
}

View File

@ -29,6 +29,7 @@
#include "block/aio.h"
#include "raw-aio.h"
#include "qemu/event_notifier.h"
#include "qemu/iov.h"
#include <windows.h>
#include <winioctl.h>
@ -80,15 +81,9 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
if (!waiocb->is_linear) {
if (ret == 0 && waiocb->is_read) {
QEMUIOVector *qiov = waiocb->qiov;
char *p = waiocb->buf;
int i;
for (i = 0; i < qiov->niov; ++i) {
memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
p += qiov->iov[i].iov_len;
}
qemu_vfree(waiocb->buf);
iov_from_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
}
qemu_vfree(waiocb->buf);
}
@ -153,13 +148,7 @@ BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
if (qiov->niov > 1) {
waiocb->buf = qemu_blockalign(bs, qiov->size);
if (type & QEMU_AIO_WRITE) {
char *p = waiocb->buf;
int i;
for (i = 0; i < qiov->niov; ++i) {
memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
p += qiov->iov[i].iov_len;
}
iov_to_buf(qiov->iov, qiov->niov, 0, waiocb->buf, qiov->size);
}
waiocb->is_linear = false;
} else {

View File

@ -40,6 +40,7 @@ typedef struct {
struct VirtIOBlockDataPlane {
bool started;
bool stopping;
QEMUBH *start_bh;
QemuThread thread;
@ -357,7 +358,7 @@ static void *data_plane_thread(void *opaque)
do {
event_poll(&s->event_poll);
} while (s->started || s->num_reqs > 0);
} while (!s->stopping || s->num_reqs > 0);
return NULL;
}
@ -486,10 +487,10 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
{
if (!s->started) {
if (!s->started || s->stopping) {
return;
}
s->started = false;
s->stopping = true;
trace_virtio_blk_data_plane_stop(s);
/* Stop thread or cancel pending thread creation BH */
@ -511,4 +512,6 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1, false);
vring_teardown(&s->vring);
s->started = false;
s->stopping = false;
}

View File

@ -311,7 +311,6 @@ void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
if (bm->bus->dma->aiocb) {
bdrv_drain_all();
assert(bm->bus->dma->aiocb == NULL);
assert((bm->status & BM_STATUS_DMAING) == 0);
}
} else {
bm->cur_addr = bm->addr;

View File

@ -571,7 +571,8 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
uint32_t features;
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
if (s->dataplane && !(status & VIRTIO_CONFIG_S_DRIVER)) {
if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
VIRTIO_CONFIG_S_DRIVER_OK))) {
virtio_blk_data_plane_stop(s->dataplane);
}
#endif

View File

@ -173,16 +173,14 @@ bool aio_pending(AioContext *ctx);
* aio as a result of executing I/O completion or bh callbacks.
*
* If there is no pending AIO operation or completion (bottom half),
* return false. If there are pending bottom halves, return true.
* return false. If there are pending AIO operations of bottom halves,
* return true.
*
* If there are no pending bottom halves, but there are pending AIO
* operations, it may not be possible to make any progress without
* blocking. If @blocking is true, this function will wait until one
* or more AIO events have completed, to ensure something has moved
* before returning.
*
* If @blocking is false, this function will also return false if the
* function cannot make any progress without blocking.
*/
bool aio_poll(AioContext *ctx, bool blocking);

View File

@ -315,13 +315,13 @@ static void test_wait_event_notifier_noflush(void)
event_notifier_set(&data.e);
g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 1);
g_assert(!aio_poll(ctx, false));
g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 1);
event_notifier_set(&data.e);
g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 2);
g_assert(!aio_poll(ctx, false));
g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 2);
event_notifier_set(&dummy.e);