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]; 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 *active = s->active;
BlockDriverState *top = s->top; BlockDriverState *top = s->top;
BlockDriverState *base = s->base; BlockDriverState *base = s->base;
BlockDriverState *overlay_bs = NULL; BlockDriverState *overlay_bs;
int64_t sector_num, end; int64_t sector_num, end;
int ret = 0; int ret = 0;
int n = 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; end = s->common.len >> BDRV_SECTOR_BITS;
buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE); buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);
@ -156,7 +154,8 @@ exit_restore_reopen:
if (s->base_flags != bdrv_get_flags(base)) { if (s->base_flags != bdrv_get_flags(base)) {
bdrv_reopen(base, s->base_flags, NULL); 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); bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
} }

View File

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

View File

@ -40,6 +40,7 @@ typedef struct {
struct VirtIOBlockDataPlane { struct VirtIOBlockDataPlane {
bool started; bool started;
bool stopping;
QEMUBH *start_bh; QEMUBH *start_bh;
QemuThread thread; QemuThread thread;
@ -357,7 +358,7 @@ static void *data_plane_thread(void *opaque)
do { do {
event_poll(&s->event_poll); event_poll(&s->event_poll);
} while (s->started || s->num_reqs > 0); } while (!s->stopping || s->num_reqs > 0);
return NULL; return NULL;
} }
@ -486,10 +487,10 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s) void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
{ {
if (!s->started) { if (!s->started || s->stopping) {
return; return;
} }
s->started = false; s->stopping = true;
trace_virtio_blk_data_plane_stop(s); trace_virtio_blk_data_plane_stop(s);
/* Stop thread or cancel pending thread creation BH */ /* 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); s->vdev->binding->set_guest_notifiers(s->vdev->binding_opaque, 1, false);
vring_teardown(&s->vring); 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) { if (bm->bus->dma->aiocb) {
bdrv_drain_all(); bdrv_drain_all();
assert(bm->bus->dma->aiocb == NULL); assert(bm->bus->dma->aiocb == NULL);
assert((bm->status & BM_STATUS_DMAING) == 0);
} }
} else { } else {
bm->cur_addr = bm->addr; 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; uint32_t features;
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE #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); virtio_blk_data_plane_stop(s->dataplane);
} }
#endif #endif

View File

@ -173,16 +173,14 @@ bool aio_pending(AioContext *ctx);
* aio as a result of executing I/O completion or bh callbacks. * aio as a result of executing I/O completion or bh callbacks.
* *
* If there is no pending AIO operation or completion (bottom half), * 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 * If there are no pending bottom halves, but there are pending AIO
* operations, it may not be possible to make any progress without * operations, it may not be possible to make any progress without
* blocking. If @blocking is true, this function will wait until one * blocking. If @blocking is true, this function will wait until one
* or more AIO events have completed, to ensure something has moved * or more AIO events have completed, to ensure something has moved
* before returning. * 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); 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); event_notifier_set(&data.e);
g_assert(aio_poll(ctx, false)); g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 1); g_assert_cmpint(data.n, ==, 1);
g_assert(!aio_poll(ctx, false)); g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 1); g_assert_cmpint(data.n, ==, 1);
event_notifier_set(&data.e); event_notifier_set(&data.e);
g_assert(aio_poll(ctx, false)); g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 2); g_assert_cmpint(data.n, ==, 2);
g_assert(!aio_poll(ctx, false)); g_assert(aio_poll(ctx, false));
g_assert_cmpint(data.n, ==, 2); g_assert_cmpint(data.n, ==, 2);
event_notifier_set(&dummy.e); event_notifier_set(&dummy.e);