qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, stefanha@gmail.com
Subject: [Qemu-devel] [RFC PATCH 03/16] qcow2: Ignore reserved bits in count_contiguous_clusters()
Date: Tue, 27 Mar 2012 17:03:22 +0200	[thread overview]
Message-ID: <1332860615-3047-4-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1332860615-3047-1-git-send-email-kwolf@redhat.com>

Until now, count_contiguous_clusters() has an argument that allowed to
specify flags that should be ignored in the comparison, i.e. that are
allowed to change between contiguous clusters.

This patch changes the function so that it ignores all flags by default
now and you need to pass the flags on which it should stop.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-cluster.c |   38 ++++++++++++++++++++++++++++----------
 1 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 44d13de..9547fa9 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -246,28 +246,44 @@ fail:
     return ret;
 }
 
+/*
+ * Checks how many clusters in a given L2 table are contiguous in the image
+ * file. As soon as one of the flags in the bitmask stop_flags changes compared
+ * to the first cluster, the search is stopped and the cluster is not counted
+ * as contiguous. (This allows it, for example, to stop at the first compressed
+ * cluster which may require a different handling)
+ */
 static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,
-        uint64_t *l2_table, uint64_t start, uint64_t mask)
+        uint64_t *l2_table, uint64_t start, uint64_t stop_flags)
 {
     int i;
-    uint64_t offset = be64_to_cpu(l2_table[0]) & ~mask;
+    uint64_t mask = stop_flags | L2E_OFFSET_MASK;
+    uint64_t offset = be64_to_cpu(l2_table[0]) & mask;
 
     if (!offset)
         return 0;
 
-    for (i = start; i < start + nb_clusters; i++)
-        if (offset + (uint64_t) i * cluster_size != (be64_to_cpu(l2_table[i]) & ~mask))
+    for (i = start; i < start + nb_clusters; i++) {
+        uint64_t l2_entry = be64_to_cpu(l2_table[i]) & mask;
+        if (offset + (uint64_t) i * cluster_size != l2_entry) {
             break;
+        }
+    }
 
 	return (i - start);
 }
 
 static int count_contiguous_free_clusters(uint64_t nb_clusters, uint64_t *l2_table)
 {
-    int i = 0;
+    int i;
 
-    while(nb_clusters-- && l2_table[i] == 0)
-        i++;
+    for (i = 0; i < nb_clusters; i++) {
+        int type = qcow2_get_cluster_type(be64_to_cpu(l2_table[i]));
+
+        if (type != QCOW2_CLUSTER_UNALLOCATED) {
+            break;
+        }
+    }
 
     return i;
 }
@@ -444,7 +460,7 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
     case QCOW2_CLUSTER_NORMAL:
         /* how many allocated clusters ? */
         c = count_contiguous_clusters(nb_clusters, s->cluster_size,
-                &l2_table[l2_index], 0, QCOW_OFLAG_COPIED);
+                &l2_table[l2_index], 0, QCOW_OFLAG_COMPRESSED);
         *cluster_offset &= L2E_OFFSET_MASK;
         break;
     }
@@ -696,7 +712,8 @@ static int count_cow_clusters(BDRVQcowState *s, int nb_clusters,
 
     while (i < nb_clusters) {
         i += count_contiguous_clusters(nb_clusters - i, s->cluster_size,
-                &l2_table[l2_index], i, 0);
+                &l2_table[l2_index], i,
+                QCOW_OFLAG_COPIED | QCOW_OFLAG_COMPRESSED);
         if ((i >= nb_clusters) || be64_to_cpu(l2_table[l2_index + i])) {
             break;
         }
@@ -854,7 +871,8 @@ again:
     if (cluster_offset & QCOW_OFLAG_COPIED) {
         /* We keep all QCOW_OFLAG_COPIED clusters */
         keep_clusters = count_contiguous_clusters(nb_clusters, s->cluster_size,
-                                                  &l2_table[l2_index], 0, 0);
+                                                  &l2_table[l2_index], 0,
+                                                  QCOW_OFLAG_COPIED);
         assert(keep_clusters <= nb_clusters);
         nb_clusters -= keep_clusters;
     } else {
-- 
1.7.6.5

  parent reply	other threads:[~2012-03-27 15:00 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-27 15:03 [Qemu-devel] [RFC PATCH 00/16] qcow2: Basic version 3 support Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 01/16] Specification for qcow2 version 3 Kevin Wolf
2012-03-27 16:25   ` Eric Blake
2012-04-02 10:00     ` Kevin Wolf
2012-04-02 16:14       ` Eric Blake
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 02/16] qcow2: Ignore reserved bits in get_cluster_offset Kevin Wolf
2012-03-27 15:03 ` Kevin Wolf [this message]
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 04/16] qcow2: Fail write_compressed when overwriting data Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 05/16] qcow2: Ignore reserved bits in L1/L2 entries Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 06/16] qcow2: Refactor qcow2_free_any_clusters Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 07/16] qcow2: Simplify count_cow_clusters Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 08/16] qcow2: Ignore reserved bits in refcount table entries Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 09/16] qcow2: Ignore reserved bits in check_refcounts Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 10/16] qcow2: Version 3 images Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 11/16] qcow2: Support reading zero clusters Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 12/16] qcow2: Support for feature table header extension Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 13/16] qemu-iotests: add a simple test for write_zeroes Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 14/16] qemu-iotests: Test COW with zero clusters Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 15/16] qcow2: Zero write support Kevin Wolf
2012-03-27 15:03 ` [Qemu-devel] [RFC PATCH 16/16] qemu-iotests: use qcow3 Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1332860615-3047-4-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).