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 11/16] qcow2: Support reading zero clusters
Date: Tue, 27 Mar 2012 17:03:30 +0200	[thread overview]
Message-ID: <1332860615-3047-12-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1332860615-3047-1-git-send-email-kwolf@redhat.com>

This adds support for reading zero clusters in version 3 images.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-cluster.c  |   17 +++++++++++++----
 block/qcow2-refcount.c |    7 +++++++
 block/qcow2.c          |    8 ++++++++
 block/qcow2.h          |    5 +++++
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index b120b92..4853f1f 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -453,6 +453,12 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
         c = 1;
         *cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK;
         break;
+    case QCOW2_CLUSTER_ZERO:
+        c = count_contiguous_clusters(nb_clusters, s->cluster_size,
+                &l2_table[l2_index], 0,
+                QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
+        *cluster_offset = 0;
+        break;
     case QCOW2_CLUSTER_UNALLOCATED:
         /* how many empty clusters ? */
         c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);
@@ -461,7 +467,8 @@ 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_COMPRESSED);
+                &l2_table[l2_index], 0,
+                QCOW_OFLAG_COMPRESSED | QCOW_OFLAG_ZERO);
         *cluster_offset &= L2E_OFFSET_MASK;
         break;
     }
@@ -720,6 +727,7 @@ static int count_cow_clusters(BDRVQcowState *s, int nb_clusters,
             break;
         case QCOW2_CLUSTER_UNALLOCATED:
         case QCOW2_CLUSTER_COMPRESSED:
+        case QCOW2_CLUSTER_ZERO:
             break;
         default:
             abort();
@@ -868,9 +876,10 @@ again:
         && (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,
-                                                  QCOW_OFLAG_COPIED);
+        keep_clusters =
+            count_contiguous_clusters(nb_clusters, s->cluster_size,
+                                      &l2_table[l2_index], 0,
+                                      QCOW_OFLAG_COPIED | QCOW_OFLAG_ZERO);
         assert(keep_clusters <= nb_clusters);
         nb_clusters -= keep_clusters;
     } else {
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index c5d3171..60e2fb5 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -697,6 +697,7 @@ void qcow2_free_any_clusters(BlockDriverState *bs,
                             nb_clusters << s->cluster_bits);
         break;
     case QCOW2_CLUSTER_UNALLOCATED:
+    case QCOW2_CLUSTER_ZERO:
         break;
     default:
         abort();
@@ -967,6 +968,12 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
                 l2_entry & ~511, nb_csectors * 512);
             break;
 
+        case QCOW2_CLUSTER_ZERO:
+            if ((l2_entry & L2E_OFFSET_MASK) == 0) {
+                break;
+            }
+            /* fall through */
+
         case QCOW2_CLUSTER_NORMAL:
         {
             /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
diff --git a/block/qcow2.c b/block/qcow2.c
index c1f113d..aef8282 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -536,6 +536,14 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
             }
             break;
 
+        case QCOW2_CLUSTER_ZERO:
+            if (s->qcow_version < 3) {
+                ret = -EIO;
+                goto fail;
+            }
+            qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors);
+            break;
+
         case QCOW2_CLUSTER_COMPRESSED:
             /* add AIO support for compressed blocks ? */
             ret = qcow2_decompress_cluster(bs, cluster_offset);
diff --git a/block/qcow2.h b/block/qcow2.h
index 71b8d88..64cfa69 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -43,6 +43,8 @@
 #define QCOW_OFLAG_COPIED     (1LL << 63)
 /* indicate that the cluster is compressed (they never have the copied flag) */
 #define QCOW_OFLAG_COMPRESSED (1LL << 62)
+/* The cluster reads as all zeros */
+#define QCOW_OFLAG_ZERO (1LL << 0)
 
 #define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
 
@@ -183,6 +185,7 @@ enum {
     QCOW2_CLUSTER_UNALLOCATED,
     QCOW2_CLUSTER_NORMAL,
     QCOW2_CLUSTER_COMPRESSED,
+    QCOW2_CLUSTER_ZERO
 };
 
 #define L1E_OFFSET_MASK 0x00ffffffffffff00ULL
@@ -212,6 +215,8 @@ static inline int qcow2_get_cluster_type(uint64_t l2_entry)
 {
     if (l2_entry & QCOW_OFLAG_COMPRESSED) {
         return QCOW2_CLUSTER_COMPRESSED;
+    } else if (l2_entry & QCOW_OFLAG_ZERO) {
+        return QCOW2_CLUSTER_ZERO;
     } else if (!(l2_entry & L2E_OFFSET_MASK)) {
         return QCOW2_CLUSTER_UNALLOCATED;
     } 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 ` [Qemu-devel] [RFC PATCH 03/16] qcow2: Ignore reserved bits in count_contiguous_clusters() Kevin Wolf
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 ` Kevin Wolf [this message]
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-12-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).