Message ID | 1366596479-22212-4-git-send-email-famz@redhat.com |
---|---|
State | New |
Headers | show |
On Mon, Apr 22, 2013 at 10:07:57AM +0800, Fam Zheng wrote: > Add image create option "zeroed-grain" to enable zeroed-grain GTE > feature of vmdk sparse extents. When this option is on, header version > of newly created extent will be 2 and VMDK4_FLAG_ZG flag bit will be > set. > Signed-off-by: Fam Zheng <famz@redhat.com> > --- > block/vmdk.c | 22 +++++++++++++++++----- > 1 file changed, 17 insertions(+), 5 deletions(-) Is there a way to upgrade an image file to use zeroed-grain GTEs once the file has been created? Stefan
On Mon, 04/22 16:06, Stefan Hajnoczi wrote: > On Mon, Apr 22, 2013 at 10:07:57AM +0800, Fam Zheng wrote: > > Add image create option "zeroed-grain" to enable zeroed-grain GTE > > feature of vmdk sparse extents. When this option is on, header version > > of newly created extent will be 2 and VMDK4_FLAG_ZG flag bit will be > > set. > > Signed-off-by: Fam Zheng <famz@redhat.com> > > --- > > block/vmdk.c | 22 +++++++++++++++++----- > > 1 file changed, 17 insertions(+), 5 deletions(-) > > Is there a way to upgrade an image file to use zeroed-grain GTEs once > the file has been created? > Yes. We have discussed this on IRC. Here's how we do it: - If file version is 2 and zeroed-grain GTE bit set in header, we can support bdrv_co_write_zeroes (this patch series implemented). - If the file version is 2, we can enable zeroed-grain flag in header on bdrv_co_write_zeroes, and use zeroed-grain GTE. (need another patch to update the header). - Otherwize, -ENOTSUP For background, here's how vmware uses this feature: - On shrinking a *child* disk (e.g.: vmware-vdiskmanager -k child.vmdk), if the child cluster is filled with zero, then the image version is upgraded to 2 and zeroed-grian flag is set, and zeroed-grain GTE is used to clear out the cluster, no need to take care of parent cluster allocation and actual data at all. That's where the efficiency comes.
On Tue, Apr 23, 2013 at 08:52:02AM +0800, Fam Zheng wrote: > On Mon, 04/22 16:06, Stefan Hajnoczi wrote: > > On Mon, Apr 22, 2013 at 10:07:57AM +0800, Fam Zheng wrote: > > > Add image create option "zeroed-grain" to enable zeroed-grain GTE > > > feature of vmdk sparse extents. When this option is on, header version > > > of newly created extent will be 2 and VMDK4_FLAG_ZG flag bit will be > > > set. > > > Signed-off-by: Fam Zheng <famz@redhat.com> > > > --- > > > block/vmdk.c | 22 +++++++++++++++++----- > > > 1 file changed, 17 insertions(+), 5 deletions(-) > > > > Is there a way to upgrade an image file to use zeroed-grain GTEs once > > the file has been created? > > > > Yes. We have discussed this on IRC. > > Here's how we do it: > - If file version is 2 and zeroed-grain GTE bit set in header, we can > support bdrv_co_write_zeroes (this patch series implemented). > - If the file version is 2, we can enable zeroed-grain flag in header > on bdrv_co_write_zeroes, and use zeroed-grain GTE. (need another > patch to update the header). > - Otherwize, -ENOTSUP > > For background, here's how vmware uses this feature: > - On shrinking a *child* disk (e.g.: vmware-vdiskmanager -k > child.vmdk), if the child cluster is filled with zero, then the image > version is upgraded to 2 and zeroed-grian flag is set, and > zeroed-grain GTE is used to clear out the cluster, no need to take > care of parent cluster allocation and actual data at all. That's > where the efficiency comes. The question is when QEMU should upgrade images. It's safest to avoid silently increasing the image file's version requirements. But it would be nice to allow upgrading if the users wishes to do that. It doesn't need to be solved in this patch series. Stefan
diff --git a/block/vmdk.c b/block/vmdk.c index 7e07c0f..d8c6c70 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -48,6 +48,8 @@ #define VMDK_UNALLOC (-2) #define VMDK_ZEROED (-3) +#define BLOCK_OPT_ZEROED_GRAIN "zeroed_grain" + typedef struct { uint32_t version; uint32_t flags; @@ -1262,7 +1264,7 @@ static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num, static int vmdk_create_extent(const char *filename, int64_t filesize, - bool flat, bool compress) + bool flat, bool compress, bool zeroed_grain) { int ret, i; int fd = 0; @@ -1284,9 +1286,10 @@ static int vmdk_create_extent(const char *filename, int64_t filesize, } magic = cpu_to_be32(VMDK4_MAGIC); memset(&header, 0, sizeof(header)); - header.version = 1; - header.flags = - 3 | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0); + header.version = zeroed_grain ? 2 : 1; + header.flags = 3 + | (compress ? VMDK4_FLAG_COMPRESS | VMDK4_FLAG_MARKER : 0) + | (zeroed_grain ? VMDK4_FLAG_ZG : 0); header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0; header.capacity = filesize / 512; header.granularity = 128; @@ -1467,6 +1470,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) char parent_desc_line[BUF_SIZE] = ""; uint32_t parent_cid = 0xffffffff; uint32_t number_heads = 16; + bool zeroed_grain = false; const char desc_template[] = "# Disk DescriptorFile\n" "version=1\n" @@ -1502,6 +1506,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0; } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) { fmt = options->value.s; + } else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) { + zeroed_grain |= options->value.n; } options++; } @@ -1588,7 +1594,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options) snprintf(ext_filename, sizeof(ext_filename), "%s%s", path, desc_filename); - if (vmdk_create_extent(ext_filename, size, flat, compress)) { + if (vmdk_create_extent(ext_filename, size, + flat, compress, zeroed_grain)) { return -EINVAL; } filesize -= size; @@ -1714,6 +1721,11 @@ static QEMUOptionParameter vmdk_create_options[] = { "VMDK flat extent format, can be one of " "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} " }, + { + .name = BLOCK_OPT_ZEROED_GRAIN, + .type = OPT_FLAG, + .help = "Enable efficient zero writes using the zeroed-grain GTE feature" + }, { NULL } };
Add image create option "zeroed-grain" to enable zeroed-grain GTE feature of vmdk sparse extents. When this option is on, header version of newly created extent will be 2 and VMDK4_FLAG_ZG flag bit will be set. Signed-off-by: Fam Zheng <famz@redhat.com> --- block/vmdk.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)