X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=block%2Fqed.c;h=1a7ef0a9ce1a192814f309f759221595cb474bc7;hb=0b4384d0bb98f0016ba671b1c9cc75c2f31cd057;hp=0f621924f87366ae6b5c6e281bea85db47e167ca;hpb=c41a73ffaf40aadc2c1e038ae4d12b62cd578e7f;p=mirror_qemu.git diff --git a/block/qed.c b/block/qed.c index 0f621924f8..1a7ef0a9ce 100644 --- a/block/qed.c +++ b/block/qed.c @@ -86,7 +86,7 @@ int qed_write_header_sync(BDRVQEDState *s) int ret; qed_header_cpu_to_le(&s->header, &le); - ret = bdrv_pwrite(s->bs->file->bs, 0, &le, sizeof(le)); + ret = bdrv_pwrite(s->bs->file, 0, &le, sizeof(le)); if (ret != sizeof(le)) { return ret; } @@ -123,7 +123,7 @@ static void qed_write_header_read_cb(void *opaque, int ret) /* Update header */ qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf); - bdrv_aio_writev(s->bs->file->bs, 0, &write_header_cb->qiov, + bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov, write_header_cb->nsectors, qed_write_header_cb, write_header_cb); } @@ -155,7 +155,7 @@ static void qed_write_header(BDRVQEDState *s, BlockCompletionFunc cb, write_header_cb->iov.iov_len = len; qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1); - bdrv_aio_readv(s->bs->file->bs, 0, &write_header_cb->qiov, nsectors, + bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors, qed_write_header_read_cb, write_header_cb); } @@ -218,7 +218,7 @@ static bool qed_is_image_size_valid(uint64_t image_size, uint32_t cluster_size, * * The string is NUL-terminated. */ -static int qed_read_string(BlockDriverState *file, uint64_t offset, size_t n, +static int qed_read_string(BdrvChild *file, uint64_t offset, size_t n, char *buf, size_t buflen) { int ret; @@ -336,7 +336,7 @@ static void qed_need_check_timer_cb(void *opaque) qed_plug_allocating_write_reqs(s); /* Ensure writes are on disk before clearing flag */ - bdrv_aio_flush(s->bs, qed_clear_need_check, s); + bdrv_aio_flush(s->bs->file->bs, qed_clear_need_check, s); } static void qed_start_need_check_timer(BDRVQEDState *s) @@ -378,6 +378,19 @@ static void bdrv_qed_attach_aio_context(BlockDriverState *bs, } } +static void bdrv_qed_drain(BlockDriverState *bs) +{ + BDRVQEDState *s = bs->opaque; + + /* Fire the timer immediately in order to start doing I/O as soon as the + * header is flushed. + */ + if (s->need_check_timer && timer_pending(s->need_check_timer)) { + qed_cancel_need_check_timer(s); + qed_need_check_timer_cb(s); + } +} + static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -389,7 +402,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, s->bs = bs; QSIMPLEQ_INIT(&s->allocating_write_reqs); - ret = bdrv_pread(bs->file->bs, 0, &le_header, sizeof(le_header)); + ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header)); if (ret < 0) { return ret; } @@ -446,7 +459,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, return -EINVAL; } - ret = qed_read_string(bs->file->bs, s->header.backing_filename_offset, + ret = qed_read_string(bs->file, s->header.backing_filename_offset, s->header.backing_filename_size, bs->backing_file, sizeof(bs->backing_file)); if (ret < 0) { @@ -517,7 +530,7 @@ static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQEDState *s = bs->opaque; - bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS; + bs->bl.pwrite_zeroes_alignment = s->header.cluster_size; } /* We have nothing to do for QED reopen, stubs just return @@ -708,7 +721,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l } if (cb->co) { - qemu_coroutine_enter(cb->co, NULL); + qemu_coroutine_enter(cb->co); } } @@ -800,7 +813,7 @@ static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos, qemu_iovec_concat(*backing_qiov, qiov, 0, size); BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING_AIO); - bdrv_aio_readv(s->bs->backing->bs, pos / BDRV_SECTOR_SIZE, + bdrv_aio_readv(s->bs->backing, pos / BDRV_SECTOR_SIZE, *backing_qiov, size / BDRV_SECTOR_SIZE, cb, opaque); } @@ -837,7 +850,7 @@ static void qed_copy_from_backing_file_write(void *opaque, int ret) } BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE); - bdrv_aio_writev(s->bs->file->bs, copy_cb->offset / BDRV_SECTOR_SIZE, + bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE, ©_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE, qed_copy_from_backing_file_cb, copy_cb); } @@ -909,7 +922,6 @@ static void qed_aio_complete_bh(void *opaque) void *user_opaque = acb->common.opaque; int ret = acb->bh_ret; - qemu_bh_delete(acb->bh); qemu_aio_unref(acb); /* Invoke callback */ @@ -934,9 +946,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret) /* Arrange for a bh to invoke the completion function */ acb->bh_ret = ret; - acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs), - qed_aio_complete_bh, acb); - qemu_bh_schedule(acb->bh); + aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs), + qed_aio_complete_bh, acb); /* Start next allocating write request waiting behind this one. Note that * requests enqueue themselves when they first hit an unallocated cluster @@ -1087,7 +1098,7 @@ static void qed_aio_write_main(void *opaque, int ret) } BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO); - bdrv_aio_writev(s->bs->file->bs, offset / BDRV_SECTOR_SIZE, + bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, next_fn, acb); } @@ -1319,7 +1330,7 @@ static void qed_aio_read_data(void *opaque, int ret, } BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - bdrv_aio_readv(bs->file->bs, offset / BDRV_SECTOR_SIZE, + bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE, &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, qed_aio_next_io, acb); return; @@ -1418,21 +1429,21 @@ typedef struct { bool done; } QEDWriteZeroesCB; -static void coroutine_fn qed_co_write_zeroes_cb(void *opaque, int ret) +static void coroutine_fn qed_co_pwrite_zeroes_cb(void *opaque, int ret) { QEDWriteZeroesCB *cb = opaque; cb->done = true; cb->ret = ret; if (cb->co) { - qemu_coroutine_enter(cb->co, NULL); + qemu_coroutine_enter(cb->co); } } -static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, - BdrvRequestFlags flags) +static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs, + int64_t offset, + int count, + BdrvRequestFlags flags) { BlockAIOCB *blockacb; BDRVQEDState *s = bs->opaque; @@ -1440,25 +1451,22 @@ static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs, QEMUIOVector qiov; struct iovec iov; - /* Refuse if there are untouched backing file sectors */ - if (bs->backing) { - if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) { - return -ENOTSUP; - } - if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) { - return -ENOTSUP; - } + /* Fall back if the request is not aligned */ + if (qed_offset_into_cluster(s, offset) || + qed_offset_into_cluster(s, count)) { + return -ENOTSUP; } /* Zero writes start without an I/O buffer. If a buffer becomes necessary * then it will be allocated during request processing. */ - iov.iov_base = NULL, - iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE, + iov.iov_base = NULL; + iov.iov_len = count; qemu_iovec_init_external(&qiov, &iov, 1); - blockacb = qed_aio_setup(bs, sector_num, &qiov, nb_sectors, - qed_co_write_zeroes_cb, &cb, + blockacb = qed_aio_setup(bs, offset >> BDRV_SECTOR_BITS, &qiov, + count >> BDRV_SECTOR_BITS, + qed_co_pwrite_zeroes_cb, &cb, QED_AIOCB_WRITE | QED_AIOCB_ZERO); if (!blockacb) { return -EIO; @@ -1578,7 +1586,7 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs, } /* Write new header */ - ret = bdrv_pwrite_sync(bs->file->bs, 0, buffer, buffer_len); + ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len); g_free(buffer); if (ret == 0) { memcpy(&s->header, &new_header, sizeof(new_header)); @@ -1663,7 +1671,7 @@ static BlockDriver bdrv_qed = { .bdrv_co_get_block_status = bdrv_qed_co_get_block_status, .bdrv_aio_readv = bdrv_qed_aio_readv, .bdrv_aio_writev = bdrv_qed_aio_writev, - .bdrv_co_write_zeroes = bdrv_qed_co_write_zeroes, + .bdrv_co_pwrite_zeroes = bdrv_qed_co_pwrite_zeroes, .bdrv_truncate = bdrv_qed_truncate, .bdrv_getlength = bdrv_qed_getlength, .bdrv_get_info = bdrv_qed_get_info, @@ -1673,6 +1681,7 @@ static BlockDriver bdrv_qed = { .bdrv_check = bdrv_qed_check, .bdrv_detach_aio_context = bdrv_qed_detach_aio_context, .bdrv_attach_aio_context = bdrv_qed_attach_aio_context, + .bdrv_drain = bdrv_qed_drain, }; static void bdrv_qed_init(void)