From patchwork Fri Oct 27 08:57:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 10029451 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B60660249 for ; Fri, 27 Oct 2017 09:01:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0271328F95 for ; Fri, 27 Oct 2017 09:01:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 00F7728F81; Fri, 27 Oct 2017 09:00:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 95E5A28F98 for ; Fri, 27 Oct 2017 09:00:59 +0000 (UTC) Received: from localhost ([::1]:56309 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e80Ve-0005HF-Q0 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 27 Oct 2017 05:00:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59394) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e80TC-00044e-QT for qemu-devel@nongnu.org; Fri, 27 Oct 2017 04:58:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e80T7-0001lW-2T for qemu-devel@nongnu.org; Fri, 27 Oct 2017 04:58:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37666) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e80T4-0001jC-4s; Fri, 27 Oct 2017 04:58:18 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 21C16B0AA6; Fri, 27 Oct 2017 08:58:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 21C16B0AA6 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=jcody@redhat.com Received: from localhost (ovpn-204-81.brq.redhat.com [10.40.204.81]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7313D60619; Fri, 27 Oct 2017 08:58:14 +0000 (UTC) From: Jeff Cody To: qemu-block@nongnu.org Date: Fri, 27 Oct 2017 04:57:55 -0400 Message-Id: <2f0114c773e8fb917a7a54acccfd2e2adfb6e066.1509094209.git.jcody@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 27 Oct 2017 08:58:17 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 3/4] block/parallels: Don't update header until the first actual write X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The on disk image format 'inuse' header field is updated blindly if the image is opened RDWR. This can cause problems if the QEMU runstate is set to INMIGRATE, at which point the underlying file is set to INACTIVE. This causes an assert in bdrv_co_pwritev(). Do something similar to what is done in VHDX; latch the first write, and update the header the first time we modify the file. Signed-off-by: Jeff Cody Reviewed-by: Denis V. Lunev --- block/parallels.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/block/parallels.c b/block/parallels.c index fed199eccd..c560e2fcf2 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -100,6 +100,8 @@ typedef struct BDRVParallelsState { unsigned int tracks; unsigned int off_multiplier; + + bool first_write_latch; } BDRVParallelsState; @@ -317,6 +319,16 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs, QEMUIOVector hd_qiov; int ret = 0; + if (s->first_write_latch) { + s->first_write_latch = false; + qemu_co_mutex_lock(&s->lock); + ret = parallels_update_header(bs); + qemu_co_mutex_unlock(&s->lock); + } + if (ret < 0) { + return ret; + } + qemu_iovec_init(&hd_qiov, qiov->niov); while (nb_sectors > 0) { @@ -416,6 +428,9 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, /* parallels_close will do the job right */ res->corruptions_fixed++; s->header_unclean = false; + /* set that a write has occurred, so that parallels_close() will + * update the inuse field in the header */ + s->first_write_latch = false; } } @@ -597,6 +612,8 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, Error *local_err = NULL; char *buf; + s->first_write_latch = true; + bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false, errp); if (!bs->file) { @@ -710,10 +727,6 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, if (flags & BDRV_O_RDWR) { s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC); - ret = parallels_update_header(bs); - if (ret < 0) { - goto fail; - } } s->bat_dirty_block = 4 * getpagesize(); @@ -741,7 +754,9 @@ static void parallels_close(BlockDriverState *bs) { BDRVParallelsState *s = bs->opaque; - if (bs->open_flags & BDRV_O_RDWR) { + /* Only need to update the header, if we ever actually wrote to the + * image at all */ + if ((bs->open_flags & BDRV_O_RDWR) && !s->first_write_latch) { s->header->inuse = 0; parallels_update_header(bs); }