From patchwork Thu Apr 5 15:51:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 151085 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D6B8FB7083 for ; Fri, 6 Apr 2012 15:49:08 +1000 (EST) Received: from localhost ([::1]:58269 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SG22b-0007XC-HY for incoming@patchwork.ozlabs.org; Fri, 06 Apr 2012 01:48:57 -0400 Received: from eggs.gnu.org ([208.118.235.92]:38700) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFowH-0003M4-C8 for qemu-devel@nongnu.org; Thu, 05 Apr 2012 11:49:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SFow2-0006oW-Fl for qemu-devel@nongnu.org; Thu, 05 Apr 2012 11:49:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:65352) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFow2-0006nd-7o for qemu-devel@nongnu.org; Thu, 05 Apr 2012 11:49:18 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q35Fn8cX003116 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 5 Apr 2012 11:49:08 -0400 Received: from dhcp-5-188.str.redhat.com (vpn1-4-41.ams2.redhat.com [10.36.4.41]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q35FmiHU007630; Thu, 5 Apr 2012 11:49:07 -0400 From: Kevin Wolf To: anthony@codemonkey.ws Date: Thu, 5 Apr 2012 17:51:54 +0200 Message-Id: <1333641144-13612-17-git-send-email-kwolf@redhat.com> In-Reply-To: <1333641144-13612-1-git-send-email-kwolf@redhat.com> References: <1333641144-13612-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 16/46] vdi: move end-of-I/O handling at the end 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 From: Paolo Bonzini The next step is to take code that only triggers after the first operation, and move it at the end of vdi_aio_read_cb and vdi_aio_write_cb. Acked-by: Stefan Weil Signed-off-by: Paolo Bonzini Signed-off-by: Kevin Wolf --- block/vdi.c | 123 +++++++++++++++++++++++++++-------------------------------- 1 files changed, 56 insertions(+), 67 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index 5fd8700..df0f431 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -533,20 +533,7 @@ static int vdi_aio_read_cb(void *opaque, int ret) uint32_t sector_in_block; uint32_t n_sectors; - logout("%u sectors read\n", acb->n_sectors); - restart: - acb->nb_sectors -= acb->n_sectors; - - if (acb->nb_sectors == 0) { - /* request completed */ - ret = 0; - goto done; - } - - acb->sector_num += acb->n_sectors; - acb->buf += acb->n_sectors * SECTOR_SIZE; - block_index = acb->sector_num / s->block_sectors; sector_in_block = acb->sector_num % s->block_sectors; n_sectors = s->block_sectors - sector_in_block; @@ -573,11 +560,16 @@ restart: qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); ret = bdrv_co_readv(bs->file, offset, n_sectors, &acb->hd_qiov); } - if (ret >= 0) { + logout("%u sectors read\n", acb->n_sectors); + + acb->nb_sectors -= acb->n_sectors; + acb->sector_num += acb->n_sectors; + acb->buf += acb->n_sectors * SECTOR_SIZE; + + if (ret >= 0 && acb->nb_sectors > 0) { goto restart; } -done: if (acb->qiov->niov > 1) { qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size); qemu_vfree(acb->orig_buf); @@ -609,56 +601,6 @@ static int vdi_aio_write_cb(void *opaque, int ret) uint32_t n_sectors; restart: - acb->nb_sectors -= acb->n_sectors; - acb->sector_num += acb->n_sectors; - acb->buf += acb->n_sectors * SECTOR_SIZE; - - if (acb->nb_sectors == 0) { - logout("finished data write\n"); - acb->n_sectors = 0; - ret = 0; - if (acb->header_modified) { - VdiHeader *header = acb->block_buffer; - logout("now writing modified header\n"); - assert(VDI_IS_ALLOCATED(acb->bmap_first)); - *header = s->header; - vdi_header_to_le(header); - acb->header_modified = 0; - acb->hd_iov.iov_base = acb->block_buffer; - acb->hd_iov.iov_len = SECTOR_SIZE; - qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); - ret = bdrv_co_writev(bs->file, 0, 1, &acb->hd_qiov); - } - if (ret >= 0 && VDI_IS_ALLOCATED(acb->bmap_first)) { - /* One or more new blocks were allocated. */ - uint64_t offset; - uint32_t bmap_first; - uint32_t bmap_last; - g_free(acb->block_buffer); - acb->block_buffer = NULL; - bmap_first = acb->bmap_first; - bmap_last = acb->bmap_last; - logout("now writing modified block map entry %u...%u\n", - bmap_first, bmap_last); - /* Write modified sectors from block map. */ - bmap_first /= (SECTOR_SIZE / sizeof(uint32_t)); - bmap_last /= (SECTOR_SIZE / sizeof(uint32_t)); - n_sectors = bmap_last - bmap_first + 1; - offset = s->bmap_sector + bmap_first; - acb->bmap_first = VDI_UNALLOCATED; - acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] + - bmap_first * SECTOR_SIZE); - acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE; - qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); - logout("will write %u block map sectors starting from entry %u\n", - n_sectors, bmap_first); - ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov); - } - goto done; - } - - logout("%u sectors written\n", acb->n_sectors); - block_index = acb->sector_num / s->block_sectors; sector_in_block = acb->sector_num % s->block_sectors; n_sectors = s->block_sectors - sector_in_block; @@ -709,11 +651,58 @@ restart: qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov); } - if (ret >= 0) { + + acb->nb_sectors -= acb->n_sectors; + acb->sector_num += acb->n_sectors; + acb->buf += acb->n_sectors * SECTOR_SIZE; + + logout("%u sectors written\n", acb->n_sectors); + if (ret >= 0 && acb->nb_sectors > 0) { goto restart; } -done: + logout("finished data write\n"); + if (ret >= 0) { + ret = 0; + if (acb->header_modified) { + VdiHeader *header = acb->block_buffer; + logout("now writing modified header\n"); + assert(VDI_IS_ALLOCATED(acb->bmap_first)); + *header = s->header; + vdi_header_to_le(header); + acb->header_modified = 0; + acb->hd_iov.iov_base = acb->block_buffer; + acb->hd_iov.iov_len = SECTOR_SIZE; + qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); + ret = bdrv_co_writev(bs->file, 0, 1, &acb->hd_qiov); + } + if (ret >= 0 && VDI_IS_ALLOCATED(acb->bmap_first)) { + /* One or more new blocks were allocated. */ + uint64_t offset; + uint32_t bmap_first; + uint32_t bmap_last; + g_free(acb->block_buffer); + acb->block_buffer = NULL; + bmap_first = acb->bmap_first; + bmap_last = acb->bmap_last; + logout("now writing modified block map entry %u...%u\n", + bmap_first, bmap_last); + /* Write modified sectors from block map. */ + bmap_first /= (SECTOR_SIZE / sizeof(uint32_t)); + bmap_last /= (SECTOR_SIZE / sizeof(uint32_t)); + n_sectors = bmap_last - bmap_first + 1; + offset = s->bmap_sector + bmap_first; + acb->bmap_first = VDI_UNALLOCATED; + acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] + + bmap_first * SECTOR_SIZE); + acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE; + qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); + logout("will write %u block map sectors starting from entry %u\n", + n_sectors, bmap_first); + ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov); + } + } + if (acb->qiov->niov > 1) { qemu_vfree(acb->orig_buf); }