Blame 0013-block-expect-errors-from-bdrv_co_is_allocated.patch

298366
From da4e203efa76f2d2ee0a17670c241881963d033d Mon Sep 17 00:00:00 2001
298366
From: Paolo Bonzini <pbonzini@redhat.com>
298366
Date: Wed, 4 Sep 2013 19:00:25 +0200
298366
Subject: [PATCH] block: expect errors from bdrv_co_is_allocated
298366
298366
Some bdrv_is_allocated callers do not expect errors, but the fallback
298366
in qcow2.c might make other callers trip on assertion failures or
298366
infinite loops.
298366
298366
Fix the callers to always look for errors.
298366
298366
Cc: qemu-stable@nongnu.org
298366
Reviewed-by: Eric Blake <eblake@redhat.com>
298366
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
298366
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
298366
(cherry picked from commit d663640c04f2aab810915c556390211d75457704)
298366
298366
Conflicts:
298366
298366
	block/cow.c
298366
298366
*modified to avoid dependency on upstream's e641c1e8
298366
298366
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
298366
---
298366
 block.c        |  7 +++++--
298366
 block/cow.c    |  6 +++++-
298366
 block/qcow2.c  |  4 +---
298366
 block/stream.c |  2 +-
298366
 qemu-img.c     | 16 ++++++++++++++--
298366
 qemu-io-cmds.c |  4 ++++
298366
 6 files changed, 30 insertions(+), 9 deletions(-)
298366
298366
diff --git a/block.c b/block.c
298366
index d5ce8d3..8ce8b91 100644
298366
--- a/block.c
298366
+++ b/block.c
298366
@@ -1803,8 +1803,11 @@ int bdrv_commit(BlockDriverState *bs)
298366
     buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
298366
 
298366
     for (sector = 0; sector < total_sectors; sector += n) {
298366
-        if (bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
298366
-
298366
+        ret = bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n);
298366
+        if (ret < 0) {
298366
+            goto ro_cleanup;
298366
+        }
298366
+        if (ret) {
298366
             if (bdrv_read(bs, sector, buf, n) != 0) {
298366
                 ret = -EIO;
298366
                 goto ro_cleanup;
298366
diff --git a/block/cow.c b/block/cow.c
298366
index 1cc2e89..e1b73d6 100644
298366
--- a/block/cow.c
298366
+++ b/block/cow.c
298366
@@ -189,7 +189,11 @@ static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,
298366
     int ret, n;
298366
 
298366
     while (nb_sectors > 0) {
298366
-        if (bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n)) {
298366
+        ret = bdrv_co_is_allocated(bs, sector_num, nb_sectors, &n);
298366
+        if (ret < 0) {
298366
+            return ret;
298366
+        }
298366
+        if (ret) {
298366
             ret = bdrv_pread(bs->file,
298366
                         s->cow_sectors_offset + sector_num * 512,
298366
                         buf, n * 512);
298366
diff --git a/block/qcow2.c b/block/qcow2.c
298366
index 3376901..7f7282e 100644
298366
--- a/block/qcow2.c
298366
+++ b/block/qcow2.c
298366
@@ -648,13 +648,11 @@ static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,
298366
     int ret;
298366
 
298366
     *pnum = nb_sectors;
298366
-    /* FIXME We can get errors here, but the bdrv_co_is_allocated interface
298366
-     * can't pass them on today */
298366
     qemu_co_mutex_lock(&s->lock);
298366
     ret = qcow2_get_cluster_offset(bs, sector_num << 9, pnum, &cluster_offset);
298366
     qemu_co_mutex_unlock(&s->lock);
298366
     if (ret < 0) {
298366
-        *pnum = 0;
298366
+        return ret;
298366
     }
298366
 
298366
     return (cluster_offset != 0) || (ret == QCOW2_CLUSTER_ZERO);
298366
diff --git a/block/stream.c b/block/stream.c
298366
index 7fe9e48..4e8d177 100644
298366
--- a/block/stream.c
298366
+++ b/block/stream.c
298366
@@ -120,7 +120,7 @@ wait:
298366
         if (ret == 1) {
298366
             /* Allocated in the top, no need to copy.  */
298366
             copy = false;
298366
-        } else {
298366
+        } else if (ret >= 0) {
298366
             /* Copy if allocated in the intermediate images.  Limit to the
298366
              * known-unallocated area [sector_num, sector_num+n).  */
298366
             ret = bdrv_co_is_allocated_above(bs->backing_hd, base,
298366
diff --git a/qemu-img.c b/qemu-img.c
298366
index b9a848d..b01998b 100644
298366
--- a/qemu-img.c
298366
+++ b/qemu-img.c
298366
@@ -1485,8 +1485,15 @@ static int img_convert(int argc, char **argv)
298366
                    are present in both the output's and input's base images (no
298366
                    need to copy them). */
298366
                 if (out_baseimg) {
298366
-                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
298366
-                                           n, &n1)) {
298366
+                    ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,
298366
+                                            n, &n1;;
298366
+                    if (ret < 0) {
298366
+                        error_report("error while reading metadata for sector "
298366
+                                     "%" PRId64 ": %s",
298366
+                                     sector_num - bs_offset, strerror(-ret));
298366
+                        goto out;
298366
+                    }
298366
+                    if (!ret) {
298366
                         sector_num += n1;
298366
                         continue;
298366
                     }
298366
@@ -2076,6 +2083,11 @@ static int img_rebase(int argc, char **argv)
298366
 
298366
             /* If the cluster is allocated, we don't need to take action */
298366
             ret = bdrv_is_allocated(bs, sector, n, &n);
298366
+            if (ret < 0) {
298366
+                error_report("error while reading image metadata: %s",
298366
+                             strerror(-ret));
298366
+                goto out;
298366
+            }
298366
             if (ret) {
298366
                 continue;
298366
             }
298366
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
298366
index ffbcf31..ffe48ad 100644
298366
--- a/qemu-io-cmds.c
298366
+++ b/qemu-io-cmds.c
298366
@@ -1829,6 +1829,10 @@ static int alloc_f(BlockDriverState *bs, int argc, char **argv)
298366
     sector_num = offset >> 9;
298366
     while (remaining) {
298366
         ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
298366
+        if (ret < 0) {
298366
+            printf("is_allocated failed: %s\n", strerror(-ret));
298366
+            return 0;
298366
+        }
298366
         sector_num += num;
298366
         remaining -= num;
298366
         if (ret) {