From patchwork Tue Aug 23 13:21:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 111104 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 2A168B6F69 for ; Tue, 23 Aug 2011 23:22:10 +1000 (EST) Received: from localhost ([::1]:37425 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qvqva-0001O1-3z for incoming@patchwork.ozlabs.org; Tue, 23 Aug 2011 09:22:02 -0400 Received: from eggs.gnu.org ([140.186.70.92]:58396) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QvqvD-0000pj-SK for qemu-devel@nongnu.org; Tue, 23 Aug 2011 09:21:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QvqvC-0006o9-An for qemu-devel@nongnu.org; Tue, 23 Aug 2011 09:21:39 -0400 Received: from mail-yx0-f173.google.com ([209.85.213.173]:57972) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QvqvC-0006nU-73 for qemu-devel@nongnu.org; Tue, 23 Aug 2011 09:21:38 -0400 Received: by mail-yx0-f173.google.com with SMTP id 3so85620yxt.4 for ; Tue, 23 Aug 2011 06:21:38 -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=EKl77UYhrqg7lTL4p2MnyoNR+u/Za0nwAY2ZhdJ1fcU=; b=izGBcNtAGcrtND7immo9hvKqpGAieVbgZ/8XVAJTCza5QxZtOB/gDfuJI+aosB69H0 mi83KR1EIC0CsJVbCkicO/VTyLcb9GhDDe6wccrahfTHKGkg5g0MrDHvs9RlRGeeEBNL 7BtzSuJw1V3aygM066yeekVPYjWfcd7f/wx2w= Received: by 10.236.115.98 with SMTP id d62mr23139421yhh.70.1314105697998; Tue, 23 Aug 2011 06:21:37 -0700 (PDT) Received: from obol602.omnitel.it (tor-exit-router37-readme.formlessnetworking.net [199.48.147.37]) by mx.google.com with ESMTPS id a29sm227805yhj.3.2011.08.23.06.21.31 (version=SSLv3 cipher=OTHER); Tue, 23 Aug 2011 06:21:37 -0700 (PDT) From: Frediano Ziglio To: kwolf@redhat.com Date: Tue, 23 Aug 2011 15:21:11 +0200 Message-Id: <1314105682-28396-5-git-send-email-freddy77@gmail.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1314105682-28396-1-git-send-email-freddy77@gmail.com> References: <1314105682-28396-1-git-send-email-freddy77@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.213.173 Cc: qemu-devel@nongnu.org, Frediano Ziglio Subject: [Qemu-devel] [PATCH v3 04/15] 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 | 291 ++++++++++++++++++++++++--------------------------------- 1 files changed, 123 insertions(+), 168 deletions(-) diff --git a/block/qcow.c b/block/qcow.c index 4ede7f3..f28c821 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -486,223 +486,178 @@ 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 = g_malloc0(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; -} + while (nb_sectors != 0) { -static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, QEMUIOVector *qiov) -{ - BDRVQcowState *s = bs->opaque; - QCowAIOCB acb; - int ret; - - 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 = g_malloc0(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; }