diff options
author | Kevin Wolf <kwolf@redhat.com> | 2016-11-14 14:56:32 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-06-26 14:51:14 +0200 |
commit | a4d8f1aee13955026c7ff4414cabad625749a613 (patch) | |
tree | 83428455f65524e7cc09efe81ca5ec8c921b4a77 | |
parent | 3e248cdcd907df82da63f89905e2e1bd20d44ab6 (diff) |
qed: Make qed_aio_write_main() synchronous
Note that this code is generally not running in coroutine context, so
this is an actual blocking synchronous operation. We'll fix this in a
moment.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | block/qed.c | 61 |
1 files changed, 19 insertions, 42 deletions
diff --git a/block/qed.c b/block/qed.c index cfebbaed23..d164b0e6f2 100644 --- a/block/qed.c +++ b/block/qed.c @@ -260,13 +260,6 @@ static void qed_aio_start_io(QEDAIOCB *acb) qed_aio_next_io(acb, 0); } -static void qed_aio_next_io_cb(void *opaque, int ret) -{ - QEDAIOCB *acb = opaque; - - qed_aio_next_io(acb, ret); -} - static void qed_plug_allocating_write_reqs(BDRVQEDState *s) { assert(!s->allocating_write_reqs_plugged); @@ -1042,31 +1035,6 @@ err: qed_aio_complete(acb, ret); } -static void qed_aio_write_l2_update_cb(void *opaque, int ret) -{ - QEDAIOCB *acb = opaque; - qed_aio_write_l2_update(acb, ret, acb->cur_cluster); -} - -/** - * Flush new data clusters before updating the L2 table - * - * This flush is necessary when a backing file is in use. A crash during an - * allocating write could result in empty clusters in the image. If the write - * only touched a subregion of the cluster, then backing image sectors have - * been lost in the untouched region. The solution is to flush after writing a - * new data cluster and before updating the L2 table. - */ -static void qed_aio_write_flush_before_l2_update(void *opaque, int ret) -{ - QEDAIOCB *acb = opaque; - BDRVQEDState *s = acb_to_s(acb); - - if (!bdrv_aio_flush(s->bs->file->bs, qed_aio_write_l2_update_cb, opaque)) { - qed_aio_complete(acb, -EIO); - } -} - /** * Write data to the image file */ @@ -1076,7 +1044,6 @@ static void qed_aio_write_main(void *opaque, int ret) BDRVQEDState *s = acb_to_s(acb); uint64_t offset = acb->cur_cluster + qed_offset_into_cluster(s, acb->cur_pos); - BlockCompletionFunc *next_fn; trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size); @@ -1085,20 +1052,30 @@ static void qed_aio_write_main(void *opaque, int ret) return; } + BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO); + ret = bdrv_pwritev(s->bs->file, offset, &acb->cur_qiov); + if (ret >= 0) { + ret = 0; + } + if (acb->find_cluster_ret == QED_CLUSTER_FOUND) { - next_fn = qed_aio_next_io_cb; + qed_aio_next_io(acb, ret); } else { if (s->bs->backing) { - next_fn = qed_aio_write_flush_before_l2_update; - } else { - next_fn = qed_aio_write_l2_update_cb; + /* + * Flush new data clusters before updating the L2 table + * + * This flush is necessary when a backing file is in use. A crash + * during an allocating write could result in empty clusters in the + * image. If the write only touched a subregion of the cluster, + * then backing image sectors have been lost in the untouched + * region. The solution is to flush after writing a new data + * cluster and before updating the L2 table. + */ + ret = bdrv_flush(s->bs->file->bs); } + qed_aio_write_l2_update(acb, ret, acb->cur_cluster); } - - BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO); - bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, - &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, - next_fn, acb); } /** |