[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v8 4/4] qcow2: Add full image preallocation option
From: |
Hu Tao |
Subject: |
[Qemu-devel] [PATCH v8 4/4] qcow2: Add full image preallocation option |
Date: |
Wed, 9 Apr 2014 15:12:37 +0800 |
This adds a preallocation=full mode to qcow2 image creation, which
creates a non-sparse image file.
Signed-off-by: Hu Tao <address@hidden>
---
block/qcow2.c | 79 ++++++++++++++++++++++++++++++++++++++++++++--
tests/qemu-iotests/082.out | 54 +++++++++++++++----------------
2 files changed, 103 insertions(+), 30 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index b2ff9c3..1b0034d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1596,6 +1596,7 @@ static int qcow2_create2(const char *filename, int64_t
total_size,
QEMUOptionParameter *options, int version,
Error **errp)
{
+ QEMUOptionParameter *alloc_options = NULL;
/* Calculate cluster_bits */
int cluster_bits;
cluster_bits = ffs(cluster_size) - 1;
@@ -1625,10 +1626,78 @@ static int qcow2_create2(const char *filename, int64_t
total_size,
Error *local_err = NULL;
int ret;
+ if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_METADATA) {
+ int64_t meta_size = 0;
+ unsigned nreftablee, nrefblocke, nl1e, nl2e;
+ BlockDriver *drv;
+
+ total_size = align_offset(total_size, cluster_size);
+
+ drv = bdrv_find_protocol(filename, true);
+ if (drv == NULL) {
+ error_setg(errp, "Could not find protocol for file '%s'",
filename);
+ return -ENOENT;
+ }
+
+ alloc_options = append_option_parameters(alloc_options,
+ drv->create_options);
+ alloc_options = append_option_parameters(alloc_options, options);
+
+ /* header: 1 cluster */
+ meta_size += cluster_size;
+
+ /* total size of L2 tables */
+ nl2e = total_size / cluster_size;
+ nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
+ meta_size += nl2e * sizeof(uint64_t);
+
+ /* total size of L1 tables */
+ nl1e = nl2e * sizeof(uint64_t) / cluster_size;
+ nl1e = align_offset(nl1e, cluster_size / sizeof(uint64_t));
+ meta_size += nl1e * sizeof(uint64_t);
+
+ /* total size of refcount blocks
+ *
+ * note: every host cluster is reference-counted, including metadata
+ * (even refcount blocks are recursively included).
+ * Let:
+ * a = total_size (this is the guest disk size)
+ * m = meta size not including refcount blocks and refcount tables
+ * c = cluster size
+ * y1 = number of refcount blocks entries
+ * y2 = meta size including everything
+ * then,
+ * y1 = (y2 + a)/c
+ * y2 = y1 * sizeof(u16) + y1 * sizeof(u16) * sizeof(u64) / c + m
+ * we can get y1:
+ * y1 = (a + m) / (c - sizeof(u16) - sizeof(u16) * sizeof(u64) / c)
+ */
+ nrefblocke = (total_size + meta_size + cluster_size) /
+ (cluster_size - sizeof(uint16_t) -
+ 1.0 * sizeof(uint16_t) * sizeof(uint64_t) / cluster_size);
+ nrefblocke = align_offset(nrefblocke, cluster_size / sizeof(uint16_t));
+ meta_size += nrefblocke * sizeof(uint16_t);
+
+ /* total size of refcount tables */
+ nreftablee = nrefblocke * sizeof(uint16_t) / cluster_size;
+ nreftablee = align_offset(nreftablee, cluster_size / sizeof(uint64_t));
+ meta_size += nreftablee * sizeof(uint64_t);
+
+ set_option_parameter_int(alloc_options, BLOCK_OPT_SIZE,
+ total_size + meta_size);
+ if (prealloc == PREALLOC_MODE_FULL) {
+ set_option_parameter(alloc_options, BLOCK_OPT_PREALLOC, "full");
+ } else if (prealloc == PREALLOC_MODE_METADATA) {
+ set_option_parameter(alloc_options, BLOCK_OPT_PREALLOC,
"metadata");
+ }
+
+ options = alloc_options;
+ }
+
ret = bdrv_create_file(filename, options, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
- return ret;
+ goto out_options;
}
bs = NULL;
@@ -1636,7 +1705,7 @@ static int qcow2_create2(const char *filename, int64_t
total_size,
NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
- return ret;
+ goto out_options;
}
/* Write the header */
@@ -1758,6 +1827,8 @@ out:
if (bs) {
bdrv_unref(bs);
}
+out_options:
+ free_option_parameters(alloc_options);
return ret;
}
@@ -1793,6 +1864,8 @@ static int qcow2_create(const char *filename,
QEMUOptionParameter *options,
prealloc = PREALLOC_MODE_OFF;
} else if (!strcmp(options->value.s, "metadata")) {
prealloc = PREALLOC_MODE_METADATA;
+ } else if (!strcmp(options->value.s, "full")) {
+ prealloc = PREALLOC_MODE_FULL;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'",
options->value.s);
@@ -2358,7 +2431,7 @@ static QEMUOptionParameter qcow2_create_options[] = {
{
.name = BLOCK_OPT_PREALLOC,
.type = OPT_STRING,
- .help = "Preallocation mode (allowed values: off, metadata)"
+ .help = "Preallocation mode (allowed values: off, metadata, full)"
},
{
.name = BLOCK_OPT_LAZY_REFCOUNTS,
diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out
index 28309a0..5689802 100644
--- a/tests/qemu-iotests/082.out
+++ b/tests/qemu-iotests/082.out
@@ -64,7 +64,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o ? TEST_DIR/t.qcow2 128M
@@ -75,7 +75,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2 128M
@@ -86,7 +86,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2 128M
@@ -97,7 +97,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2 128M
@@ -108,7 +108,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2 128M
@@ -119,7 +119,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2 128M
@@ -130,7 +130,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2 128M
@@ -141,7 +141,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help
TEST_DIR/t.qcow2 128M
@@ -167,7 +167,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: create -o help
@@ -245,7 +245,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o ? TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
@@ -256,7 +256,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
TEST_DIR/t.qcow2.base
@@ -267,7 +267,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
TEST_DIR/t.qcow2.base
@@ -278,7 +278,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
TEST_DIR/t.qcow2.base
@@ -289,7 +289,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
TEST_DIR/t.qcow2.base
@@ -300,7 +300,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
TEST_DIR/t.qcow2.base
@@ -311,7 +311,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
TEST_DIR/t.qcow2.base
@@ -322,7 +322,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -O qcow2 -o backing_file=TEST_DIR/t.qcow2,,help
TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
@@ -348,7 +348,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -o help
@@ -415,7 +415,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o ? TEST_DIR/t.qcow2
@@ -426,7 +426,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o cluster_size=4k,help TEST_DIR/t.qcow2
@@ -437,7 +437,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o cluster_size=4k,? TEST_DIR/t.qcow2
@@ -448,7 +448,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o help,cluster_size=4k TEST_DIR/t.qcow2
@@ -459,7 +459,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o ?,cluster_size=4k TEST_DIR/t.qcow2
@@ -470,7 +470,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o cluster_size=4k -o help TEST_DIR/t.qcow2
@@ -481,7 +481,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o cluster_size=4k -o ? TEST_DIR/t.qcow2
@@ -492,7 +492,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: amend -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2
@@ -520,7 +520,7 @@ backing_file File name of a base image
backing_fmt Image format of the base image
encryption Encrypt the image
cluster_size qcow2 cluster size
-preallocation Preallocation mode (allowed values: off, metadata)
+preallocation Preallocation mode (allowed values: off, metadata, full)
lazy_refcounts Postpone refcount updates
Testing: convert -o help
--
1.8.5.2.229.g4448466
- [Qemu-devel] [PATCH v8 0/4] qemu-img: add preallocation=full, Hu Tao, 2014/04/09
- [Qemu-devel] [PATCH v8 1/4] qapi: introduce PreallocMode and a new PreallocMode full., Hu Tao, 2014/04/09
- [Qemu-devel] [PATCH v8 3/4] raw-posix: Add full image preallocation option, Hu Tao, 2014/04/09
- [Qemu-devel] [PATCH v8 2/4] raw, qcow2: don't convert file size to sector size, Hu Tao, 2014/04/09
- [Qemu-devel] [PATCH v8 4/4] qcow2: Add full image preallocation option,
Hu Tao <=
- Re: [Qemu-devel] [PATCH v8 0/4] qemu-img: add preallocation=full, Hu Tao, 2014/04/23