From patchwork Tue Feb 11 19:23:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wayne Xia X-Patchwork-Id: 319134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2C89C2C007A for ; Tue, 11 Feb 2014 17:24:23 +1100 (EST) Received: from localhost ([::1]:59715 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WD6lY-0003u2-Q3 for incoming@patchwork.ozlabs.org; Tue, 11 Feb 2014 01:24:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50624) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WD6jM-0001p7-UA for qemu-devel@nongnu.org; Tue, 11 Feb 2014 01:22:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WD6jB-0005Ds-QN for qemu-devel@nongnu.org; Tue, 11 Feb 2014 01:22:04 -0500 Received: from e28smtp01.in.ibm.com ([122.248.162.1]:35056) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WD6jB-0005DE-4w for qemu-devel@nongnu.org; Tue, 11 Feb 2014 01:21:53 -0500 Received: from /spool/local by e28smtp01.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 11 Feb 2014 11:51:50 +0530 Received: from d28dlp01.in.ibm.com (9.184.220.126) by e28smtp01.in.ibm.com (192.168.1.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 11 Feb 2014 11:51:48 +0530 Received: from d28relay03.in.ibm.com (d28relay03.in.ibm.com [9.184.220.60]) by d28dlp01.in.ibm.com (Postfix) with ESMTP id 6B8D5E0056 for ; Tue, 11 Feb 2014 11:55:06 +0530 (IST) Received: from d28av02.in.ibm.com (d28av02.in.ibm.com [9.184.220.64]) by d28relay03.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s1B6LhDB63832308 for ; Tue, 11 Feb 2014 11:51:43 +0530 Received: from d28av02.in.ibm.com (localhost [127.0.0.1]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s1B6Ll33025732 for ; Tue, 11 Feb 2014 11:51:47 +0530 Received: from RH64wenchao ([9.181.129.59]) by d28av02.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s1B6LbNO025270; Tue, 11 Feb 2014 11:51:46 +0530 From: Wenchao Xia To: qemu-devel@nongnu.org Date: Tue, 11 Feb 2014 14:23:06 -0500 Message-Id: <1392146588-12120-7-git-send-email-xiawenc@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1392146588-12120-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1392146588-12120-1-git-send-email-xiawenc@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14021106-4790-0000-0000-00000CA99AEE X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 122.248.162.1 Cc: kwolf@redhat.com, peter.crosthwaite@xilinx.com, jcody@redhat.com, mreitz@redhat.com, stefanha@redhat.com, Wenchao Xia Subject: [Qemu-devel] [PATCH V11 6/8] qcow2: rollback on fail in qcow2_snapshot_create() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org A new variable *err_rollback is added to detect sub function's rollback failure. If one step in rollback procedure fails, following steps will be skipped, and the error message will be appended to errp. Signed-off-by: Wenchao Xia Reviewed-by: Max Reitz --- block/qcow2-snapshot.c | 37 ++++++++++++++++++++++++++++++++----- 1 files changed, 32 insertions(+), 5 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index ee8f990..12938a0 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -423,6 +423,7 @@ void qcow2_snapshot_create(BlockDriverState *bs, int i, ret; uint64_t *l1_table = NULL; int64_t l1_table_offset; + Error *err_rollback = NULL; memset(sn, 0, sizeof(*sn)); @@ -471,7 +472,7 @@ void qcow2_snapshot_create(BlockDriverState *bs, PRIu64 " with size %" PRIu64, sn->l1_table_offset, (uint64_t)(s->l1_size * sizeof(uint64_t))); - goto fail; + goto dealloc_l1_table; } ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table, @@ -482,7 +483,7 @@ void qcow2_snapshot_create(BlockDriverState *bs, PRIu64 " with size %" PRIu64, sn->l1_table_offset, (uint64_t)(s->l1_size * sizeof(uint64_t))); - goto fail; + goto dealloc_l1_table; } g_free(l1_table); @@ -499,7 +500,7 @@ void qcow2_snapshot_create(BlockDriverState *bs, "Failed in update of refcount for snapshot at %" PRIu64 " with size %d", s->l1_table_offset, s->l1_size); - goto fail; + goto dealloc_l1_table; } /* Append the new snapshot to the snapshot list */ @@ -512,12 +513,18 @@ void qcow2_snapshot_create(BlockDriverState *bs, s->snapshots = new_snapshot_list; s->snapshots[s->nb_snapshots++] = *sn; - ret = qcow2_write_snapshots(bs, errp, NULL); + ret = qcow2_write_snapshots(bs, errp, &err_rollback); if (ret < 0) { g_free(s->snapshots); s->snapshots = old_snapshot_list; s->nb_snapshots--; - goto fail; + if (error_is_set(&err_rollback)) { + error_append(errp, "%s", error_get_pretty(err_rollback)); + error_free(err_rollback); + goto fail; + } else { + goto restore_refcount; + } } g_free(old_snapshot_list); @@ -537,6 +544,26 @@ void qcow2_snapshot_create(BlockDriverState *bs, #endif return; +restore_refcount: + if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) + < 0) { + /* Nothing can be done now, need image check later, skip following + rollback action. */ + error_append(errp, + "Failed to restore refcounts during rollback"); + goto fail; + } + +dealloc_l1_table: + ret = qcow2_free_clusters(bs, sn->l1_table_offset, + sn->l1_size * sizeof(uint64_t), + QCOW2_DISCARD_ALWAYS); + if (ret < 0) { + error_append(errp, + "Failed to free the L1 table during rollback: %s", + strerror(-ret)); + } + fail: g_free(sn->id_str); g_free(sn->name);