From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:46735) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UT2K0-0006a3-Iz for qemu-devel@nongnu.org; Thu, 18 Apr 2013 23:49:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UT2Jy-0000aF-1h for qemu-devel@nongnu.org; Thu, 18 Apr 2013 23:49:12 -0400 Received: from mx1.redhat.com ([209.132.183.28]:64259) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UT2Jx-0000a5-Ql for qemu-devel@nongnu.org; Thu, 18 Apr 2013 23:49:09 -0400 From: Fam Zheng Date: Fri, 19 Apr 2013 11:48:45 +0800 Message-Id: <1366343325-5252-6-git-send-email-famz@redhat.com> In-Reply-To: <1366343325-5252-1-git-send-email-famz@redhat.com> References: <1366343325-5252-1-git-send-email-famz@redhat.com> Subject: [Qemu-devel] [PATCH 5/5] vmdk: add bdrv_co_write_zeroes List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, Fam Zheng , stefanha@redhat.com, Feiran Zheng From: Feiran Zheng Use special offset to write zeroes efficiently, when zeroed-grain GTE is available. If zero-write an allocated cluster, cluster is leaked because its offset pointer is overwritten by "0x1". Signed-off-by: Fam Zheng --- block/vmdk.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 5daa9f2..3055847 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1163,8 +1163,16 @@ static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num, return ret; } +/** + * params: + * - zeroed: buf is ignored (data is zero), use zeroed_grain GTE + * feature if possible, otherwise return -ENOTSUP. + * - zero_dry_run: used for zeroed == true only, don't update L2 table, just + * try if it's supported + */ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors) + const uint8_t *buf, int nb_sectors, + bool zeroed, bool zero_dry_run) { BDRVVmdkState *s = bs->opaque; VmdkExtent *extent = NULL; @@ -1220,17 +1228,30 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, if (n > nb_sectors) { n = nb_sectors; } - - ret = vmdk_write_extent(extent, - cluster_offset, index_in_cluster * 512, - buf, n, sector_num); - if (ret) { - return ret; - } - if (m_data.valid) { - /* update L2 tables */ - if (vmdk_L2update(extent, &m_data) == -1) { - return -EIO; + if (zeroed) { + /* Do zeroed write, buf is ignored */ + if (extent->has_zero_grain && + index_in_cluster == 0 && + n >= extent->cluster_sectors) { + n = extent->cluster_sectors; + if (!zero_dry_run) { + m_data.offset = VMDK_GTE_ZEROED; + } + } else { + return -ENOTSUP; + } + } else { + ret = vmdk_write_extent(extent, + cluster_offset, index_in_cluster * 512, + buf, n, sector_num); + if (ret) { + return ret; + } + if (m_data.valid) { + /* update L2 tables */ + if (vmdk_L2update(extent, &m_data) == -1) { + return -EIO; + } } } nb_sectors -= n; @@ -1256,7 +1277,22 @@ static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num, int ret; BDRVVmdkState *s = bs->opaque; qemu_co_mutex_lock(&s->lock); - ret = vmdk_write(bs, sector_num, buf, nb_sectors); + ret = vmdk_write(bs, sector_num, buf, nb_sectors, false, false); + qemu_co_mutex_unlock(&s->lock); + return ret; +} + +static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs, + int64_t sector_num, + int nb_sectors) +{ + int ret; + BDRVVmdkState *s = bs->opaque; + qemu_co_mutex_lock(&s->lock); + ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true); + if (!ret) { + ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false); + } qemu_co_mutex_unlock(&s->lock); return ret; } @@ -1736,6 +1772,7 @@ static BlockDriver bdrv_vmdk = { .bdrv_reopen_prepare = vmdk_reopen_prepare, .bdrv_read = vmdk_co_read, .bdrv_write = vmdk_co_write, + .bdrv_co_write_zeroes = vmdk_co_write_zeroes, .bdrv_close = vmdk_close, .bdrv_create = vmdk_create, .bdrv_co_flush_to_disk = vmdk_co_flush, -- 1.8.1.4