yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
76daa3
From 0a86fe65bd08fb190d71a0276b8bbddd7853b196 Mon Sep 17 00:00:00 2001
76daa3
From: John Snow <jsnow@redhat.com>
76daa3
Date: Tue, 16 May 2017 21:00:40 +0200
76daa3
Subject: [PATCH 04/27] block: Add errp to b{lk, drv}_truncate()
76daa3
76daa3
RH-Author: John Snow <jsnow@redhat.com>
76daa3
Message-id: <20170516210041.12856-3-jsnow@redhat.com>
76daa3
Patchwork-id: 75198
76daa3
O-Subject: [RHV-7.4 qemu-kvm-rhev PATCH v2 2/3] block: Add errp to b{lk, drv}_truncate()
76daa3
Bugzilla: 1447551
76daa3
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
76daa3
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
76daa3
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
76daa3
76daa3
From: Max Reitz <mreitz@redhat.com>
76daa3
76daa3
For one thing, this allows us to drop the error message generation from
76daa3
qemu-img.c and blockdev.c and instead have it unified in
76daa3
bdrv_truncate().
76daa3
76daa3
Signed-off-by: Max Reitz <mreitz@redhat.com>
76daa3
Message-id: 20170328205129.15138-3-mreitz@redhat.com
76daa3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
76daa3
Signed-off-by: Max Reitz <mreitz@redhat.com>
76daa3
(cherry picked from commit ed3d2ec98a33fbdeabc471b11ff807075f07e996)
76daa3
Signed-off-by: John Snow <jsnow@redhat.com>
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 block.c                        | 16 ++++++++++++----
76daa3
 block/blkdebug.c               |  2 +-
76daa3
 block/block-backend.c          |  5 +++--
76daa3
 block/commit.c                 |  5 +++--
76daa3
 block/crypto.c                 |  2 +-
76daa3
 block/mirror.c                 |  2 +-
76daa3
 block/parallels.c              | 13 ++++++++-----
76daa3
 block/qcow.c                   |  6 +++---
76daa3
 block/qcow2-refcount.c         |  5 ++++-
76daa3
 block/qcow2.c                  | 14 +++++++++-----
76daa3
 block/qed.c                    |  2 +-
76daa3
 block/raw-format.c             |  2 +-
76daa3
 block/vdi.c                    |  4 ++--
76daa3
 block/vhdx-log.c               |  2 +-
76daa3
 block/vhdx.c                   | 10 +++-------
76daa3
 block/vmdk.c                   | 13 +++----------
76daa3
 block/vpc.c                    | 13 +++++++------
76daa3
 blockdev.c                     | 21 +--------------------
76daa3
 include/block/block.h          |  2 +-
76daa3
 include/sysemu/block-backend.h |  2 +-
76daa3
 qemu-img.c                     | 17 ++++-------------
76daa3
 qemu-io-cmds.c                 |  5 +++--
76daa3
 22 files changed, 73 insertions(+), 90 deletions(-)
76daa3
76daa3
diff --git a/block.c b/block.c
76daa3
index 9fca814..6201991 100644
76daa3
--- a/block.c
76daa3
+++ b/block.c
76daa3
@@ -3307,7 +3307,7 @@ exit:
76daa3
 /**
76daa3
  * Truncate file to 'offset' bytes (needed only for file protocols)
76daa3
  */
76daa3
-int bdrv_truncate(BdrvChild *child, int64_t offset)
76daa3
+int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp)
76daa3
 {
76daa3
     BlockDriverState *bs = child->bs;
76daa3
     BlockDriver *drv = bs->drv;
76daa3
@@ -3319,12 +3319,18 @@ int bdrv_truncate(BdrvChild *child, int64_t offset)
76daa3
      *        cannot assert this permission in that case. */
76daa3
     // assert(child->perm & BLK_PERM_RESIZE);
76daa3
 
76daa3
-    if (!drv)
76daa3
+    if (!drv) {
76daa3
+        error_setg(errp, "No medium inserted");
76daa3
         return -ENOMEDIUM;
76daa3
-    if (!drv->bdrv_truncate)
76daa3
+    }
76daa3
+    if (!drv->bdrv_truncate) {
76daa3
+        error_setg(errp, "Image format driver does not support resize");
76daa3
         return -ENOTSUP;
76daa3
-    if (bs->read_only)
76daa3
+    }
76daa3
+    if (bs->read_only) {
76daa3
+        error_setg(errp, "Image is read-only");
76daa3
         return -EACCES;
76daa3
+    }
76daa3
 
76daa3
     ret = drv->bdrv_truncate(bs, offset);
76daa3
     if (ret == 0) {
76daa3
@@ -3332,6 +3338,8 @@ int bdrv_truncate(BdrvChild *child, int64_t offset)
76daa3
         bdrv_dirty_bitmap_truncate(bs);
76daa3
         bdrv_parent_cb_resize(bs);
76daa3
         ++bs->write_gen;
76daa3
+    } else {
76daa3
+        error_setg_errno(errp, -ret, "Failed to resize image");
76daa3
     }
76daa3
     return ret;
76daa3
 }
76daa3
diff --git a/block/blkdebug.c b/block/blkdebug.c
76daa3
index 67e8024..15a9966 100644
76daa3
--- a/block/blkdebug.c
76daa3
+++ b/block/blkdebug.c
76daa3
@@ -663,7 +663,7 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
76daa3
 
76daa3
 static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
76daa3
 {
76daa3
-    return bdrv_truncate(bs->file, offset);
76daa3
+    return bdrv_truncate(bs->file, offset, NULL);
76daa3
 }
76daa3
 
76daa3
 static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
76daa3
diff --git a/block/block-backend.c b/block/block-backend.c
76daa3
index dd131cf..67753ee 100644
76daa3
--- a/block/block-backend.c
76daa3
+++ b/block/block-backend.c
76daa3
@@ -1765,13 +1765,14 @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
76daa3
                    BDRV_REQ_WRITE_COMPRESSED);
76daa3
 }
76daa3
 
76daa3
-int blk_truncate(BlockBackend *blk, int64_t offset)
76daa3
+int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp)
76daa3
 {
76daa3
     if (!blk_is_available(blk)) {
76daa3
+        error_setg(errp, "No medium inserted");
76daa3
         return -ENOMEDIUM;
76daa3
     }
76daa3
 
76daa3
-    return bdrv_truncate(blk->root, offset);
76daa3
+    return bdrv_truncate(blk->root, offset, errp);
76daa3
 }
76daa3
 
76daa3
 static void blk_pdiscard_entry(void *opaque)
76daa3
diff --git a/block/commit.c b/block/commit.c
76daa3
index 91d2c34..76a0d98 100644
76daa3
--- a/block/commit.c
76daa3
+++ b/block/commit.c
76daa3
@@ -151,7 +151,7 @@ static void coroutine_fn commit_run(void *opaque)
76daa3
     }
76daa3
 
76daa3
     if (base_len < s->common.len) {
76daa3
-        ret = blk_truncate(s->base, s->common.len);
76daa3
+        ret = blk_truncate(s->base, s->common.len, NULL);
76daa3
         if (ret) {
76daa3
             goto out;
76daa3
         }
76daa3
@@ -511,8 +511,9 @@ int bdrv_commit(BlockDriverState *bs)
76daa3
      * grow the backing file image if possible.  If not possible,
76daa3
      * we must return an error */
76daa3
     if (length > backing_length) {
76daa3
-        ret = blk_truncate(backing, length);
76daa3
+        ret = blk_truncate(backing, length, &local_err);
76daa3
         if (ret < 0) {
76daa3
+            error_report_err(local_err);
76daa3
             goto ro_cleanup;
76daa3
         }
76daa3
     }
76daa3
diff --git a/block/crypto.c b/block/crypto.c
76daa3
index 4a20388..52e4f2b 100644
76daa3
--- a/block/crypto.c
76daa3
+++ b/block/crypto.c
76daa3
@@ -389,7 +389,7 @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset)
76daa3
 
76daa3
     offset += payload_offset;
76daa3
 
76daa3
-    return bdrv_truncate(bs->file, offset);
76daa3
+    return bdrv_truncate(bs->file, offset, NULL);
76daa3
 }
76daa3
 
76daa3
 static void block_crypto_close(BlockDriverState *bs)
76daa3
diff --git a/block/mirror.c b/block/mirror.c
76daa3
index 164438f..2173a2f 100644
76daa3
--- a/block/mirror.c
76daa3
+++ b/block/mirror.c
76daa3
@@ -724,7 +724,7 @@ static void coroutine_fn mirror_run(void *opaque)
76daa3
         }
76daa3
 
76daa3
         if (s->bdev_length > base_length) {
76daa3
-            ret = blk_truncate(s->target, s->bdev_length);
76daa3
+            ret = blk_truncate(s->target, s->bdev_length, NULL);
76daa3
             if (ret < 0) {
76daa3
                 goto immediate_exit;
76daa3
             }
76daa3
diff --git a/block/parallels.c b/block/parallels.c
76daa3
index 90acf79..8be46a7 100644
76daa3
--- a/block/parallels.c
76daa3
+++ b/block/parallels.c
76daa3
@@ -223,7 +223,8 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
76daa3
                                      space << BDRV_SECTOR_BITS, 0);
76daa3
         } else {
76daa3
             ret = bdrv_truncate(bs->file,
76daa3
-                                (s->data_end + space) << BDRV_SECTOR_BITS);
76daa3
+                                (s->data_end + space) << BDRV_SECTOR_BITS,
76daa3
+                                NULL);
76daa3
         }
76daa3
         if (ret < 0) {
76daa3
             return ret;
76daa3
@@ -456,8 +457,10 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
76daa3
                 size - res->image_end_offset);
76daa3
         res->leaks += count;
76daa3
         if (fix & BDRV_FIX_LEAKS) {
76daa3
-            ret = bdrv_truncate(bs->file, res->image_end_offset);
76daa3
+            Error *local_err = NULL;
76daa3
+            ret = bdrv_truncate(bs->file, res->image_end_offset, &local_err);
76daa3
             if (ret < 0) {
76daa3
+                error_report_err(local_err);
76daa3
                 res->check_errors++;
76daa3
                 return ret;
76daa3
             }
76daa3
@@ -504,7 +507,7 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
76daa3
 
76daa3
     blk_set_allow_write_beyond_eof(file, true);
76daa3
 
76daa3
-    ret = blk_truncate(file, 0);
76daa3
+    ret = blk_truncate(file, 0, errp);
76daa3
     if (ret < 0) {
76daa3
         goto exit;
76daa3
     }
76daa3
@@ -696,7 +699,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
76daa3
     }
76daa3
 
76daa3
     if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) ||
76daa3
-            bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs)) != 0) {
76daa3
+            bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), NULL) != 0) {
76daa3
         s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
76daa3
     }
76daa3
 
76daa3
@@ -739,7 +742,7 @@ static void parallels_close(BlockDriverState *bs)
76daa3
     }
76daa3
 
76daa3
     if (bs->open_flags & BDRV_O_RDWR) {
76daa3
-        bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
76daa3
+        bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, NULL);
76daa3
     }
76daa3
 
76daa3
     g_free(s->bat_dirty_bmap);
76daa3
diff --git a/block/qcow.c b/block/qcow.c
76daa3
index 9d6ac83..5d147b9 100644
76daa3
--- a/block/qcow.c
76daa3
+++ b/block/qcow.c
76daa3
@@ -473,7 +473,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
76daa3
                 /* round to cluster size */
76daa3
                 cluster_offset = (cluster_offset + s->cluster_size - 1) &
76daa3
                     ~(s->cluster_size - 1);
76daa3
-                bdrv_truncate(bs->file, cluster_offset + s->cluster_size);
76daa3
+                bdrv_truncate(bs->file, cluster_offset + s->cluster_size, NULL);
76daa3
                 /* if encrypted, we must initialize the cluster
76daa3
                    content which won't be written */
76daa3
                 if (bs->encrypted &&
76daa3
@@ -833,7 +833,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
76daa3
 
76daa3
     blk_set_allow_write_beyond_eof(qcow_blk, true);
76daa3
 
76daa3
-    ret = blk_truncate(qcow_blk, 0);
76daa3
+    ret = blk_truncate(qcow_blk, 0, errp);
76daa3
     if (ret < 0) {
76daa3
         goto exit;
76daa3
     }
76daa3
@@ -916,7 +916,7 @@ static int qcow_make_empty(BlockDriverState *bs)
76daa3
     if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
76daa3
             l1_length) < 0)
76daa3
         return -1;
76daa3
-    ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
76daa3
+    ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, NULL);
76daa3
     if (ret < 0)
76daa3
         return ret;
76daa3
 
76daa3
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
76daa3
index 9e96f64..4efca7e 100644
76daa3
--- a/block/qcow2-refcount.c
76daa3
+++ b/block/qcow2-refcount.c
76daa3
@@ -1728,14 +1728,17 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
76daa3
 
76daa3
             if (fix & BDRV_FIX_ERRORS) {
76daa3
                 int64_t new_nb_clusters;
76daa3
+                Error *local_err = NULL;
76daa3
 
76daa3
                 if (offset > INT64_MAX - s->cluster_size) {
76daa3
                     ret = -EINVAL;
76daa3
                     goto resize_fail;
76daa3
                 }
76daa3
 
76daa3
-                ret = bdrv_truncate(bs->file, offset + s->cluster_size);
76daa3
+                ret = bdrv_truncate(bs->file, offset + s->cluster_size,
76daa3
+                                    &local_err);
76daa3
                 if (ret < 0) {
76daa3
+                    error_report_err(local_err);
76daa3
                     goto resize_fail;
76daa3
                 }
76daa3
                 size = bdrv_getlength(bs->file->bs);
76daa3
diff --git a/block/qcow2.c b/block/qcow2.c
76daa3
index 6a92d2e..845eee4 100644
76daa3
--- a/block/qcow2.c
76daa3
+++ b/block/qcow2.c
76daa3
@@ -2294,9 +2294,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
76daa3
     }
76daa3
 
76daa3
     /* Okay, now that we have a valid image, let's give it the right size */
76daa3
-    ret = blk_truncate(blk, total_size);
76daa3
+    ret = blk_truncate(blk, total_size, errp);
76daa3
     if (ret < 0) {
76daa3
-        error_setg_errno(errp, -ret, "Could not resize image");
76daa3
+        error_prepend(errp, "Could not resize image: ");
76daa3
         goto out;
76daa3
     }
76daa3
 
76daa3
@@ -2584,7 +2584,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
76daa3
         /* align end of file to a sector boundary to ease reading with
76daa3
            sector based I/Os */
76daa3
         cluster_offset = bdrv_getlength(bs->file->bs);
76daa3
-        return bdrv_truncate(bs->file, cluster_offset);
76daa3
+        return bdrv_truncate(bs->file, cluster_offset, NULL);
76daa3
     }
76daa3
 
76daa3
     buf = qemu_blockalign(bs, s->cluster_size);
76daa3
@@ -2674,6 +2674,7 @@ fail:
76daa3
 static int make_completely_empty(BlockDriverState *bs)
76daa3
 {
76daa3
     BDRVQcow2State *s = bs->opaque;
76daa3
+    Error *local_err = NULL;
76daa3
     int ret, l1_clusters;
76daa3
     int64_t offset;
76daa3
     uint64_t *new_reftable = NULL;
76daa3
@@ -2798,8 +2799,10 @@ static int make_completely_empty(BlockDriverState *bs)
76daa3
         goto fail;
76daa3
     }
76daa3
 
76daa3
-    ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size);
76daa3
+    ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size,
76daa3
+                        &local_err);
76daa3
     if (ret < 0) {
76daa3
+        error_report_err(local_err);
76daa3
         goto fail;
76daa3
     }
76daa3
 
76daa3
@@ -3273,9 +3276,10 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
76daa3
             return ret;
76daa3
         }
76daa3
 
76daa3
-        ret = blk_truncate(blk, new_size);
76daa3
+        ret = blk_truncate(blk, new_size, &local_err);
76daa3
         blk_unref(blk);
76daa3
         if (ret < 0) {
76daa3
+            error_report_err(local_err);
76daa3
             return ret;
76daa3
         }
76daa3
     }
76daa3
diff --git a/block/qed.c b/block/qed.c
76daa3
index 5ec7fd8..53199ac 100644
76daa3
--- a/block/qed.c
76daa3
+++ b/block/qed.c
76daa3
@@ -635,7 +635,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
76daa3
     blk_set_allow_write_beyond_eof(blk, true);
76daa3
 
76daa3
     /* File must start empty and grow, check truncate is supported */
76daa3
-    ret = blk_truncate(blk, 0);
76daa3
+    ret = blk_truncate(blk, 0, errp);
76daa3
     if (ret < 0) {
76daa3
         goto out;
76daa3
     }
76daa3
diff --git a/block/raw-format.c b/block/raw-format.c
76daa3
index 86fbc65..a800733 100644
76daa3
--- a/block/raw-format.c
76daa3
+++ b/block/raw-format.c
76daa3
@@ -341,7 +341,7 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset)
76daa3
 
76daa3
     s->size = offset;
76daa3
     offset += s->offset;
76daa3
-    return bdrv_truncate(bs->file, offset);
76daa3
+    return bdrv_truncate(bs->file, offset, NULL);
76daa3
 }
76daa3
 
76daa3
 static int raw_media_changed(BlockDriverState *bs)
76daa3
diff --git a/block/vdi.c b/block/vdi.c
76daa3
index 9b4f70e..d12d9cd 100644
76daa3
--- a/block/vdi.c
76daa3
+++ b/block/vdi.c
76daa3
@@ -832,9 +832,9 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
76daa3
     }
76daa3
 
76daa3
     if (image_type == VDI_TYPE_STATIC) {
76daa3
-        ret = blk_truncate(blk, offset + blocks * block_size);
76daa3
+        ret = blk_truncate(blk, offset + blocks * block_size, errp);
76daa3
         if (ret < 0) {
76daa3
-            error_setg(errp, "Failed to statically allocate %s", filename);
76daa3
+            error_prepend(errp, "Failed to statically allocate %s", filename);
76daa3
             goto exit;
76daa3
         }
76daa3
     }
76daa3
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
76daa3
index 67a91c0..3f4c2aa 100644
76daa3
--- a/block/vhdx-log.c
76daa3
+++ b/block/vhdx-log.c
76daa3
@@ -548,7 +548,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
76daa3
             if (new_file_size % (1024*1024)) {
76daa3
                 /* round up to nearest 1MB boundary */
76daa3
                 new_file_size = ((new_file_size >> 20) + 1) << 20;
76daa3
-                bdrv_truncate(bs->file, new_file_size);
76daa3
+                bdrv_truncate(bs->file, new_file_size, NULL);
76daa3
             }
76daa3
         }
76daa3
         qemu_vfree(desc_entries);
76daa3
diff --git a/block/vhdx.c b/block/vhdx.c
76daa3
index d25bcd9..e8fe3fb 100644
76daa3
--- a/block/vhdx.c
76daa3
+++ b/block/vhdx.c
76daa3
@@ -1171,7 +1171,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
76daa3
     /* per the spec, the address for a block is in units of 1MB */
76daa3
     *new_offset = ROUND_UP(*new_offset, 1024 * 1024);
76daa3
 
76daa3
-    return bdrv_truncate(bs->file, *new_offset + s->block_size);
76daa3
+    return bdrv_truncate(bs->file, *new_offset + s->block_size, NULL);
76daa3
 }
76daa3
 
76daa3
 /*
76daa3
@@ -1607,17 +1607,13 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
76daa3
     if (type == VHDX_TYPE_DYNAMIC) {
76daa3
         /* All zeroes, so we can just extend the file - the end of the BAT
76daa3
          * is the furthest thing we have written yet */
76daa3
-        ret = blk_truncate(blk, data_file_offset);
76daa3
+        ret = blk_truncate(blk, data_file_offset, errp);
76daa3
         if (ret < 0) {
76daa3
-            error_setg_errno(errp, -ret,
76daa3
-                            "Failed to resize the underlying file");
76daa3
             goto exit;
76daa3
         }
76daa3
     } else if (type == VHDX_TYPE_FIXED) {
76daa3
-        ret = blk_truncate(blk, data_file_offset + image_size);
76daa3
+        ret = blk_truncate(blk, data_file_offset + image_size, errp);
76daa3
         if (ret < 0) {
76daa3
-            error_setg_errno(errp, -ret,
76daa3
-                            "Failed to resize the underlying file");
76daa3
             goto exit;
76daa3
         }
76daa3
     } else {
76daa3
diff --git a/block/vmdk.c b/block/vmdk.c
76daa3
index a9bd22b..c61b9cc 100644
76daa3
--- a/block/vmdk.c
76daa3
+++ b/block/vmdk.c
76daa3
@@ -1714,10 +1714,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
76daa3
     blk_set_allow_write_beyond_eof(blk, true);
76daa3
 
76daa3
     if (flat) {
76daa3
-        ret = blk_truncate(blk, filesize);
76daa3
-        if (ret < 0) {
76daa3
-            error_setg_errno(errp, -ret, "Could not truncate file");
76daa3
-        }
76daa3
+        ret = blk_truncate(blk, filesize, errp);
76daa3
         goto exit;
76daa3
     }
76daa3
     magic = cpu_to_be32(VMDK4_MAGIC);
76daa3
@@ -1780,9 +1777,8 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
76daa3
         goto exit;
76daa3
     }
76daa3
 
76daa3
-    ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9);
76daa3
+    ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, errp);
76daa3
     if (ret < 0) {
76daa3
-        error_setg_errno(errp, -ret, "Could not truncate file");
76daa3
         goto exit;
76daa3
     }
76daa3
 
76daa3
@@ -2090,10 +2086,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
76daa3
     /* bdrv_pwrite write padding zeros to align to sector, we don't need that
76daa3
      * for description file */
76daa3
     if (desc_offset == 0) {
76daa3
-        ret = blk_truncate(new_blk, desc_len);
76daa3
-        if (ret < 0) {
76daa3
-            error_setg_errno(errp, -ret, "Could not truncate file");
76daa3
-        }
76daa3
+        ret = blk_truncate(new_blk, desc_len, errp);
76daa3
     }
76daa3
 exit:
76daa3
     if (new_blk) {
76daa3
diff --git a/block/vpc.c b/block/vpc.c
76daa3
index f591d4b..ecfee77 100644
76daa3
--- a/block/vpc.c
76daa3
+++ b/block/vpc.c
76daa3
@@ -851,20 +851,21 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
76daa3
 }
76daa3
 
76daa3
 static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
76daa3
-                             int64_t total_size)
76daa3
+                             int64_t total_size, Error **errp)
76daa3
 {
76daa3
     int ret;
76daa3
 
76daa3
     /* Add footer to total size */
76daa3
     total_size += HEADER_SIZE;
76daa3
 
76daa3
-    ret = blk_truncate(blk, total_size);
76daa3
+    ret = blk_truncate(blk, total_size, errp);
76daa3
     if (ret < 0) {
76daa3
         return ret;
76daa3
     }
76daa3
 
76daa3
     ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0);
76daa3
     if (ret < 0) {
76daa3
+        error_setg_errno(errp, -ret, "Unable to write VHD header");
76daa3
         return ret;
76daa3
     }
76daa3
 
76daa3
@@ -996,11 +997,11 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
76daa3
 
76daa3
     if (disk_type == VHD_DYNAMIC) {
76daa3
         ret = create_dynamic_disk(blk, buf, total_sectors);
76daa3
+        if (ret < 0) {
76daa3
+            error_setg(errp, "Unable to create or write VHD header");
76daa3
+        }
76daa3
     } else {
76daa3
-        ret = create_fixed_disk(blk, buf, total_size);
76daa3
-    }
76daa3
-    if (ret < 0) {
76daa3
-        error_setg(errp, "Unable to create or write VHD header");
76daa3
+        ret = create_fixed_disk(blk, buf, total_size, errp);
76daa3
     }
76daa3
 
76daa3
 out:
76daa3
diff --git a/blockdev.c b/blockdev.c
76daa3
index 033c3fd..6a50742 100644
76daa3
--- a/blockdev.c
76daa3
+++ b/blockdev.c
76daa3
@@ -2975,26 +2975,7 @@ void qmp_block_resize(bool has_device, const char *device,
76daa3
     /* complete all in-flight operations before resizing the device */
76daa3
     bdrv_drain_all();
76daa3
 
76daa3
-    ret = blk_truncate(blk, size);
76daa3
-    switch (ret) {
76daa3
-    case 0:
76daa3
-        break;
76daa3
-    case -ENOMEDIUM:
76daa3
-        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
76daa3
-        break;
76daa3
-    case -ENOTSUP:
76daa3
-        error_setg(errp, QERR_UNSUPPORTED);
76daa3
-        break;
76daa3
-    case -EACCES:
76daa3
-        error_setg(errp, "Device '%s' is read only", device);
76daa3
-        break;
76daa3
-    case -EBUSY:
76daa3
-        error_setg(errp, QERR_DEVICE_IN_USE, device);
76daa3
-        break;
76daa3
-    default:
76daa3
-        error_setg_errno(errp, -ret, "Could not resize");
76daa3
-        break;
76daa3
-    }
76daa3
+    ret = blk_truncate(blk, size, errp);
76daa3
 
76daa3
 out:
76daa3
     blk_unref(blk);
76daa3
diff --git a/include/block/block.h b/include/block/block.h
76daa3
index 56b27fb..54b70ee 100644
76daa3
--- a/include/block/block.h
76daa3
+++ b/include/block/block.h
76daa3
@@ -294,7 +294,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
76daa3
     const char *backing_file);
76daa3
 int bdrv_get_backing_file_depth(BlockDriverState *bs);
76daa3
 void bdrv_refresh_filename(BlockDriverState *bs);
76daa3
-int bdrv_truncate(BdrvChild *child, int64_t offset);
76daa3
+int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp);
76daa3
 int64_t bdrv_nb_sectors(BlockDriverState *bs);
76daa3
 int64_t bdrv_getlength(BlockDriverState *bs);
76daa3
 int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
76daa3
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
76daa3
index 7462228..0ba4e27 100644
76daa3
--- a/include/sysemu/block-backend.h
76daa3
+++ b/include/sysemu/block-backend.h
76daa3
@@ -225,7 +225,7 @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
76daa3
                                       int count, BdrvRequestFlags flags);
76daa3
 int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
76daa3
                           int count);
76daa3
-int blk_truncate(BlockBackend *blk, int64_t offset);
76daa3
+int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp);
76daa3
 int blk_pdiscard(BlockBackend *blk, int64_t offset, int count);
76daa3
 int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
76daa3
                      int64_t pos, int size);
76daa3
diff --git a/qemu-img.c b/qemu-img.c
76daa3
index b220cf7..37c2894 100644
76daa3
--- a/qemu-img.c
76daa3
+++ b/qemu-img.c
76daa3
@@ -3500,20 +3500,11 @@ static int img_resize(int argc, char **argv)
76daa3
         goto out;
76daa3
     }
76daa3
 
76daa3
-    ret = blk_truncate(blk, total_size);
76daa3
-    switch (ret) {
76daa3
-    case 0:
76daa3
+    ret = blk_truncate(blk, total_size, &err;;
76daa3
+    if (!ret) {
76daa3
         qprintf(quiet, "Image resized.\n");
76daa3
-        break;
76daa3
-    case -ENOTSUP:
76daa3
-        error_report("This image does not support resize");
76daa3
-        break;
76daa3
-    case -EACCES:
76daa3
-        error_report("Image is read-only");
76daa3
-        break;
76daa3
-    default:
76daa3
-        error_report("Error resizing image: %s", strerror(-ret));
76daa3
-        break;
76daa3
+    } else {
76daa3
+        error_report_err(err);
76daa3
     }
76daa3
 out:
76daa3
     blk_unref(blk);
76daa3
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
76daa3
index 312fc6d..21af9e6 100644
76daa3
--- a/qemu-io-cmds.c
76daa3
+++ b/qemu-io-cmds.c
76daa3
@@ -1567,6 +1567,7 @@ static const cmdinfo_t flush_cmd = {
76daa3
 
76daa3
 static int truncate_f(BlockBackend *blk, int argc, char **argv)
76daa3
 {
76daa3
+    Error *local_err = NULL;
76daa3
     int64_t offset;
76daa3
     int ret;
76daa3
 
76daa3
@@ -1576,9 +1577,9 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
76daa3
         return 0;
76daa3
     }
76daa3
 
76daa3
-    ret = blk_truncate(blk, offset);
76daa3
+    ret = blk_truncate(blk, offset, &local_err);
76daa3
     if (ret < 0) {
76daa3
-        printf("truncate: %s\n", strerror(-ret));
76daa3
+        error_report_err(local_err);
76daa3
         return 0;
76daa3
     }
76daa3
 
76daa3
-- 
76daa3
1.8.3.1
76daa3