Blame 0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch

Justin M. Forbes 45e84a
From 5bb37d151b026759ee35f04212b11b4d625c7431 Mon Sep 17 00:00:00 2001
Justin M. Forbes 45e84a
From: Kevin Wolf <kwolf@redhat.com>
Justin M. Forbes 45e84a
Date: Wed, 7 Dec 2011 12:42:10 +0100
Justin M. Forbes 45e84a
Subject: [PATCH 23/25] qemu-img rebase: Fix for undersized backing files
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Backing files may be smaller than the corresponding COW file. When
Justin M. Forbes 45e84a
reading directly from the backing file, qemu-img rebase must consider
Justin M. Forbes 45e84a
this and assume zero sectors after the end of backing files.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Justin M. Forbes 45e84a
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Justin M. Forbes 45e84a
---
Justin M. Forbes 45e84a
 qemu-img.c |   42 +++++++++++++++++++++++++++++++++---------
Justin M. Forbes 45e84a
 1 files changed, 33 insertions(+), 9 deletions(-)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
diff --git a/qemu-img.c b/qemu-img.c
Justin M. Forbes 45e84a
index 8bdae66..01cc0d3 100644
Justin M. Forbes 45e84a
--- a/qemu-img.c
Justin M. Forbes 45e84a
+++ b/qemu-img.c
Justin M. Forbes 45e84a
@@ -1420,6 +1420,8 @@ static int img_rebase(int argc, char **argv)
Justin M. Forbes 45e84a
      */
Justin M. Forbes 45e84a
     if (!unsafe) {
Justin M. Forbes 45e84a
         uint64_t num_sectors;
Justin M. Forbes 45e84a
+        uint64_t old_backing_num_sectors;
Justin M. Forbes 45e84a
+        uint64_t new_backing_num_sectors;
Justin M. Forbes 45e84a
         uint64_t sector;
Justin M. Forbes 45e84a
         int n;
Justin M. Forbes 45e84a
         uint8_t * buf_old;
Justin M. Forbes 45e84a
@@ -1430,6 +1432,8 @@ static int img_rebase(int argc, char **argv)
Justin M. Forbes 45e84a
         buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
         bdrv_get_geometry(bs, &num_sectors);
Justin M. Forbes 45e84a
+        bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
Justin M. Forbes 45e84a
+        bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
         local_progress = (float)100 /
Justin M. Forbes 45e84a
             (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
Justin M. Forbes 45e84a
@@ -1448,16 +1452,36 @@ static int img_rebase(int argc, char **argv)
Justin M. Forbes 45e84a
                 continue;
Justin M. Forbes 45e84a
             }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-            /* Read old and new backing file */
Justin M. Forbes 45e84a
-            ret = bdrv_read(bs_old_backing, sector, buf_old, n);
Justin M. Forbes 45e84a
-            if (ret < 0) {
Justin M. Forbes 45e84a
-                error_report("error while reading from old backing file");
Justin M. Forbes 45e84a
-                goto out;
Justin M. Forbes 45e84a
+            /*
Justin M. Forbes 45e84a
+             * Read old and new backing file and take into consideration that
Justin M. Forbes 45e84a
+             * backing files may be smaller than the COW image.
Justin M. Forbes 45e84a
+             */
Justin M. Forbes 45e84a
+            if (sector >= old_backing_num_sectors) {
Justin M. Forbes 45e84a
+                memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
Justin M. Forbes 45e84a
+            } else {
Justin M. Forbes 45e84a
+                if (sector + n > old_backing_num_sectors) {
Justin M. Forbes 45e84a
+                    n = old_backing_num_sectors - sector;
Justin M. Forbes 45e84a
+                }
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+                ret = bdrv_read(bs_old_backing, sector, buf_old, n);
Justin M. Forbes 45e84a
+                if (ret < 0) {
Justin M. Forbes 45e84a
+                    error_report("error while reading from old backing file");
Justin M. Forbes 45e84a
+                    goto out;
Justin M. Forbes 45e84a
+                }
Justin M. Forbes 45e84a
             }
Justin M. Forbes 45e84a
-            ret = bdrv_read(bs_new_backing, sector, buf_new, n);
Justin M. Forbes 45e84a
-            if (ret < 0) {
Justin M. Forbes 45e84a
-                error_report("error while reading from new backing file");
Justin M. Forbes 45e84a
-                goto out;
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+            if (sector >= new_backing_num_sectors) {
Justin M. Forbes 45e84a
+                memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
Justin M. Forbes 45e84a
+            } else {
Justin M. Forbes 45e84a
+                if (sector + n > new_backing_num_sectors) {
Justin M. Forbes 45e84a
+                    n = new_backing_num_sectors - sector;
Justin M. Forbes 45e84a
+                }
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+                ret = bdrv_read(bs_new_backing, sector, buf_new, n);
Justin M. Forbes 45e84a
+                if (ret < 0) {
Justin M. Forbes 45e84a
+                    error_report("error while reading from new backing file");
Justin M. Forbes 45e84a
+                    goto out;
Justin M. Forbes 45e84a
+                }
Justin M. Forbes 45e84a
             }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
             /* If they differ, we need to write to the COW file */
Justin M. Forbes 45e84a
-- 
Justin M. Forbes 45e84a
1.7.7.5
Justin M. Forbes 45e84a