qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: anthony@codemonkey.ws
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 02/19] qcow2: Allow get_refcount to return errors
Date: Tue, 15 Jun 2010 16:19:24 +0200	[thread overview]
Message-ID: <1276611581-3757-3-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1276611581-3757-1-git-send-email-kwolf@redhat.com>

get_refcount might need to load a refcount block from disk, so errors may
happen. Return the error code instead of assuming a refcount of 1 and change
the callers to respect error return values.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-refcount.c |   41 +++++++++++++++++++++++++++++++++++++----
 1 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 22b0b45..ca6b373 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -105,11 +105,17 @@ static int load_refcount_block(BlockDriverState *bs,
     return 0;
 }
 
+/*
+ * Returns the refcount of the cluster given by its index. Any non-negative
+ * return value is the refcount of the cluster, negative values are -errno
+ * and indicate an error.
+ */
 static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
 {
     BDRVQcowState *s = bs->opaque;
     int refcount_table_index, block_index;
     int64_t refcount_block_offset;
+    int ret;
 
     refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
     if (refcount_table_index >= s->refcount_table_size)
@@ -119,8 +125,10 @@ static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
         return 0;
     if (refcount_block_offset != s->refcount_block_cache_offset) {
         /* better than nothing: return allocated if read error */
-        if (load_refcount_block(bs, refcount_block_offset) < 0)
-            return 1;
+        ret = load_refcount_block(bs, refcount_block_offset);
+        if (ret < 0) {
+            return ret;
+        }
     }
     block_index = cluster_index &
         ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
@@ -538,7 +546,13 @@ fail:
     return ret;
 }
 
-/* addend must be 1 or -1 */
+/*
+ * Increases or decreases the refcount of a given cluster by one.
+ * addend must be 1 or -1.
+ *
+ * If the return value is non-negative, it is the new refcount of the cluster.
+ * If it is negative, it is -errno and indicates an error.
+ */
 static int update_cluster_refcount(BlockDriverState *bs,
                                    int64_t cluster_index,
                                    int addend)
@@ -779,6 +793,10 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                         } else {
                             refcount = get_refcount(bs, offset >> s->cluster_bits);
                         }
+
+                        if (refcount < 0) {
+                            goto fail;
+                        }
                     }
 
                     if (refcount == 1) {
@@ -801,7 +819,9 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
             } else {
                 refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
             }
-            if (refcount == 1) {
+            if (refcount < 0) {
+                goto fail;
+            } else if (refcount == 1) {
                 l2_offset |= QCOW_OFLAG_COPIED;
             }
             if (l2_offset != old_l2_offset) {
@@ -934,6 +954,10 @@ static int check_refcounts_l2(BlockDriverState *bs,
                     uint64_t entry = offset;
                     offset &= ~QCOW_OFLAG_COPIED;
                     refcount = get_refcount(bs, offset >> s->cluster_bits);
+                    if (refcount < 0) {
+                        fprintf(stderr, "Can't get refcount for offset %"
+                            PRIx64 ": %s\n", entry, strerror(-refcount));
+                    }
                     if ((refcount == 1) != ((entry & QCOW_OFLAG_COPIED) != 0)) {
                         fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"
                             PRIx64 " refcount=%d\n", entry, refcount);
@@ -1011,6 +1035,10 @@ static int check_refcounts_l1(BlockDriverState *bs,
             if (check_copied) {
                 refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED)
                     >> s->cluster_bits);
+                if (refcount < 0) {
+                    fprintf(stderr, "Can't get refcount for l2_offset %"
+                        PRIx64 ": %s\n", l2_offset, strerror(-refcount));
+                }
                 if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
                     fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64
                         " refcount=%d\n", l2_offset, refcount);
@@ -1118,6 +1146,11 @@ int qcow2_check_refcounts(BlockDriverState *bs)
     /* compare ref counts */
     for(i = 0; i < nb_clusters; i++) {
         refcount1 = get_refcount(bs, i);
+        if (refcount1 < 0) {
+            fprintf(stderr, "Can't get refcount for cluster %d: %s\n",
+                i, strerror(-refcount1));
+        }
+
         refcount2 = refcount_table[i];
         if (refcount1 != refcount2) {
             fprintf(stderr, "ERROR cluster %d refcount=%d reference=%d\n",
-- 
1.6.6.1

  parent reply	other threads:[~2010-06-15 14:20 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-15 14:19 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 01/19] vpc: Read/write multiple sectors at once Kevin Wolf
2010-06-15 14:19 ` Kevin Wolf [this message]
2010-06-15 14:19 ` [Qemu-devel] [PATCH 03/19] qcow2: Allow alloc_clusters_noref to return errors Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 04/19] qcow2: Return real error code in load_refcount_block Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 05/19] savevm: Really verify if a drive supports snapshots Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 06/19] Fix regression for "-drive file=" Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 07/19] qcow2: Restore L1 entry on l2_allocate failure Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 08/19] cow: use pread/pwrite Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 09/19] cow: stop using mmap Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 10/19] cow: use qemu block API Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 11/19] block: Move error actions from DriveInfo to BlockDriverState Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 12/19] block: Decouple block device "commit all" from DriveInfo Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 13/19] monitor: Make "commit FOO" complain when FOO doesn't exist Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 14/19] block: New bdrv_next() Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 15/19] block: Decouple savevm from DriveInfo Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 16/19] blockdev: Give drives internal linkage Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 17/19] Correct definitions for FD_CMD_SAVE and FD_CMD_RESTORE Kevin Wolf
2010-06-15 14:28   ` [Qemu-devel] " Anthony Liguori
2010-06-15 14:42     ` Kevin Wolf
2010-06-15 14:47       ` Jes Sorensen
2010-06-15 14:52         ` Kevin Wolf
2010-06-15 14:54           ` Jes Sorensen
2010-06-15 14:19 ` [Qemu-devel] [PATCH 18/19] block: fix a warning and possible truncation Kevin Wolf
2010-06-15 14:19 ` [Qemu-devel] [PATCH 19/19] xen: Fix build error due to missing include Kevin Wolf
2010-06-15 14:26 ` [Qemu-devel] [PULL 00/19] Block patches Anthony Liguori

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=1276611581-3757-3-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    /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).