diff mbox

[V3,2/7] qcow2: free allocated cluster on fail in qcow2_write_snapshots()

Message ID 1378695482-29805-3-git-send-email-xiawenc@linux.vnet.ibm.com
State New
Headers show

Commit Message

Wayne Xia Sept. 9, 2013, 2:57 a.m. UTC
Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 block/qcow2-snapshot.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

Comments

Eric Blake Sept. 30, 2013, 9:16 p.m. UTC | #1
On 09/08/2013 08:57 PM, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  block/qcow2-snapshot.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>
Stefan Hajnoczi Oct. 2, 2013, 12:07 p.m. UTC | #2
On Mon, Sep 09, 2013 at 10:57:57AM +0800, Wenchao Xia wrote:
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  block/qcow2-snapshot.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
> index 40393b2..9e2d695 100644
> --- a/block/qcow2-snapshot.c
> +++ b/block/qcow2-snapshot.c
> @@ -186,7 +186,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
>      }
>      ret = bdrv_flush(bs);
>      if (ret < 0) {
> -        return ret;
> +        goto fail;
>      }
>  
>      /* The snapshot list position has not yet been updated, so these clusters
> @@ -194,7 +194,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
>      ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
>                                          s->snapshots_size);
>      if (ret < 0) {
> -        return ret;
> +        goto fail;
>      }
>  
>  
> @@ -278,6 +278,9 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
>      return 0;
>  
>  fail:
> +    /* free the new snapshot table */
> +    qcow2_free_clusters(bs, snapshots_offset, snapshots_size,
> +                        QCOW2_DISCARD_ALWAYS);

It is safer to skip qcow2_free_clusters() when the final
bdrv_pwrite_sync() fails.  We don't know if the header was updated on
disk.  If it was updated, then freeing the clusters may allow them to be
reallocated later (this will cause corruption).
diff mbox

Patch

diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 40393b2..9e2d695 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -186,7 +186,7 @@  static int qcow2_write_snapshots(BlockDriverState *bs)
     }
     ret = bdrv_flush(bs);
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
 
     /* The snapshot list position has not yet been updated, so these clusters
@@ -194,7 +194,7 @@  static int qcow2_write_snapshots(BlockDriverState *bs)
     ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
                                         s->snapshots_size);
     if (ret < 0) {
-        return ret;
+        goto fail;
     }
 
 
@@ -278,6 +278,9 @@  static int qcow2_write_snapshots(BlockDriverState *bs)
     return 0;
 
 fail:
+    /* free the new snapshot table */
+    qcow2_free_clusters(bs, snapshots_offset, snapshots_size,
+                        QCOW2_DISCARD_ALWAYS);
     return ret;
 }