diff --git a/block/block-backend.c b/block/block-backend.c index e042544025..4bc72658f9 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -870,6 +870,11 @@ int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset, flags | BDRV_REQ_ZERO_WRITE); } +int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags) +{ + return bdrv_make_zero(blk->root, flags); +} + static void error_callback_bh(void *opaque) { struct BlockBackendAIOCB *acb = opaque; diff --git a/block/io.c b/block/io.c index 7f86c06fe7..4e6e1c4557 100644 --- a/block/io.c +++ b/block/io.c @@ -649,7 +649,7 @@ int bdrv_write(BdrvChild *child, int64_t sector_num, true, 0); } -int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, +int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset, int count, BdrvRequestFlags flags) { QEMUIOVector qiov; @@ -659,7 +659,7 @@ int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, }; qemu_iovec_init_external(&qiov, &iov, 1); - return bdrv_prwv_co(bs, offset, &qiov, true, + return bdrv_prwv_co(child->bs, offset, &qiov, true, BDRV_REQ_ZERO_WRITE | flags); } @@ -672,9 +672,10 @@ int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, * * Returns < 0 on error, 0 on success. For error codes see bdrv_write(). */ -int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) +int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags) { int64_t target_sectors, ret, nb_sectors, sector_num = 0; + BlockDriverState *bs = child->bs; BlockDriverState *file; int n; @@ -698,7 +699,7 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags) sector_num += n; continue; } - ret = bdrv_pwrite_zeroes(bs, sector_num << BDRV_SECTOR_BITS, + ret = bdrv_pwrite_zeroes(child, sector_num << BDRV_SECTOR_BITS, n << BDRV_SECTOR_BITS, flags); if (ret < 0) { error_report("error writing zeroes at sector %" PRId64 ": %s", diff --git a/block/parallels.c b/block/parallels.c index 4542eb8a0f..807a80169f 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -210,7 +210,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num, int ret; space += s->prealloc_size; if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { - ret = bdrv_pwrite_zeroes(bs->file->bs, + ret = bdrv_pwrite_zeroes(bs->file, s->data_end << BDRV_SECTOR_BITS, space << BDRV_SECTOR_BITS, 0); } else { diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 0cd7fdf3de..6a3ad90744 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1752,7 +1752,7 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table, goto fail; } - ret = bdrv_pwrite_zeroes(bs->file->bs, offset, s->cluster_size, 0); + ret = bdrv_pwrite_zeroes(bs->file, offset, s->cluster_size, 0); if (ret < 0) { if (!preallocated) { qcow2_free_clusters(bs, offset, s->cluster_size, diff --git a/block/qcow2.c b/block/qcow2.c index 090dc6d92e..a289c12225 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2709,7 +2709,7 @@ static int make_completely_empty(BlockDriverState *bs) /* After this call, neither the in-memory nor the on-disk refcount * information accurately describe the actual references */ - ret = bdrv_pwrite_zeroes(bs->file->bs, s->l1_table_offset, + ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset, l1_clusters * s->cluster_size, 0); if (ret < 0) { goto fail_broken_refcounts; @@ -2723,7 +2723,7 @@ static int make_completely_empty(BlockDriverState *bs) * overwrite parts of the existing refcount and L1 table, which is not * an issue because the dirty flag is set, complete data loss is in fact * desired and partial data loss is consequently fine as well */ - ret = bdrv_pwrite_zeroes(bs->file->bs, s->cluster_size, + ret = bdrv_pwrite_zeroes(bs->file, s->cluster_size, (2 + l1_clusters) * s->cluster_size, 0); /* This call (even if it failed overall) may have overwritten on-disk * refcount structures; in that case, the in-memory refcount information diff --git a/include/block/block.h b/include/block/block.h index 59fd20b101..4eaa1c1325 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -230,9 +230,9 @@ int bdrv_read(BdrvChild *child, int64_t sector_num, uint8_t *buf, int nb_sectors); int bdrv_write(BdrvChild *child, int64_t sector_num, const uint8_t *buf, int nb_sectors); -int bdrv_pwrite_zeroes(BlockDriverState *bs, int64_t offset, +int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset, int count, BdrvRequestFlags flags); -int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags); +int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags); int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int bytes); int bdrv_preadv(BdrvChild *child, int64_t offset, QEMUIOVector *qiov); int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int bytes); diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 2469a1c15b..3c3e82f05d 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -124,6 +124,7 @@ int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset, BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset, int count, BdrvRequestFlags flags, BlockCompletionFunc *cb, void *opaque); +int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags); int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count); int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count, BdrvRequestFlags flags); diff --git a/qemu-img.c b/qemu-img.c index 3a7c162fb0..2e04e281aa 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1648,7 +1648,7 @@ static int convert_do_copy(ImgConvertState *s) if (!s->has_zero_init && !s->target_has_backing && bdrv_can_write_zeroes_with_unmap(blk_bs(s->target))) { - ret = bdrv_make_zero(blk_bs(s->target), BDRV_REQ_MAY_UNMAP); + ret = blk_make_zero(s->target, BDRV_REQ_MAY_UNMAP); if (ret == 0) { s->has_zero_init = true; }