summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2018-01-11 14:38:34 +0100
committerKevin Wolf <kwolf@redhat.com>2018-03-09 15:17:47 +0100
commite4b5dad8269b1b629c52be25e6da50644293abf7 (patch)
treefdd4507e10c4daf08cf99d3233856002806215e0
parent60900b7bd930e0b9acad118ead4fabf4610066a8 (diff)
downloadqemu-e4b5dad8269b1b629c52be25e6da50644293abf7.zip
qcow2: Handle full/falloc preallocation in qcow2_co_create()
Once qcow2_co_create() can be called directly on an already existing node, we must provide the 'full' and 'falloc' preallocation modes outside of creating the image on the protocol layer. Fortunately, we have preallocated truncate now which can provide this functionality. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
-rw-r--r--block/qcow2.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index e1821eb3c8..933c612754 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2908,6 +2908,25 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp)
}
blk_set_allow_write_beyond_eof(blk, true);
+ /* Clear the protocol layer and preallocate it if necessary */
+ ret = blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp);
+ if (ret < 0) {
+ goto out;
+ }
+
+ if (qcow2_opts->preallocation == PREALLOC_MODE_FULL ||
+ qcow2_opts->preallocation == PREALLOC_MODE_FALLOC)
+ {
+ int64_t prealloc_size =
+ qcow2_calc_prealloc_size(qcow2_opts->size, cluster_size,
+ refcount_order);
+
+ ret = blk_truncate(blk, prealloc_size, qcow2_opts->preallocation, errp);
+ if (ret < 0) {
+ goto out;
+ }
+ }
+
/* Write the header */
QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header));
header = g_malloc0(cluster_size);
@@ -3145,15 +3164,6 @@ static int coroutine_fn qcow2_co_create_opts(const char *filename, QemuOpts *opt
/* Create and open the file (protocol layer) */
- if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
- int refcount_order = ctz32(refcount_bits);
- int64_t prealloc_size =
- qcow2_calc_prealloc_size(size, cluster_size, refcount_order);
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort);
- qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc),
- &error_abort);
- }
-
ret = bdrv_create_file(filename, opts, errp);
if (ret < 0) {
goto finish;