Signed-off-by: Peter Lieven <p...@kamp.de> --- qemu-img-cmds.hx | 4 ++-- qemu-img.c | 37 +++++++++++++++++++++++++------------ qemu-img.texi | 5 ++++- 3 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index e0b8ab4..266cdf3 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -34,9 +34,9 @@ STEXI ETEXI DEF("convert", img_convert, - "convert [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] [-m iobuf_size] filename [filename2 [...]] output_filename") + "convert [-c] [-p] [-q] [-n] [-a] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] [-m iobuf_size] filename [filename2 [...]] output_filename") STEXI -@item convert [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] [-m @var{iobuf_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-p] [-q] [-n] [-a] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] [-m @var{iobuf_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} ETEXI DEF("info", img_info, diff --git a/qemu-img.c b/qemu-img.c index 0ce5d14..9fa8fd4 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -109,6 +109,7 @@ static void help(void) " '--output' takes the format in which the output must be done (human or json)\n" " '-n' skips the target volume creation (useful if the volume is created\n" " prior to running qemu-img)\n" + " '-a' align write requests to cluster size if possible\n" "\n" "Parameters to check subcommand:\n" " '-r' tries to repair any inconsistencies that are found during the check.\n" @@ -1125,8 +1126,7 @@ out3: static int img_convert(int argc, char **argv) { - int c, n, n1, bs_n, bs_i, compress, cluster_size, - cluster_sectors, skip_create; + int c, n, n1, bs_n, bs_i, compress, cluster_sectors, skip_create; int64_t ret = 0; int progress = 0, flags; const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename; @@ -1144,7 +1144,7 @@ static int img_convert(int argc, char **argv) char *options = NULL; const char *snapshot_name = NULL; int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */ - bool quiet = false; + bool quiet = false, align = false; Error *local_err = NULL; fmt = NULL; @@ -1154,7 +1154,7 @@ static int img_convert(int argc, char **argv) compress = 0; skip_create = 0; for(;;) { - c = getopt(argc, argv, "f:O:B:s:hce6o:pS:m:t:qn"); + c = getopt(argc, argv, "f:O:B:s:hcae6o:pS:m:t:qn"); if (c == -1) { break; } @@ -1175,6 +1175,9 @@ static int img_convert(int argc, char **argv) case 'c': compress = 1; break; + case 'a': + align = true; + break; case 'e': error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); @@ -1402,19 +1405,21 @@ static int img_convert(int argc, char **argv) } } + cluster_sectors = 0; + ret = bdrv_get_info(out_bs, &bdi); + if (ret < 0 && compress) { + error_report("could not get block driver info"); + goto out; + } else { + cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE; + } + if (compress) { - ret = bdrv_get_info(out_bs, &bdi); - if (ret < 0) { - error_report("could not get block driver info"); - goto out; - } - cluster_size = bdi.cluster_size; - if (cluster_size <= 0 || cluster_size > bufsectors * BDRV_SECTOR_SIZE) { + if (cluster_sectors <= 0 || cluster_sectors > bufsectors) { error_report("invalid cluster size"); ret = -1; goto out; } - cluster_sectors = cluster_size >> 9; sector_num = 0; nb_sectors = total_sectors; @@ -1552,6 +1557,14 @@ static int img_convert(int argc, char **argv) n = nb_sectors; } + if (align && cluster_sectors > 0) { + int64_t next_aligned_sector = (sector_num + cluster_sectors); + next_aligned_sector -= next_aligned_sector % cluster_sectors; + if (sector_num + n > next_aligned_sector) { + n = next_aligned_sector - sector_num; + } + } + if (n > bs_offset + bs_sectors - sector_num) { n = bs_offset + bs_sectors - sector_num; } diff --git a/qemu-img.texi b/qemu-img.texi index 87f9d0f..9b1720f 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -179,11 +179,14 @@ Error on reading data @end table -@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] [-m @var{iobuf_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-p] [-n] [-a] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] [-m @var{iobuf_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c} option) or use any format specific options like encryption (@code{-o} option). +If the @code{-a} option is specified write requests will be aligned +to the cluster size of the output image if possible. This is the default +for compressed images. Only the formats @code{qcow} and @code{qcow2} support compression. The compression is read-only. It means that if a compressed sector is -- 1.7.9.5