218e99
From ebd7d27935a5ec9d5c72403fc1cd60af2e450e7c Mon Sep 17 00:00:00 2001
218e99
From: Paolo Bonzini <pbonzini@redhat.com>
218e99
Date: Fri, 18 Oct 2013 08:14:33 +0200
218e99
Subject: [PATCH 08/81] block: expect errors from bdrv_co_is_allocated
218e99
218e99
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
218e99
Message-id: <1382084091-16636-9-git-send-email-pbonzini@redhat.com>
218e99
Patchwork-id: 54992
218e99
O-Subject: [RHEL 7.0 qemu-kvm PATCH 08/26] block: expect errors from bdrv_co_is_allocated
218e99
Bugzilla: 989646
218e99
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
218e99
RH-Acked-by: Max Reitz <mreitz@redhat.com>
218e99
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
218e99
218e99
Some bdrv_is_allocated callers do not expect errors, but the fallback
218e99
in qcow2.c might make other callers trip on assertion failures or
218e99
infinite loops.
218e99
218e99
Fix the callers to always look for errors.
218e99
218e99
Cc: qemu-stable@nongnu.org
218e99
Reviewed-by: Eric Blake <eblake@redhat.com>
218e99
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
218e99
(cherry picked from commit d663640c04f2aab810915c556390211d75457704)
218e99
---
218e99
 block.c        |  7 +++++--
218e99
 block/cow.c    |  6 +++++-
218e99
 block/qcow2.c  |  4 +---
218e99
 block/stream.c |  2 +-
218e99
 qemu-img.c     | 16 ++++++++++++++--
218e99
 qemu-io.c      |  4 ++++
218e99
 6 files changed, 30 insertions(+), 9 deletions(-)
218e99
218e99
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
218e99
---
218e99
 block.c        |    7 +++++--
218e99
 block/cow.c    |    6 +++++-
218e99
 block/qcow2.c  |    4 +---
218e99
 block/stream.c |    2 +-
218e99
 qemu-img.c     |   16 ++++++++++++++--
218e99
 qemu-io.c      |    4 ++++
218e99
 6 files changed, 30 insertions(+), 9 deletions(-)
218e99
218e99
diff --git a/block.c b/block.c
218e99
index 46d9420..d838a3c 100644
218e99
--- a/block.c
218e99
+++ b/block.c
218e99
@@ -1815,8 +1815,11 @@ int bdrv_commit(BlockDriverState *bs)
218e99
     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
218e99
 
218e99
     for (sector = 0; sector < total_sectors; sector += n) {
218e99
-        if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
218e99
-
218e99
+        ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
218e99
+        if (ret < 0) {
218e99
+            goto ro_cleanup;
218e99
+        }
218e99
+        if (ret) {
218e99
             if (bdrv_read(bs, sector, buf, n) != 0) {
218e99
                 ret = -EIO;
218e99
                 goto ro_cleanup;
218e99
diff --git a/block/cow.c b/block/cow.c
218e99
index 21bceaa..5a33b46 100644
218e99
--- a/block/cow.c
218e99
+++ b/block/cow.c
218e99
@@ -212,7 +212,11 @@ static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,
218e99
     int ret, n;
218e99
 
218e99
     while (nb_sectors > 0) {
218e99
-        if (cow_co_is_allocated(bs, sector_num, nb_sectors, &n)) {
218e99
+        ret = cow_co_is_allocated(bs, sector_num, nb_sectors, &n);
218e99
+        if (ret < 0) {
218e99
+            return ret;
218e99
+        }
218e99
+        if (ret) {
218e99
             ret = bdrv_pread(bs->file,
218e99
                         s->cow_sectors_offset + sector_num * 512,
218e99
                         buf, n * 512);
218e99
diff --git a/block/qcow2.c b/block/qcow2.c
218e99
index 70da5bd..f6e64d2 100644
218e99
--- a/block/qcow2.c
218e99
+++ b/block/qcow2.c
218e99
@@ -648,13 +648,11 @@ static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,
218e99
     int ret;
218e99
 
218e99
     *pnum = nb_sectors;
218e99
-    /* FIXME We can get errors here, but the bdrv_co_is_allocated interface
218e99
-     * can't pass them on today */
218e99
     qemu_co_mutex_lock(&s->lock);
218e99
     ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset);
218e99
     qemu_co_mutex_unlock(&s->lock);
218e99
     if (ret < 0) {
218e99
-        *pnum = 0;
218e99
+        return ret;
218e99
     }
218e99
 
218e99
     return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
218e99
diff --git a/block/stream.c b/block/stream.c
218e99
index 9674c31..995b97b 100644
218e99
--- a/block/stream.c
218e99
+++ b/block/stream.c
218e99
@@ -120,7 +120,7 @@ wait:
218e99
         if (ret == 1) {
218e99
             /* Allocated in the top, no need to copy.  */
218e99
             copy = false;
218e99
-        } else {
218e99
+        } else if (ret >= 0) {
218e99
             /* Copy if allocated in the intermediate images.  Limit to the
218e99
              * known-unallocated area [sector_num, sector_num+n).  */
218e99
             ret = bdrv_is_allocated_above(bs->backing_hd, base,
218e99
diff --git a/qemu-img.c b/qemu-img.c
218e99
index 3b11414..28efb4f 100644
218e99
--- a/qemu-img.c
218e99
+++ b/qemu-img.c
218e99
@@ -1482,8 +1482,15 @@ static int img_convert(int argc, char **argv)
218e99
                    are present in both the output's and input's base images (no
218e99
                    need to copy them). */
218e99
                 if (out_baseimg) {
218e99
-                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
218e99
-                                           n, &n1)) {
218e99
+                    ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
218e99
+                                            n, &n1);
218e99
+                    if (ret < 0) {
218e99
+                        error_report("error while reading metadata for sector "
218e99
+                                     "%" PRId64 ": %s",
218e99
+                                     sector_num - bs_offset, strerror(-ret));
218e99
+                        goto out;
218e99
+                    }
218e99
+                    if (!ret) {
218e99
                         sector_num += n1;
218e99
                         continue;
218e99
                     }
218e99
@@ -2217,6 +2224,11 @@ static int img_rebase(int argc, char **argv)
218e99
 
218e99
             /* If the cluster is allocated, we don't need to take action */
218e99
             ret = bdrv_is_allocated(bs, sector, n, &n);
218e99
+            if (ret < 0) {
218e99
+                error_report("error while reading image metadata: %s",
218e99
+                             strerror(-ret));
218e99
+                goto out;
218e99
+            }
218e99
             if (ret) {
218e99
                 continue;
218e99
             }
218e99
diff --git a/qemu-io.c b/qemu-io.c
218e99
index 5045ff8..bdcce7f 100644
218e99
--- a/qemu-io.c
218e99
+++ b/qemu-io.c
218e99
@@ -1607,6 +1607,10 @@ static int alloc_f(int argc, char **argv)
218e99
     sector_num = offset >> 9;
218e99
     while (remaining) {
218e99
         ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
218e99
+        if (ret < 0) {
218e99
+            printf("is_allocated failed: %s\n", strerror(-ret));
218e99
+            return 0;
218e99
+        }
218e99
         sector_num += num;
218e99
         remaining -= num;
218e99
         if (ret) {
218e99
-- 
218e99
1.7.1
218e99