void *opaque,
bool is_write);
static void coroutine_fn bdrv_co_do_rw(void *opaque);
+static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors);
static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors,
bool is_write, double elapsed_time, uint64_t *wait);
void bdrv_close(BlockDriverState *bs)
{
+ bdrv_flush(bs);
if (bs->drv) {
if (bs->job) {
block_job_cancel_sync(bs->job);
}
+ bdrv_drain_all();
+
if (bs == bs_snapshots) {
bs_snapshots = NULL;
}
if (drv->bdrv_co_write_zeroes &&
buffer_is_zero(bounce_buffer, iov.iov_len)) {
- ret = drv->bdrv_co_write_zeroes(bs, cluster_sector_num,
- cluster_nb_sectors);
+ ret = bdrv_co_do_write_zeroes(bs, cluster_sector_num,
+ cluster_nb_sectors);
} else {
ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
&bounce_qiov);
struct iovec iov;
int ret;
+ /* TODO Emulate only part of misaligned requests instead of letting block
+ * drivers return -ENOTSUP and emulate everything */
+
/* First try the efficient write zeroes operation */
if (drv->bdrv_co_write_zeroes) {
- return drv->bdrv_co_write_zeroes(bs, sector_num, nb_sectors);
+ ret = drv->bdrv_co_write_zeroes(bs, sector_num, nb_sectors);
+ if (ret != -ENOTSUP) {
+ return ret;
+ }
}
/* Fall back to bounce buffer if write zeroes is unsupported */