From 43716fa8058a9095b9c1f9be4397dbaf7c521ee0 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 26 Jun 2014 13:23:21 +0200 Subject: block: Use bdrv_nb_sectors() in img_convert() Instead of bdrv_getlength(). Replace variable output_length by output_sectors. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Stefan Hajnoczi --- qemu-img.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'qemu-img.c') diff --git a/qemu-img.c b/qemu-img.c index d4518e7..9832a7e 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1469,13 +1469,13 @@ static int img_convert(int argc, char **argv) buf = qemu_blockalign(out_bs, bufsectors * BDRV_SECTOR_SIZE); if (skip_create) { - int64_t output_length = bdrv_getlength(out_bs); - if (output_length < 0) { + int64_t output_sectors = bdrv_nb_sectors(out_bs); + if (output_sectors < 0) { error_report("unable to get output image length: %s\n", - strerror(-output_length)); + strerror(-output_sectors)); ret = -1; goto out; - } else if (output_length < total_sectors << BDRV_SECTOR_BITS) { + } else if (output_sectors < total_sectors) { error_report("output file is smaller than input file"); ret = -1; goto out; -- cgit v1.1 From d739f1c41094141268a33fa8fc6715fbab714fbe Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 26 Jun 2014 13:23:24 +0200 Subject: qemu-img: Make img_convert() get image size just once per image Chiefly so I don't have to do the error checking in quadruplicate in the next commit. Moreover, replacing the frequently updated bs_sectors by an array assigned just once makes the code easier to understand. Signed-off-by: Markus Armbruster Reviewed-by: Max Reitz Reviewed-by: Benoit Canet Signed-off-by: Stefan Hajnoczi --- qemu-img.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'qemu-img.c') diff --git a/qemu-img.c b/qemu-img.c index 9832a7e..b832997 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1182,7 +1182,7 @@ static int img_convert(int argc, char **argv) BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; int64_t total_sectors, nb_sectors, sector_num, bs_offset; - uint64_t bs_sectors; + uint64_t *bs_sectors = NULL; uint8_t * buf = NULL; size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE; const uint8_t *buf1; @@ -1323,7 +1323,8 @@ static int img_convert(int argc, char **argv) qemu_progress_print(0, 100); - bs = g_malloc0(bs_n * sizeof(BlockDriverState *)); + bs = g_new0(BlockDriverState *, bs_n); + bs_sectors = g_new(uint64_t, bs_n); total_sectors = 0; for (bs_i = 0; bs_i < bs_n; bs_i++) { @@ -1337,8 +1338,8 @@ static int img_convert(int argc, char **argv) ret = -1; goto out; } - bdrv_get_geometry(bs[bs_i], &bs_sectors); - total_sectors += bs_sectors; + bdrv_get_geometry(bs[bs_i], &bs_sectors[bs_i]); + total_sectors += bs_sectors[bs_i]; } if (sn_opts) { @@ -1456,7 +1457,6 @@ static int img_convert(int argc, char **argv) bs_i = 0; bs_offset = 0; - bdrv_get_geometry(bs[0], &bs_sectors); /* increase bufsectors from the default 4096 (2M) if opt_transfer_length * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB) @@ -1523,19 +1523,19 @@ static int img_convert(int argc, char **argv) buf2 = buf; while (remainder > 0) { int nlow; - while (bs_num == bs_sectors) { + while (bs_num == bs_sectors[bs_i]) { + bs_offset += bs_sectors[bs_i]; bs_i++; assert (bs_i < bs_n); - bs_offset += bs_sectors; - bdrv_get_geometry(bs[bs_i], &bs_sectors); bs_num = 0; /* printf("changing part: sector_num=%" PRId64 ", " "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64 - "\n", sector_num, bs_i, bs_offset, bs_sectors); */ + "\n", sector_num, bs_i, bs_offset, bs_sectors[bs_i]); */ } - assert (bs_num < bs_sectors); + assert (bs_num < bs_sectors[bs_i]); - nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder; + nlow = remainder > bs_sectors[bs_i] - bs_num + ? bs_sectors[bs_i] - bs_num : remainder; ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow); if (ret < 0) { @@ -1596,14 +1596,13 @@ restart: break; } - while (sector_num - bs_offset >= bs_sectors) { + while (sector_num - bs_offset >= bs_sectors[bs_i]) { + bs_offset += bs_sectors[bs_i]; bs_i ++; assert (bs_i < bs_n); - bs_offset += bs_sectors; - bdrv_get_geometry(bs[bs_i], &bs_sectors); /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, " "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n", - sector_num, bs_i, bs_offset, bs_sectors); */ + sector_num, bs_i, bs_offset, bs_sectors[bs_i]); */ } if ((out_baseimg || has_zero_init) && @@ -1656,7 +1655,7 @@ restart: } } - n = MIN(n, bs_sectors - (sector_num - bs_offset)); + n = MIN(n, bs_sectors[bs_i] - (sector_num - bs_offset)); sectors_read += n; if (count_allocated_sectors) { @@ -1714,6 +1713,7 @@ out: } g_free(bs); } + g_free(bs_sectors); fail_getopt: g_free(options); -- cgit v1.1 From 52bf1e722d996d1accfc35e29283f172d003d9b2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 26 Jun 2014 13:23:25 +0200 Subject: block: Avoid bdrv_get_geometry() where errors should be detected bdrv_get_geometry() hides errors. Use bdrv_nb_sectors() or bdrv_getlength() instead where that's obviously inappropriate. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Max Reitz Reviewed-by: Benoit Canet Signed-off-by: Stefan Hajnoczi --- qemu-img.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 14 deletions(-) (limited to 'qemu-img.c') diff --git a/qemu-img.c b/qemu-img.c index b832997..9566fae 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -955,7 +955,6 @@ static int img_compare(int argc, char **argv) int64_t sector_num = 0; int64_t nb_sectors; int c, pnum; - uint64_t bs_sectors; uint64_t progress_base; for (;;) { @@ -1017,10 +1016,20 @@ static int img_compare(int argc, char **argv) buf1 = qemu_blockalign(bs1, IO_BUF_SIZE); buf2 = qemu_blockalign(bs2, IO_BUF_SIZE); - bdrv_get_geometry(bs1, &bs_sectors); - total_sectors1 = bs_sectors; - bdrv_get_geometry(bs2, &bs_sectors); - total_sectors2 = bs_sectors; + total_sectors1 = bdrv_nb_sectors(bs1); + if (total_sectors1 < 0) { + error_report("Can't get size of %s: %s", + filename1, strerror(-total_sectors1)); + ret = 4; + goto out; + } + total_sectors2 = bdrv_nb_sectors(bs2); + if (total_sectors2 < 0) { + error_report("Can't get size of %s: %s", + filename2, strerror(-total_sectors2)); + ret = 4; + goto out; + } total_sectors = MIN(total_sectors1, total_sectors2); progress_base = MAX(total_sectors1, total_sectors2); @@ -1182,7 +1191,7 @@ static int img_convert(int argc, char **argv) BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; int64_t total_sectors, nb_sectors, sector_num, bs_offset; - uint64_t *bs_sectors = NULL; + int64_t *bs_sectors = NULL; uint8_t * buf = NULL; size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE; const uint8_t *buf1; @@ -1324,7 +1333,7 @@ static int img_convert(int argc, char **argv) qemu_progress_print(0, 100); bs = g_new0(BlockDriverState *, bs_n); - bs_sectors = g_new(uint64_t, bs_n); + bs_sectors = g_new(int64_t, bs_n); total_sectors = 0; for (bs_i = 0; bs_i < bs_n; bs_i++) { @@ -1338,7 +1347,13 @@ static int img_convert(int argc, char **argv) ret = -1; goto out; } - bdrv_get_geometry(bs[bs_i], &bs_sectors[bs_i]); + bs_sectors[bs_i] = bdrv_nb_sectors(bs[bs_i]); + if (bs_sectors[bs_i] < 0) { + error_report("Could not get size of %s: %s", + argv[optind + bs_i], strerror(-bs_sectors[bs_i])); + ret = -1; + goto out; + } total_sectors += bs_sectors[bs_i]; } @@ -2413,9 +2428,9 @@ static int img_rebase(int argc, char **argv) * the image is the same as the original one at any time. */ if (!unsafe) { - uint64_t num_sectors; - uint64_t old_backing_num_sectors; - uint64_t new_backing_num_sectors = 0; + int64_t num_sectors; + int64_t old_backing_num_sectors; + int64_t new_backing_num_sectors = 0; uint64_t sector; int n; uint8_t * buf_old; @@ -2425,10 +2440,31 @@ static int img_rebase(int argc, char **argv) buf_old = qemu_blockalign(bs, IO_BUF_SIZE); buf_new = qemu_blockalign(bs, IO_BUF_SIZE); - bdrv_get_geometry(bs, &num_sectors); - bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors); + num_sectors = bdrv_nb_sectors(bs); + if (num_sectors < 0) { + error_report("Could not get size of '%s': %s", + filename, strerror(-num_sectors)); + ret = -1; + goto out; + } + old_backing_num_sectors = bdrv_nb_sectors(bs_old_backing); + if (old_backing_num_sectors < 0) { + char backing_name[1024]; + + bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name)); + error_report("Could not get size of '%s': %s", + backing_name, strerror(-old_backing_num_sectors)); + ret = -1; + goto out; + } if (bs_new_backing) { - bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors); + new_backing_num_sectors = bdrv_nb_sectors(bs_new_backing); + if (new_backing_num_sectors < 0) { + error_report("Could not get size of '%s': %s", + out_baseimg, strerror(-new_backing_num_sectors)); + ret = -1; + goto out; + } } if (num_sectors != 0) { -- cgit v1.1