diff mbox

[v2,01/10] qcow2: Fix error handling in qcow2_grow_l1_table

Message ID 1263996186-6623-2-git-send-email-kwolf@redhat.com
State New
Headers show

Commit Message

Kevin Wolf Jan. 20, 2010, 2:02 p.m. UTC
Return the appropriate error value instead of always using EIO. Don't free the
L1 table on errors, we still need it.

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

Comments

Anthony Liguori Jan. 26, 2010, 9:37 p.m. UTC | #1
On 01/20/2010 08:02 AM, Kevin Wolf wrote:
> Return the appropriate error value instead of always using EIO. Don't free the
> L1 table on errors, we still need it.
>
> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
>    

Applied all.  Thanks.

Do you think this is stable-0.12 material?  Is there any reasonable 
scenario where this could fix a user visible bug?

Regards,

Anthony Liguori
Kevin Wolf Jan. 27, 2010, 8:56 a.m. UTC | #2
Am 26.01.2010 22:37, schrieb Anthony Liguori:
> On 01/20/2010 08:02 AM, Kevin Wolf wrote:
>> Return the appropriate error value instead of always using EIO. Don't free the
>> L1 table on errors, we still need it.
>>
>> Signed-off-by: Kevin Wolf<kwolf@redhat.com>
>>    
> 
> Applied all.  Thanks.
> 
> Do you think this is stable-0.12 material?  Is there any reasonable 
> scenario where this could fix a user visible bug?

Yes, I think this is something for stable. Obviously the patches are
meant to only make a difference if something has gone wrong in the first
place, but in these cases it's expected to fix possible causes of
corruption (things like data written to clusters with refcount 0). Also
if someone relies on werror=enospc he'll need the right error codes.

Kevin
diff mbox

Patch

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f88118c..cb46376 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -67,9 +67,10 @@  int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
     /* set new table */
     cpu_to_be32w((uint32_t*)data, new_l1_size);
     cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
-    if (bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,
-                sizeof(data)) != sizeof(data))
+    ret = bdrv_pwrite(s->hd, offsetof(QCowHeader, l1_size), data,sizeof(data));
+    if (ret != sizeof(data)) {
         goto fail;
+    }
     qemu_free(s->l1_table);
     qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
     s->l1_table_offset = new_l1_table_offset;
@@ -77,8 +78,9 @@  int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
     s->l1_size = new_l1_size;
     return 0;
  fail:
-    qemu_free(s->l1_table);
-    return -EIO;
+    qemu_free(new_l1_table);
+    qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
+    return ret < 0 ? ret : -EIO;
 }
 
 void qcow2_l2_cache_reset(BlockDriverState *bs)