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:
commit
8b17ed4caa
@ -264,5 +264,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
assert(progress || busy);
|
||||
return true;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user