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

login
register
mail settings
Submitter Kevin Wolf
Date Jan. 20, 2010, 2:02 p.m.
Message ID <1263996186-6623-2-git-send-email-kwolf@redhat.com>
Download mbox | patch
Permalink /patch/43285/
State New
Headers show

Comments

Kevin Wolf - Jan. 20, 2010, 2:02 p.m.
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(-)
Anthony Liguori - Jan. 26, 2010, 9:37 p.m.
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.
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

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)