diff --git a/qemu-img.c b/qemu-img.c index ea62d2d61e..62b29e7feb 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -3381,7 +3381,7 @@ static int img_resize(int argc, char **argv) Error *err = NULL; int c, ret, relative; const char *filename, *fmt, *size; - int64_t n, total_size, current_size; + int64_t n, total_size, current_size, new_size; bool quiet = false; BlockBackend *blk = NULL; PreallocMode prealloc = PREALLOC_MODE_OFF; @@ -3557,11 +3557,42 @@ static int img_resize(int argc, char **argv) } ret = blk_truncate(blk, total_size, prealloc, &err); - if (!ret) { - qprintf(quiet, "Image resized.\n"); - } else { + if (ret < 0) { error_report_err(err); + goto out; } + + new_size = blk_getlength(blk); + if (new_size < 0) { + error_report("Failed to verify truncated image length: %s", + strerror(-new_size)); + ret = -1; + goto out; + } + + /* Some block drivers implement a truncation method, but only so + * the user can cause qemu to refresh the image's size from disk. + * The idea is that the user resizes the image outside of qemu and + * then invokes block_resize to inform qemu about it. + * (This includes iscsi and file-posix for device files.) + * Of course, that is not the behavior someone invoking + * qemu-img resize would find useful, so we catch that behavior + * here and tell the user. */ + if (new_size != total_size && new_size == current_size) { + error_report("Image was not resized; resizing may not be supported " + "for this image"); + ret = -1; + goto out; + } + + if (new_size != total_size) { + warn_report("Image should have been resized to %" PRIi64 + " bytes, but was resized to %" PRIi64 " bytes", + total_size, new_size); + } + + qprintf(quiet, "Image resized.\n"); + out: blk_unref(blk); if (ret) {