#include "qemu/module.h"
#include "qemu/sockets.h"
#include "qemu/units.h"
+#include "qemu/memalign.h"
#include "qom/object_interfaces.h"
#include "sysemu/block-backend.h"
#include "block/block_int.h"
printf(" %s", name);
}
-static void QEMU_NORETURN GCC_FMT_ATTR(1, 2) error_exit(const char *fmt, ...)
+static void QEMU_NORETURN G_GNUC_PRINTF(1, 2) error_exit(const char *fmt, ...)
{
va_list ap;
},
};
-static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...)
+static int G_GNUC_PRINTF(2, 3) qprintf(bool quiet, const char *fmt, ...)
{
int ret = 0;
if (!quiet) {
static void run_block_job(BlockJob *job, Error **errp)
{
uint64_t progress_current, progress_total;
- AioContext *aio_context = blk_get_aio_context(job->blk);
+ AioContext *aio_context = block_job_get_aio_context(job);
int ret = 0;
aio_context_acquire(aio_context);
}
}
+ if (i == n) {
+ /*
+ * The whole buf is the same.
+ * No reason to split it into chunks, so return now.
+ */
+ *pnum = i;
+ return !is_zero;
+ }
+
tail = (sector_num + i) & (alignment - 1);
if (tail) {
if (is_zero && i <= tail) {
- /* treat unallocated areas which only consist
- * of a small tail as allocated. */
+ /*
+ * For sure next sector after i is data, and it will rewrite this
+ * tail anyway due to RMW. So, let's just write data now.
+ */
is_zero = false;
}
if (!is_zero) {
- /* align up end offset of allocated areas. */
+ /* If possible, align up end offset of allocated areas. */
i += alignment - tail;
i = MIN(i, n);
} else {
- /* align down end offset of zero areas. */
+ /*
+ * For sure next sector after i is data, and it will rewrite this
+ * tail anyway due to RMW. Better is avoid RMW and write zeroes up
+ * to aligned bound.
+ */
i -= tail;
}
}
int c, bs_i, flags, src_flags = BDRV_O_NO_SHARE;
const char *fmt = NULL, *out_fmt = NULL, *cache = "unsafe",
*src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL,
- *out_filename, *out_baseimg_param, *snapshot_name = NULL;
+ *out_filename, *out_baseimg_param, *snapshot_name = NULL,
+ *backing_fmt = NULL;
BlockDriver *drv = NULL, *proto_drv = NULL;
BlockDriverInfo bdi;
BlockDriverState *out_bs;
{"skip-broken-bitmaps", no_argument, 0, OPTION_SKIP_BROKEN},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, ":hf:O:B:Cco:l:S:pt:T:qnm:WUr:",
+ c = getopt_long(argc, argv, ":hf:O:B:CcF:o:l:S:pt:T:qnm:WUr:",
long_options, NULL);
if (c == -1) {
break;
case 'c':
s.compressed = true;
break;
+ case 'F':
+ backing_fmt = optarg;
+ break;
case 'o':
if (accumulate_options(&options, optarg) < 0) {
goto fail_getopt;
qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
s.total_sectors * BDRV_SECTOR_SIZE, &error_abort);
- ret = add_old_style_options(out_fmt, opts, out_baseimg, NULL);
+ ret = add_old_style_options(out_fmt, opts, out_baseimg, backing_fmt);
if (ret < 0) {
goto out;
}
goto out;
}
+ if (flags & BDRV_O_NOCACHE) {
+ /*
+ * If we open the target with O_DIRECT, it may be necessary to
+ * extend its size to align to the physical sector size.
+ */
+ flags |= BDRV_O_RESIZE;
+ }
+
if (skip_create) {
s.target = img_open(tgt_image_opts, out_filename, out_fmt,
flags, writethrough, s.quiet, false);
{
const img_cmd_t *cmd;
const char *cmdname;
- Error *local_error = NULL;
int c;
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
module_call_init(MODULE_INIT_TRACE);
qemu_init_exec_dir(argv[0]);
- if (qemu_init_main_loop(&local_error)) {
- error_report_err(local_error);
- exit(EXIT_FAILURE);
- }
+ qemu_init_main_loop(&error_fatal);
qcrypto_init(&error_fatal);