From patchwork Fri Jul 22 08:46:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 106241 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EF629B6F6B for ; Fri, 22 Jul 2011 19:02:52 +1000 (EST) Received: from localhost ([::1]:54827 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkBOK-0005x3-HA for incoming@patchwork.ozlabs.org; Fri, 22 Jul 2011 04:47:28 -0400 Received: from eggs.gnu.org ([140.186.70.92]:56485) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkBNu-0004k2-Gx for qemu-devel@nongnu.org; Fri, 22 Jul 2011 04:47:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QkBNs-0002Ly-SY for qemu-devel@nongnu.org; Fri, 22 Jul 2011 04:47:02 -0400 Received: from mail-wy0-f173.google.com ([74.125.82.173]:44549) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkBNs-0002JC-E3 for qemu-devel@nongnu.org; Fri, 22 Jul 2011 04:47:00 -0400 Received: by mail-wy0-f173.google.com with SMTP id 28so1542600wyf.4 for ; Fri, 22 Jul 2011 01:46:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=/lX5fkPSeE6YjJ354VC7aqBT32rAN05MzXAFLudeWGk=; b=LkCBFN4zUnnDHRoZzCtZF8IP2SbbhHyM5AJt+hUFaL2aCiC/f/5qLrwiEReG74khH9 v4gEgwt7UpAHL+991toYcEJ0Ol1ou9UqYCMvdaJKdrDswYWlg+iffnR/FygyeKGzWlUy HOgbJs8Ob9kV2wer0zhUS0MOc7FuDBRMkEMWg= Received: by 10.227.202.209 with SMTP id ff17mr826549wbb.23.1311324419885; Fri, 22 Jul 2011 01:46:59 -0700 (PDT) Received: from localhost.localdomain (rockhall.torservers.net [77.247.181.163]) by mx.google.com with ESMTPS id gd1sm1720338wbb.27.2011.07.22.01.46.53 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 22 Jul 2011 01:46:59 -0700 (PDT) From: Frediano Ziglio To: qemu-devel@nongnu.org Date: Fri, 22 Jul 2011 10:46:29 +0200 Message-Id: <1311324390-27830-5-git-send-email-freddy77@gmail.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1311324390-27830-1-git-send-email-freddy77@gmail.com> References: <1311324390-27830-1-git-send-email-freddy77@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.173 Cc: Kevin Wolf , Frediano Ziglio Subject: [Qemu-devel] [PATCH 4/5] qcow: embed qcow_aio_read_cb into qcow_co_readv and qcow_aio_write_cb into qcow_co_writev 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 Signed-off-by: Frediano Ziglio --- block/qcow.c | 287 ++++++++++++++++++++++++--------------------------------- 1 files changed, 121 insertions(+), 166 deletions(-) diff --git a/block/qcow.c b/block/qcow.c index 015a472..2feb7d7 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -486,221 +486,176 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num, } #endif -typedef struct QCowAIOCB { - BlockDriverState *bs; - int64_t sector_num; - QEMUIOVector *qiov; - uint8_t *buf; - void *orig_buf; - int nb_sectors; -} QCowAIOCB; - -static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs, - int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, - int is_write, QCowAIOCB *acb) -{ - acb->bs = bs; - acb->sector_num = sector_num; - acb->qiov = qiov; - - if (qiov->niov > 1) { - acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size); - if (is_write) - qemu_iovec_to_buffer(qiov, acb->buf); - } else { - acb->orig_buf = NULL; - acb->buf = (uint8_t *)qiov->iov->iov_base; - } - acb->nb_sectors = nb_sectors; - return acb; -} - -static int qcow_aio_read_cb(QCowAIOCB *acb) +static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { - BlockDriverState *bs = acb->bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; - int ret, n; + int ret = 0, n; uint64_t cluster_offset; struct iovec hd_iov; QEMUIOVector hd_qiov; + uint8_t *buf; + void *orig_buf; - redo: - if (acb->nb_sectors == 0) { - /* request completed */ - return 0; + if (qiov->niov > 1) { + buf = orig_buf = qemu_blockalign(bs, qiov->size); + } else { + orig_buf = NULL; + buf = (uint8_t *)qiov->iov->iov_base; } - /* prepare next request */ - cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, - 0, 0, 0, 0); - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - n = s->cluster_sectors - index_in_cluster; - if (n > acb->nb_sectors) - n = acb->nb_sectors; + qemu_co_mutex_lock(&s->lock); + + while (nb_sectors != 0) { + /* prepare next request */ + cluster_offset = get_cluster_offset(bs, sector_num << 9, + 0, 0, 0, 0); + index_in_cluster = sector_num & (s->cluster_sectors - 1); + n = s->cluster_sectors - index_in_cluster; + if (n > nb_sectors) + n = nb_sectors; - if (!cluster_offset) { - if (bs->backing_hd) { - /* read from the base image */ - hd_iov.iov_base = (void *)acb->buf; + if (!cluster_offset) { + if (bs->backing_hd) { + /* read from the base image */ + hd_iov.iov_base = (void *)buf; + hd_iov.iov_len = n * 512; + qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_readv(bs->backing_hd, sector_num, + n, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + goto fail; + } + } else { + /* Note: in this case, no need to wait */ + memset(buf, 0, 512 * n); + } + } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { + /* add AIO support for compressed blocks ? */ + if (decompress_cluster(bs, cluster_offset) < 0) { + goto fail; + } + memcpy(buf, + s->cluster_cache + index_in_cluster * 512, 512 * n); + } else { + if ((cluster_offset & 511) != 0) { + goto fail; + } + hd_iov.iov_base = (void *)buf; hd_iov.iov_len = n * 512; qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_readv(bs->backing_hd, acb->sector_num, + ret = bdrv_co_readv(bs->file, + (cluster_offset >> 9) + index_in_cluster, n, &hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { - return -EIO; + break; + } + if (s->crypt_method) { + encrypt_sectors(s, sector_num, buf, buf, + n, 0, + &s->aes_decrypt_key); } - } else { - /* Note: in this case, no need to wait */ - memset(acb->buf, 0, 512 * n); - } - } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* add AIO support for compressed blocks ? */ - if (decompress_cluster(bs, cluster_offset) < 0) { - return -EIO; - } - memcpy(acb->buf, - s->cluster_cache + index_in_cluster * 512, 512 * n); - } else { - if ((cluster_offset & 511) != 0) { - return -EIO; - } - hd_iov.iov_base = (void *)acb->buf; - hd_iov.iov_len = n * 512; - qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); - qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_readv(bs->file, - (cluster_offset >> 9) + index_in_cluster, - n, &hd_qiov); - qemu_co_mutex_lock(&s->lock); - if (ret < 0) { - return ret; } - } + ret = 0; - /* post process the read buffer */ - if (!cluster_offset) { - /* nothing to do */ - } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) { - /* nothing to do */ - } else { - if (s->crypt_method) { - encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf, - n, 0, - &s->aes_decrypt_key); - } + nb_sectors -= n; + sector_num += n; + buf += n * 512; } - acb->nb_sectors -= n; - acb->sector_num += n; - acb->buf += n * 512; - - goto redo; -} - -static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) -{ - BDRVQcowState *s = bs->opaque; - QCowAIOCB acb; - int ret; - - qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0, &acb); - - qemu_co_mutex_lock(&s->lock); - ret = qcow_aio_read_cb(&acb); +done: qemu_co_mutex_unlock(&s->lock); - if (acb.qiov->niov > 1) { - qemu_iovec_from_buffer(acb.qiov, acb.orig_buf, acb.qiov->size); - qemu_vfree(acb.orig_buf); + if (qiov->niov > 1) { + qemu_iovec_from_buffer(qiov, orig_buf, qiov->size); + qemu_vfree(orig_buf); } return ret; + +fail: + ret = -EIO; + goto done; } -static int qcow_aio_write_cb(QCowAIOCB *acb) +static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, QEMUIOVector *qiov) { - BlockDriverState *bs = acb->bs; BDRVQcowState *s = bs->opaque; int index_in_cluster; uint64_t cluster_offset; const uint8_t *src_buf; - int ret, n; + int ret = 0, n; uint8_t *cluster_data = NULL; struct iovec hd_iov; QEMUIOVector hd_qiov; + uint8_t *buf; + void *orig_buf; - redo: - if (acb->nb_sectors == 0) { - /* request completed */ - return 0; - } + s->cluster_cache_offset = -1; /* disable compressed cache */ - index_in_cluster = acb->sector_num & (s->cluster_sectors - 1); - n = s->cluster_sectors - index_in_cluster; - if (n > acb->nb_sectors) - n = acb->nb_sectors; - cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0, - index_in_cluster, - index_in_cluster + n); - if (!cluster_offset || (cluster_offset & 511) != 0) { - return -EIO; - } - if (s->crypt_method) { - if (!cluster_data) { - cluster_data = qemu_mallocz(s->cluster_size); - } - encrypt_sectors(s, acb->sector_num, cluster_data, acb->buf, - n, 1, &s->aes_encrypt_key); - src_buf = cluster_data; + if (qiov->niov > 1) { + buf = orig_buf = qemu_blockalign(bs, qiov->size); + qemu_iovec_to_buffer(qiov, buf); } else { - src_buf = acb->buf; + orig_buf = NULL; + buf = (uint8_t *)qiov->iov->iov_base; } - hd_iov.iov_base = (void *)src_buf; - hd_iov.iov_len = n * 512; - qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); - qemu_co_mutex_unlock(&s->lock); - ret = bdrv_co_writev(bs->file, - (cluster_offset >> 9) + index_in_cluster, - n, &hd_qiov); - if (cluster_data) { - free(cluster_data); - cluster_data = NULL; - } qemu_co_mutex_lock(&s->lock); - if (ret < 0) { - return ret; - } - - acb->nb_sectors -= n; - acb->sector_num += n; - acb->buf += n * 512; - - goto redo; -} -static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) -{ - BDRVQcowState *s = bs->opaque; - QCowAIOCB acb; - int ret; + while (nb_sectors != 0) { - s->cluster_cache_offset = -1; /* disable compressed cache */ + index_in_cluster = sector_num & (s->cluster_sectors - 1); + n = s->cluster_sectors - index_in_cluster; + if (n > nb_sectors) + n = nb_sectors; + cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0, + index_in_cluster, + index_in_cluster + n); + if (!cluster_offset || (cluster_offset & 511) != 0) { + ret = -EIO; + break; + } + if (s->crypt_method) { + if (!cluster_data) { + cluster_data = qemu_mallocz(s->cluster_size); + } + encrypt_sectors(s, sector_num, cluster_data, buf, + n, 1, &s->aes_encrypt_key); + src_buf = cluster_data; + } else { + src_buf = buf; + } - qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1, &acb); + hd_iov.iov_base = (void *)src_buf; + hd_iov.iov_len = n * 512; + qemu_iovec_init_external(&hd_qiov, &hd_iov, 1); + qemu_co_mutex_unlock(&s->lock); + ret = bdrv_co_writev(bs->file, + (cluster_offset >> 9) + index_in_cluster, + n, &hd_qiov); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + break; + } + ret = 0; - qemu_co_mutex_lock(&s->lock); - ret = qcow_aio_write_cb(&acb); + nb_sectors -= n; + sector_num += n; + buf += n * 512; + } qemu_co_mutex_unlock(&s->lock); - if (acb.qiov->niov > 1) { - qemu_vfree(acb.orig_buf); + if (qiov->niov > 1) { + qemu_vfree(orig_buf); } + free(cluster_data); return ret; }