9ae3a8
From ca635f6c3ae10562a2165590bb84667aa61ad12f Mon Sep 17 00:00:00 2001
9ae3a8
From: Max Reitz <mreitz@redhat.com>
9ae3a8
Date: Mon, 4 Nov 2013 22:32:29 +0100
9ae3a8
Subject: [PATCH 36/87] qcow2: Use negated overflow check mask
9ae3a8
9ae3a8
RH-Author: Max Reitz <mreitz@redhat.com>
9ae3a8
Message-id: <1383604354-12743-39-git-send-email-mreitz@redhat.com>
9ae3a8
Patchwork-id: 55338
9ae3a8
O-Subject: [RHEL-7.0 qemu-kvm PATCH 38/43] qcow2: Use negated overflow check mask
9ae3a8
Bugzilla: 1004347
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
9ae3a8
BZ: 1004347
9ae3a8
9ae3a8
In qcow2_check_metadata_overlap and qcow2_pre_write_overlap_check,
9ae3a8
change the parameter signifying the checks to perform from its current
9ae3a8
positive form to a negative one, i.e., it will no longer explicitly
9ae3a8
specify every check to perform but rather a mask of checks not to
9ae3a8
perform.
9ae3a8
9ae3a8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
(cherry picked from commit 231bb267644ee3a9ebfd9c7f42d5d41610194b45)
9ae3a8
9ae3a8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9ae3a8
9ae3a8
Conflicts:
9ae3a8
	block/qcow2-cluster.c
9ae3a8
9ae3a8
Conflicts because downstream does not contain
9ae3a8
expand_zero_clusters_in_l1().
9ae3a8
---
9ae3a8
 block/qcow2-cache.c    |  8 +++-----
9ae3a8
 block/qcow2-cluster.c  |  9 ++++-----
9ae3a8
 block/qcow2-refcount.c | 22 ++++++++++------------
9ae3a8
 block/qcow2-snapshot.c | 12 +++++-------
9ae3a8
 block/qcow2.c          |  5 ++---
9ae3a8
 block/qcow2.h          |  4 ++--
9ae3a8
 6 files changed, 26 insertions(+), 34 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/qcow2-cache.c    |    8 +++-----
9ae3a8
 block/qcow2-cluster.c  |    9 ++++-----
9ae3a8
 block/qcow2-refcount.c |   22 ++++++++++------------
9ae3a8
 block/qcow2-snapshot.c |   12 +++++-------
9ae3a8
 block/qcow2.c          |    5 ++---
9ae3a8
 block/qcow2.h          |    4 ++--
9ae3a8
 6 files changed, 26 insertions(+), 34 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
9ae3a8
index 7bcae09..eb1d69b 100644
9ae3a8
--- a/block/qcow2-cache.c
9ae3a8
+++ b/block/qcow2-cache.c
9ae3a8
@@ -115,15 +115,13 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
9ae3a8
     }
9ae3a8
 
9ae3a8
     if (c == s->refcount_block_cache) {
9ae3a8
-        ret = qcow2_pre_write_overlap_check(bs,
9ae3a8
-                QCOW2_OL_DEFAULT & ~QCOW2_OL_REFCOUNT_BLOCK,
9ae3a8
+        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_REFCOUNT_BLOCK,
9ae3a8
                 c->entries[i].offset, s->cluster_size);
9ae3a8
     } else if (c == s->l2_table_cache) {
9ae3a8
-        ret = qcow2_pre_write_overlap_check(bs,
9ae3a8
-                QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L2,
9ae3a8
+        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
9ae3a8
                 c->entries[i].offset, s->cluster_size);
9ae3a8
     } else {
9ae3a8
-        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
9ae3a8
+        ret = qcow2_pre_write_overlap_check(bs, 0,
9ae3a8
                 c->entries[i].offset, s->cluster_size);
9ae3a8
     }
9ae3a8
 
9ae3a8
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
9ae3a8
index c05f182..5d13515 100644
9ae3a8
--- a/block/qcow2-cluster.c
9ae3a8
+++ b/block/qcow2-cluster.c
9ae3a8
@@ -83,8 +83,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
9ae3a8
 
9ae3a8
     /* the L1 position has not yet been updated, so these clusters must
9ae3a8
      * indeed be completely free */
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
9ae3a8
-                                        new_l1_table_offset, new_l1_size2);
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, 0, new_l1_table_offset,
9ae3a8
+                                        new_l1_size2);
9ae3a8
     if (ret < 0) {
9ae3a8
         goto fail;
9ae3a8
     }
9ae3a8
@@ -160,8 +160,7 @@ int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
9ae3a8
         buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
9ae3a8
     }
9ae3a8
 
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs,
9ae3a8
-            QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L1,
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
9ae3a8
             s->l1_table_offset + 8 * l1_start_index, sizeof(buf));
9ae3a8
     if (ret < 0) {
9ae3a8
         return ret;
9ae3a8
@@ -386,7 +385,7 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
9ae3a8
                         &s->aes_encrypt_key);
9ae3a8
     }
9ae3a8
 
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, 0,
9ae3a8
             cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);
9ae3a8
     if (ret < 0) {
9ae3a8
         goto out;
9ae3a8
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
9ae3a8
index 5c5683d..91c446b 100644
9ae3a8
--- a/block/qcow2-refcount.c
9ae3a8
+++ b/block/qcow2-refcount.c
9ae3a8
@@ -1291,9 +1291,8 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
9ae3a8
         }
9ae3a8
 
9ae3a8
         if (l2_dirty) {
9ae3a8
-            ret = qcow2_pre_write_overlap_check(bs,
9ae3a8
-                    QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L2, l2_offset,
9ae3a8
-                    s->cluster_size);
9ae3a8
+            ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
9ae3a8
+                                                l2_offset, s->cluster_size);
9ae3a8
             if (ret < 0) {
9ae3a8
                 fprintf(stderr, "ERROR: Could not write L2 table; metadata "
9ae3a8
                         "overlap check failed: %s\n", strerror(-ret));
9ae3a8
@@ -1334,8 +1333,7 @@ static int write_reftable_entry(BlockDriverState *bs, int rt_index)
9ae3a8
         buf[i] = cpu_to_be64(s->refcount_table[rt_start_index + i]);
9ae3a8
     }
9ae3a8
 
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs,
9ae3a8
-            QCOW2_OL_DEFAULT & ~QCOW2_OL_REFCOUNT_TABLE,
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_REFCOUNT_TABLE,
9ae3a8
             s->refcount_table_offset + rt_start_index * sizeof(uint64_t),
9ae3a8
             sizeof(buf));
9ae3a8
     if (ret < 0) {
9ae3a8
@@ -1386,8 +1384,7 @@ static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,
9ae3a8
 
9ae3a8
     /* new block has not yet been entered into refcount table, therefore it is
9ae3a8
      * no refcount block yet (regarding this check) */
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, new_offset,
9ae3a8
-            s->cluster_size);
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, 0, new_offset, s->cluster_size);
9ae3a8
     if (ret < 0) {
9ae3a8
         fprintf(stderr, "Could not write refcount block; metadata overlap "
9ae3a8
                 "check failed: %s\n", strerror(-ret));
9ae3a8
@@ -1619,8 +1616,8 @@ fail:
9ae3a8
  * looking for overlaps with important metadata sections (L1/L2 tables etc.),
9ae3a8
  * i.e. a sanity check without relying on the refcount tables.
9ae3a8
  *
9ae3a8
- * The chk parameter specifies exactly what checks to perform (being a bitmask
9ae3a8
- * of QCow2MetadataOverlap values).
9ae3a8
+ * The ign parameter specifies what checks not to perform (being a bitmask of
9ae3a8
+ * QCow2MetadataOverlap values), i.e., what sections to ignore.
9ae3a8
  *
9ae3a8
  * Returns:
9ae3a8
  * - 0 if writing to this offset will not affect the mentioned metadata
9ae3a8
@@ -1628,10 +1625,11 @@ fail:
9ae3a8
  * - a negative value (-errno) indicating an error while performing a check,
9ae3a8
  *   e.g. when bdrv_read failed on QCOW2_OL_INACTIVE_L2
9ae3a8
  */
9ae3a8
-int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
9ae3a8
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
9ae3a8
                                  int64_t size)
9ae3a8
 {
9ae3a8
     BDRVQcowState *s = bs->opaque;
9ae3a8
+    int chk = QCOW2_OL_DEFAULT & ~ign;
9ae3a8
     int i, j;
9ae3a8
 
9ae3a8
     if (!size) {
9ae3a8
@@ -1747,10 +1745,10 @@ static const char *metadata_ol_names[] = {
9ae3a8
  * Returns 0 if there were neither overlaps nor errors while checking for
9ae3a8
  * overlaps; or a negative value (-errno) on error.
9ae3a8
  */
9ae3a8
-int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
9ae3a8
+int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
9ae3a8
                                   int64_t size)
9ae3a8
 {
9ae3a8
-    int ret = qcow2_check_metadata_overlap(bs, chk, offset, size);
9ae3a8
+    int ret = qcow2_check_metadata_overlap(bs, ign, offset, size);
9ae3a8
 
9ae3a8
     if (ret < 0) {
9ae3a8
         return ret;
9ae3a8
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
9ae3a8
index 450e4f5..aa88c51 100644
9ae3a8
--- a/block/qcow2-snapshot.c
9ae3a8
+++ b/block/qcow2-snapshot.c
9ae3a8
@@ -191,8 +191,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
9ae3a8
 
9ae3a8
     /* The snapshot list position has not yet been updated, so these clusters
9ae3a8
      * must indeed be completely free */
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
9ae3a8
-                                        snapshots_size);
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size);
9ae3a8
     if (ret < 0) {
9ae3a8
         return ret;
9ae3a8
     }
9ae3a8
@@ -372,8 +371,8 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
9ae3a8
         l1_table[i] = cpu_to_be64(s->l1_table[i]);
9ae3a8
     }
9ae3a8
 
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
9ae3a8
-            sn->l1_table_offset, s->l1_size * sizeof(uint64_t));
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, 0, sn->l1_table_offset,
9ae3a8
+                                        s->l1_size * sizeof(uint64_t));
9ae3a8
     if (ret < 0) {
9ae3a8
         goto fail;
9ae3a8
     }
9ae3a8
@@ -490,9 +489,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
9ae3a8
         goto fail;
9ae3a8
     }
9ae3a8
 
9ae3a8
-    ret = qcow2_pre_write_overlap_check(bs,
9ae3a8
-            QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L1,
9ae3a8
-            s->l1_table_offset, cur_l1_bytes);
9ae3a8
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
9ae3a8
+                                        s->l1_table_offset, cur_l1_bytes);
9ae3a8
     if (ret < 0) {
9ae3a8
         goto fail;
9ae3a8
     }
9ae3a8
diff --git a/block/qcow2.c b/block/qcow2.c
9ae3a8
index 8b73518..ac5ed47 100644
9ae3a8
--- a/block/qcow2.c
9ae3a8
+++ b/block/qcow2.c
9ae3a8
@@ -964,7 +964,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
9ae3a8
                 cur_nr_sectors * 512);
9ae3a8
         }
9ae3a8
 
9ae3a8
-        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
9ae3a8
+        ret = qcow2_pre_write_overlap_check(bs, 0,
9ae3a8
                 cluster_offset + index_in_cluster * BDRV_SECTOR_SIZE,
9ae3a8
                 cur_nr_sectors * BDRV_SECTOR_SIZE);
9ae3a8
         if (ret < 0) {
9ae3a8
@@ -1748,8 +1748,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
9ae3a8
         }
9ae3a8
         cluster_offset &= s->cluster_offset_mask;
9ae3a8
 
9ae3a8
-        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
9ae3a8
-                cluster_offset, out_len);
9ae3a8
+        ret = qcow2_pre_write_overlap_check(bs, 0, cluster_offset, out_len);
9ae3a8
         if (ret < 0) {
9ae3a8
             goto fail;
9ae3a8
         }
9ae3a8
diff --git a/block/qcow2.h b/block/qcow2.h
9ae3a8
index 10b7bf4..64ad43c 100644
9ae3a8
--- a/block/qcow2.h
9ae3a8
+++ b/block/qcow2.h
9ae3a8
@@ -424,9 +424,9 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
9ae3a8
 
9ae3a8
 void qcow2_process_discards(BlockDriverState *bs, int ret);
9ae3a8
 
9ae3a8
-int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
9ae3a8
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
9ae3a8
                                  int64_t size);
9ae3a8
-int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
9ae3a8
+int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
9ae3a8
                                   int64_t size);
9ae3a8
 
9ae3a8
 /* qcow2-cluster.c functions */
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8