From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665124; cv=none; d=zoho.com; s=zohoarc; b=kA83Wfnomr2Rsrl90d9S6i2M+VrOa9VHLw5NEDAQI4q27Xr4FYVYRgnPM86ZJzG79dYPeHp/90z9lwjNTAbGf1Vxm20YxXFfTjtHqlx4cXUxsw9LoPwvcO0hd/ATfZClrEVwdFzST7nUcBMCeg84MgF3UIWAks5aMct7fyUNeCA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665124; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=NQKSEN86rfkexqO6lNEm47iIp8z9/aFsu78qickc+OE=; b=P3xPFURciR5cwVBQ0DH942MFkFIOE4X5utXOVpg2Ued8c5zAh3Y8rgd+UHgSC5rdHJXeQ1sdnmKeXcIb5jWPKv8cWcbCRsRu1p1GgtT+TyKLa53dxmo1364zYQln06YMuWNjV6bYzok3fxjhvoVb3FvRH5FvGq4rjBwzq25Jo2w= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665124969410.12775103775857; Tue, 4 Jun 2019 09:18:44 -0700 (PDT) Received: from localhost ([127.0.0.1]:54860 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC93-0002os-03 for importer@patchew.org; Tue, 04 Jun 2019 12:18:41 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35893) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6H-00018d-R8 for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6B-0005hJ-Bg for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:46 -0400 Received: from relay.sw.ru ([185.231.240.75]:41660) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005C1-O6; Tue, 04 Jun 2019 12:15:43 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5j-0005Pq-8I; Tue, 04 Jun 2019 19:15:15 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:03 +0300 Message-Id: <20190604161514.262241-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 01/12] util/iov: introduce qemu_iovec_init_extended 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce new initialization API, to create requests with padding. Will be used in the following patch. New API uses qemu_iovec_init_buf if resulting io vector has only one element, to avoid extra allocations. So, we need to update qemu_iovec_destroy to support destroying such QIOVs. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- include/qemu/iov.h | 7 +++ util/iov.c | 112 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 48b45987b7..f3787a0cf7 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -199,6 +199,13 @@ static inline void *qemu_iovec_buf(QEMUIOVector *qiov) =20 void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int n= iov); +void qemu_iovec_init_extended( + QEMUIOVector *qiov, + void *head_buf, size_t head_len, + QEMUIOVector *mid_qiov, size_t mid_offset, size_t mid_len, + void *tail_buf, size_t tail_len); +void qemu_iovec_init_slice(QEMUIOVector *qiov, QEMUIOVector *source, + size_t offset, size_t len); void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t soffset, size_t sbytes); diff --git a/util/iov.c b/util/iov.c index 74e6ca8ed7..39b6e31494 100644 --- a/util/iov.c +++ b/util/iov.c @@ -353,6 +353,103 @@ void qemu_iovec_concat(QEMUIOVector *dst, qemu_iovec_concat_iov(dst, src->iov, src->niov, soffset, sbytes); } =20 +/* + * qiov_find_iov + * + * Return pointer to iovec structure, where byte at @offset in original ve= ctor + * @iov exactly is. + * Set @remaining_offset to be offset inside that iovec to the same byte. + */ +static struct iovec *iov_skip_offset(struct iovec *iov, size_t offset, + size_t *remaining_offset) +{ + while (offset > 0 && offset >=3D iov->iov_len) { + offset -=3D iov->iov_len; + iov++; + } + *remaining_offset =3D offset; + + return iov; +} + +/* + * qiov_slice + * + * Find subarray of iovec's, containing requested range. @head would + * be offset in first iov (returned by the function), @tail would be + * count of extra bytes in last iovec (returned iov + @niov - 1). + */ +static struct iovec *qiov_slice(QEMUIOVector *qiov, + size_t offset, size_t len, + size_t *head, size_t *tail, int *niov) +{ + struct iovec *iov, *end_iov; + + assert(offset + len <=3D qiov->size); + + iov =3D iov_skip_offset(qiov->iov, offset, head); + end_iov =3D iov_skip_offset(iov, *head + len, tail); + + if (*tail > 0) { + assert(*tail < end_iov->iov_len); + *tail =3D end_iov->iov_len - *tail; + end_iov++; + } + + *niov =3D end_iov - iov; + + return iov; +} + +/* + * Compile new iovec, combining @head_buf buffer, sub-qiov of @mid_qiov, + * and @tail_buf buffer into new qiov. + */ +void qemu_iovec_init_extended( + QEMUIOVector *qiov, + void *head_buf, size_t head_len, + QEMUIOVector *mid_qiov, size_t mid_offset, size_t mid_len, + void *tail_buf, size_t tail_len) +{ + size_t mid_head, mid_tail; + int total_niov, mid_niov; + struct iovec *p, *mid_iov; + + if (mid_len) { + mid_iov =3D qiov_slice(mid_qiov, mid_offset, mid_len, + &mid_head, &mid_tail, &mid_niov); + } + + total_niov =3D !!head_len + mid_niov + !!tail_len; + if (total_niov =3D=3D 1) { + qemu_iovec_init_buf(qiov, NULL, 0); + p =3D &qiov->local_iov; + } else { + qiov->niov =3D qiov->nalloc =3D total_niov; + qiov->size =3D head_len + mid_len + tail_len; + p =3D qiov->iov =3D g_new(struct iovec, qiov->niov); + } + + if (head_len) { + p->iov_base =3D head_buf; + p->iov_len =3D head_len; + p++; + } + + if (mid_len) { + memcpy(p, mid_iov, mid_niov * sizeof(*p)); + p[0].iov_base =3D (uint8_t *)p[0].iov_base + mid_head; + p[0].iov_len -=3D mid_head; + p[mid_niov - 1].iov_len -=3D mid_tail; + p +=3D mid_niov; + } + + if (tail_len) { + p->iov_base =3D tail_buf; + p->iov_len =3D tail_len; + } +} + /* * Check if the contents of the iovecs are all zero */ @@ -374,14 +471,19 @@ bool qemu_iovec_is_zero(QEMUIOVector *qiov) return true; } =20 +void qemu_iovec_init_slice(QEMUIOVector *qiov, QEMUIOVector *source, + size_t offset, size_t len) +{ + qemu_iovec_init_extended(qiov, NULL, 0, source, offset, len, NULL, 0); +} + void qemu_iovec_destroy(QEMUIOVector *qiov) { - assert(qiov->nalloc !=3D -1); + if (qiov->nalloc !=3D -1) { + g_free(qiov->iov); + } =20 - qemu_iovec_reset(qiov); - g_free(qiov->iov); - qiov->nalloc =3D 0; - qiov->iov =3D NULL; + memset(qiov, 0, sizeof(*qiov)); } =20 void qemu_iovec_reset(QEMUIOVector *qiov) --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665414; cv=none; d=zoho.com; s=zohoarc; b=bmgXt/AdSmPZxK8kjvJaz8bUkDyz1tm/UxhjJC8+hthilhoPGz+Ttt8BT4ndWfj+CC5gnR9saMZROeVQf2rZ3FRZCUpOh4tpbd4uO9oaEbHNoLZdV1cYvl9Mzf5c3JTm1s0KFUZk+1rVwFo5RjoXjY2ufmP2neHRKKYsA8RsI3Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665414; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=tknc77tfVu9mk7DUCVqjFRdmyaJEFjTzoptppxvVmdc=; b=NhEMe0X2Y/Xu4hZQwYc37DZu+alw9NMCDXMYdffDhLRAz++kZwsy+/RE0EJbAz2FsQMsumblY5TrrDimTVADpZPCnmc4ZjGZfk0Qhlh6rUhCFJ/i4MHixXXYg9di4owWbIHrDIQrEbkPmcWXncI7F7uXJmCz+BgxT56qyWkNyBs= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665414964284.9608096985569; Tue, 4 Jun 2019 09:23:34 -0700 (PDT) Received: from localhost ([127.0.0.1]:54926 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCDf-0006Vo-UI for importer@patchew.org; Tue, 04 Jun 2019 12:23:27 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35857) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6F-00016V-Td for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6B-0005gm-7n for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:45 -0400 Received: from relay.sw.ru ([185.231.240.75]:41646) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005Bu-N5; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5j-0005Pq-Ej; Tue, 04 Jun 2019 19:15:15 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:04 +0300 Message-Id: <20190604161514.262241-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 02/12] util/iov: improve qemu_iovec_is_zero 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We'll need to check a part of qiov soon, so implement it now. Optimization with align down to 4 * sizeof(long) is dropped due to: 1. It is strange: it aligns length of the buffer, but where is a guarantee that buffer pointer is aligned itself? 2. buffer_is_zero() is a better place for optimizations and it has them. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- include/qemu/iov.h | 2 +- block/io.c | 2 +- util/iov.c | 31 +++++++++++++++++++------------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/include/qemu/iov.h b/include/qemu/iov.h index f3787a0cf7..29957c8a72 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -212,7 +212,7 @@ void qemu_iovec_concat(QEMUIOVector *dst, size_t qemu_iovec_concat_iov(QEMUIOVector *dst, struct iovec *src_iov, unsigned int src_cnt, size_t soffset, size_t sbytes); -bool qemu_iovec_is_zero(QEMUIOVector *qiov); +bool qemu_iovec_is_zero(QEMUIOVector *qiov, size_t qiov_offeset, size_t by= tes); void qemu_iovec_destroy(QEMUIOVector *qiov); void qemu_iovec_reset(QEMUIOVector *qiov); size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset, diff --git a/block/io.c b/block/io.c index 3134a60a48..d02fded3b1 100644 --- a/block/io.c +++ b/block/io.c @@ -1651,7 +1651,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChil= d *child, =20 if (!ret && bs->detect_zeroes !=3D BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF = && !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes && - qemu_iovec_is_zero(qiov)) { + qemu_iovec_is_zero(qiov, 0, qiov->size)) { flags |=3D BDRV_REQ_ZERO_WRITE; if (bs->detect_zeroes =3D=3D BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP)= { flags |=3D BDRV_REQ_MAY_UNMAP; diff --git a/util/iov.c b/util/iov.c index 39b6e31494..d988a533ce 100644 --- a/util/iov.c +++ b/util/iov.c @@ -451,23 +451,30 @@ void qemu_iovec_init_extended( } =20 /* - * Check if the contents of the iovecs are all zero + * Check if the contents of subrange of qiov data is all zeroes. */ -bool qemu_iovec_is_zero(QEMUIOVector *qiov) +bool qemu_iovec_is_zero(QEMUIOVector *qiov, size_t offset, size_t bytes) { - int i; - for (i =3D 0; i < qiov->niov; i++) { - size_t offs =3D QEMU_ALIGN_DOWN(qiov->iov[i].iov_len, 4 * sizeof(l= ong)); - uint8_t *ptr =3D qiov->iov[i].iov_base; - if (offs && !buffer_is_zero(qiov->iov[i].iov_base, offs)) { + struct iovec *iov; + size_t current_offset; + + assert(offset + bytes <=3D qiov->size); + + iov =3D iov_skip_offset(qiov->iov, offset, ¤t_offset); + + while (bytes) { + uint8_t *base =3D (uint8_t *)iov->iov_base + current_offset; + size_t len =3D MIN(iov->iov_len - current_offset, bytes); + + if (!buffer_is_zero(base, len)) { return false; } - for (; offs < qiov->iov[i].iov_len; offs++) { - if (ptr[offs]) { - return false; - } - } + + current_offset =3D 0; + bytes -=3D len; + iov++; } + return true; } =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665686; cv=none; d=zoho.com; s=zohoarc; b=k7qkB1RSHvglvbP3bpubhVk+uMzYGRuC2jF3GErgLwDfKPddXZhHzi2C60RGrVaelxXO/ZxrrYozOHVbE/4Jfapn4LtkPuSoAsN4TnE+0QoAgNQrD6CINnYF8ZV8H2ySAcmiLBvgs+X127AimnVgneQwPeVwe54hj+gPz9BUex0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665686; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=skrcSVGivzY+AtUJXBQxf4zmtlb+3XBJ+n+2yEsKw+Q=; b=hnBk9aZrX9FUI3u8XIIAJY3Kf5KXSYY9+sGfUM4WvEqwkpvFr9XjBnAlk6+7OuecgNU5X3cY95NQeeazO/HLuPFrIB2G2khCWvIfl8sfKBPz6xq8rlqGr4Zd2J9wczqb87dE4DUdRqn9llXO97kXkc4Gp4ZeTdCtHw2mnUQWL+k= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665686146727.8149464043308; Tue, 4 Jun 2019 09:28:06 -0700 (PDT) Received: from localhost ([127.0.0.1]:55041 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCHR-0001by-Oc for importer@patchew.org; Tue, 04 Jun 2019 12:27:21 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35859) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6F-00016Z-UA for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6A-0005fc-LL for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:45 -0400 Received: from relay.sw.ru ([185.231.240.75]:41658) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005Bx-9G; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5j-0005Pq-Iz; Tue, 04 Jun 2019 19:15:15 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:05 +0300 Message-Id: <20190604161514.262241-4-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 03/12] block/io: refactor padding 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We have similar padding code in bdrv_co_pwritev, bdrv_co_do_pwrite_zeroes and bdrv_co_preadv. Let's combine and unify it. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/io.c | 355 ++++++++++++++++++++++++++++------------------------- 1 file changed, 190 insertions(+), 165 deletions(-) diff --git a/block/io.c b/block/io.c index d02fded3b1..ddd5902dc1 100644 --- a/block/io.c +++ b/block/io.c @@ -1344,28 +1344,167 @@ out: } =20 /* - * Handle a read request in coroutine context + * Request padding + * + * |<---- align ----->| |<----- align ---->| + * |<- head ->|<------------- bytes ------------->|<-- tail -->| + * | | | | | | + * -*----------$-------*-------- ... --------*-----$------------*--- + * | | | | | | + * | offset | | end | + * ALIGN_DOWN(offset) ALIGN_UP(offset) ALIGN_DOWN(end) ALIGN_UP(en= d) + * [buf ... ) [tail_buf ) + * + * @buf is an aligned allocation needed to store @head and @tail paddings.= @head + * is placed at the beginning of @buf and @tail at the @end. + * + * @tail_buf is a pointer to sub-buffer, corresponding to align-sized chunk + * around tail, if tail exists. + * + * @merge_reads is true for small requests, + * if @buf_len =3D=3D @head + bytes + @tail. In this case it is possible t= hat both + * head and tail exist but @buf_len =3D=3D align and @tail_buf =3D=3D @buf. */ +typedef struct BdrvRequestPadding { + uint8_t *buf; + size_t buf_len; + uint8_t *tail_buf; + size_t head; + size_t tail; + bool merge_reads; + QEMUIOVector local_qiov; +} BdrvRequestPadding; + +static bool bdrv_init_padding(BlockDriverState *bs, + int64_t offset, int64_t bytes, + BdrvRequestPadding *pad) +{ + uint64_t align =3D bs->bl.request_alignment; + size_t sum; + + memset(pad, 0, sizeof(*pad)); + + pad->head =3D offset & (align - 1); + pad->tail =3D ((offset + bytes) & (align - 1)); + if (pad->tail) { + pad->tail =3D align - pad->tail; + } + + if ((!pad->head && !pad->tail) || !bytes) { + return false; + } + + sum =3D pad->head + bytes + pad->tail; + pad->buf_len =3D (sum > align && pad->head && pad->tail) ? 2 * align := align; + pad->buf =3D qemu_blockalign(bs, pad->buf_len); + pad->merge_reads =3D sum =3D=3D pad->buf_len; + if (pad->tail) { + pad->tail_buf =3D pad->buf + pad->buf_len - align; + } + + return true; +} + +static int bdrv_padding_rmw_read(BdrvChild *child, + BdrvTrackedRequest *req, + BdrvRequestPadding *pad, + bool zero_middle) +{ + QEMUIOVector local_qiov; + BlockDriverState *bs =3D child->bs; + uint64_t align =3D bs->bl.request_alignment; + int ret; + + assert(req->serialising && pad->buf); + + if (pad->head || pad->merge_reads) { + uint64_t bytes =3D pad->merge_reads ? pad->buf_len : align; + + qemu_iovec_init_buf(&local_qiov, pad->buf, bytes); + + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); + ret =3D bdrv_aligned_preadv(child, req, req->overlap_offset, bytes, + align, &local_qiov, 0); + if (ret < 0) { + return ret; + } + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD); + + if (pad->merge_reads) { + goto zero_mem; + } + } + + if (pad->tail) { + qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align); + + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); + ret =3D bdrv_aligned_preadv( + child, req, + req->overlap_offset + req->overlap_bytes - align, + align, align, &local_qiov, 0); + if (ret < 0) { + return ret; + } + bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); + } + +zero_mem: + if (zero_middle) { + memset(pad->buf + pad->head, 0, pad->buf_len - pad->head - pad->ta= il); + } + + return 0; +} + +static void bdrv_padding_destroy(BdrvRequestPadding *pad) +{ + if (pad->buf) { + qemu_vfree(pad->buf); + qemu_iovec_destroy(&pad->local_qiov); + } +} + +/* + * bdrv_pad_request + * + * Exchange request parameters with padded request if needed. Don't includ= e RMW + * read of padding, bdrv_padding_rmw_read() should be called separately if + * needed. + * + * All parameters except @bs are in-out: they represent original request at + * function call and padded (if padding needed) at function finish. + * + * Function always succeeds. + */ +static bool bdrv_pad_request(BlockDriverState *bs, QEMUIOVector **qiov, + int64_t *offset, unsigned int *bytes, + BdrvRequestPadding *pad) +{ + if (!bdrv_init_padding(bs, *offset, *bytes, pad)) { + return false; + } + + qemu_iovec_init_extended(&pad->local_qiov, pad->buf, pad->head, + *qiov, 0, *bytes, + pad->buf + pad->buf_len - pad->tail, pad->tai= l); + *bytes +=3D pad->head + pad->tail; + *offset -=3D pad->head; + *qiov =3D &pad->local_qiov; + + return true; +} + int coroutine_fn bdrv_co_preadv(BdrvChild *child, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) { BlockDriverState *bs =3D child->bs; - BlockDriver *drv =3D bs->drv; BdrvTrackedRequest req; - - uint64_t align =3D bs->bl.request_alignment; - uint8_t *head_buf =3D NULL; - uint8_t *tail_buf =3D NULL; - QEMUIOVector local_qiov; - bool use_local_qiov =3D false; + BdrvRequestPadding pad; int ret; =20 - trace_bdrv_co_preadv(child->bs, offset, bytes, flags); - - if (!drv) { - return -ENOMEDIUM; - } + trace_bdrv_co_preadv(bs, offset, bytes, flags); =20 ret =3D bdrv_check_byte_request(bs, offset, bytes); if (ret < 0) { @@ -1379,43 +1518,16 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child, flags |=3D BDRV_REQ_COPY_ON_READ; } =20 - /* Align read if necessary by padding qiov */ - if (offset & (align - 1)) { - head_buf =3D qemu_blockalign(bs, align); - qemu_iovec_init(&local_qiov, qiov->niov + 2); - qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1)); - qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size); - use_local_qiov =3D true; - - bytes +=3D offset & (align - 1); - offset =3D offset & ~(align - 1); - } - - if ((offset + bytes) & (align - 1)) { - if (!use_local_qiov) { - qemu_iovec_init(&local_qiov, qiov->niov + 1); - qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size); - use_local_qiov =3D true; - } - tail_buf =3D qemu_blockalign(bs, align); - qemu_iovec_add(&local_qiov, tail_buf, - align - ((offset + bytes) & (align - 1))); - - bytes =3D ROUND_UP(bytes, align); - } + bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad); =20 tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ); - ret =3D bdrv_aligned_preadv(child, &req, offset, bytes, align, - use_local_qiov ? &local_qiov : qiov, - flags); + ret =3D bdrv_aligned_preadv(child, &req, offset, bytes, + bs->bl.request_alignment, + qiov, flags); tracked_request_end(&req); bdrv_dec_in_flight(bs); =20 - if (use_local_qiov) { - qemu_iovec_destroy(&local_qiov); - qemu_vfree(head_buf); - qemu_vfree(tail_buf); - } + bdrv_padding_destroy(&pad); =20 return ret; } @@ -1711,44 +1823,34 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(Bdr= vChild *child, BdrvTrackedRequest *req) { BlockDriverState *bs =3D child->bs; - uint8_t *buf =3D NULL; QEMUIOVector local_qiov; uint64_t align =3D bs->bl.request_alignment; - unsigned int head_padding_bytes, tail_padding_bytes; int ret =3D 0; + bool padding; + BdrvRequestPadding pad; =20 - head_padding_bytes =3D offset & (align - 1); - tail_padding_bytes =3D (align - (offset + bytes)) & (align - 1); - - - assert(flags & BDRV_REQ_ZERO_WRITE); - if (head_padding_bytes || tail_padding_bytes) { - buf =3D qemu_blockalign(bs, align); - qemu_iovec_init_buf(&local_qiov, buf, align); - } - if (head_padding_bytes) { - uint64_t zero_bytes =3D MIN(bytes, align - head_padding_bytes); - - /* RMW the unaligned part before head. */ + padding =3D bdrv_init_padding(bs, offset, bytes, &pad); + if (padding) { mark_request_serialising(req, align); wait_serialising_requests(req); - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); - ret =3D bdrv_aligned_preadv(child, req, offset & ~(align - 1), ali= gn, - align, &local_qiov, 0); - if (ret < 0) { - goto fail; - } - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD); =20 - memset(buf + head_padding_bytes, 0, zero_bytes); - ret =3D bdrv_aligned_pwritev(child, req, offset & ~(align - 1), al= ign, - align, &local_qiov, - flags & ~BDRV_REQ_ZERO_WRITE); - if (ret < 0) { - goto fail; + bdrv_padding_rmw_read(child, req, &pad, true); + + if (pad.head || pad.merge_reads) { + int64_t aligned_offset =3D offset & ~(align - 1); + int64_t write_bytes =3D pad.merge_reads ? pad.buf_len : align; + + qemu_iovec_init_buf(&local_qiov, pad.buf, write_bytes); + ret =3D bdrv_aligned_pwritev(child, req, aligned_offset, write= _bytes, + align, &local_qiov, + flags & ~BDRV_REQ_ZERO_WRITE); + if (ret < 0 || pad.merge_reads) { + /* Error or all work is done */ + goto out; + } + offset +=3D write_bytes - pad.head; + bytes -=3D write_bytes - pad.head; } - offset +=3D zero_bytes; - bytes -=3D zero_bytes; } =20 assert(!bytes || (offset & (align - 1)) =3D=3D 0); @@ -1758,7 +1860,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvC= hild *child, ret =3D bdrv_aligned_pwritev(child, req, offset, aligned_bytes, al= ign, NULL, flags); if (ret < 0) { - goto fail; + goto out; } bytes -=3D aligned_bytes; offset +=3D aligned_bytes; @@ -1766,26 +1868,17 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(Bdr= vChild *child, =20 assert(!bytes || (offset & (align - 1)) =3D=3D 0); if (bytes) { - assert(align =3D=3D tail_padding_bytes + bytes); - /* RMW the unaligned part after tail. */ - mark_request_serialising(req, align); - wait_serialising_requests(req); - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); - ret =3D bdrv_aligned_preadv(child, req, offset, align, - align, &local_qiov, 0); - if (ret < 0) { - goto fail; - } - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); + assert(align =3D=3D pad.tail + bytes); =20 - memset(buf, 0, bytes); + qemu_iovec_init_buf(&local_qiov, pad.tail_buf, align); ret =3D bdrv_aligned_pwritev(child, req, offset, align, align, &local_qiov, flags & ~BDRV_REQ_ZERO_WRI= TE); } -fail: - qemu_vfree(buf); - return ret; =20 +out: + bdrv_padding_destroy(&pad); + + return ret; } =20 /* @@ -1798,10 +1891,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, BlockDriverState *bs =3D child->bs; BdrvTrackedRequest req; uint64_t align =3D bs->bl.request_alignment; - uint8_t *head_buf =3D NULL; - uint8_t *tail_buf =3D NULL; - QEMUIOVector local_qiov; - bool use_local_qiov =3D false; + BdrvRequestPadding pad; int ret; =20 trace_bdrv_co_pwritev(child->bs, offset, bytes, flags); @@ -1828,86 +1918,21 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, goto out; } =20 - if (offset & (align - 1)) { - QEMUIOVector head_qiov; - + if (bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad)) { mark_request_serialising(&req, align); wait_serialising_requests(&req); - - head_buf =3D qemu_blockalign(bs, align); - qemu_iovec_init_buf(&head_qiov, head_buf, align); - - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); - ret =3D bdrv_aligned_preadv(child, &req, offset & ~(align - 1), al= ign, - align, &head_qiov, 0); - if (ret < 0) { - goto fail; - } - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD); - - qemu_iovec_init(&local_qiov, qiov->niov + 2); - qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1)); - qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size); - use_local_qiov =3D true; - - bytes +=3D offset & (align - 1); - offset =3D offset & ~(align - 1); - - /* We have read the tail already if the request is smaller - * than one aligned block. - */ - if (bytes < align) { - qemu_iovec_add(&local_qiov, head_buf + bytes, align - bytes); - bytes =3D align; - } - } - - if ((offset + bytes) & (align - 1)) { - QEMUIOVector tail_qiov; - size_t tail_bytes; - bool waited; - - mark_request_serialising(&req, align); - waited =3D wait_serialising_requests(&req); - assert(!waited || !use_local_qiov); - - tail_buf =3D qemu_blockalign(bs, align); - qemu_iovec_init_buf(&tail_qiov, tail_buf, align); - - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); - ret =3D bdrv_aligned_preadv(child, &req, (offset + bytes) & ~(alig= n - 1), - align, align, &tail_qiov, 0); - if (ret < 0) { - goto fail; - } - bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL); - - if (!use_local_qiov) { - qemu_iovec_init(&local_qiov, qiov->niov + 1); - qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size); - use_local_qiov =3D true; - } - - tail_bytes =3D (offset + bytes) & (align - 1); - qemu_iovec_add(&local_qiov, tail_buf + tail_bytes, align - tail_by= tes); - - bytes =3D ROUND_UP(bytes, align); + bdrv_padding_rmw_read(child, &req, &pad, false); } =20 ret =3D bdrv_aligned_pwritev(child, &req, offset, bytes, align, - use_local_qiov ? &local_qiov : qiov, - flags); + qiov, flags); =20 -fail: + bdrv_padding_destroy(&pad); =20 - if (use_local_qiov) { - qemu_iovec_destroy(&local_qiov); - } - qemu_vfree(head_buf); - qemu_vfree(tail_buf); out: tracked_request_end(&req); bdrv_dec_in_flight(bs); + return ret; } =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665503; cv=none; d=zoho.com; s=zohoarc; b=ItQ6noNw8tcoyCqcuKVU9XKQ806pioEMLPrISyBlNQ4LzvGwinrRk3TOmrkt8zX/vy4uqo5HcjoS/p0hIgfDIDvBZnu3dk9+9r6xDjOboZsXXR9TGoAOdlWhbzwnb9MKCVVracVBJxsNOqrRa1aQccoWVJZJufNZwez/TVtVjws= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665503; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=wQijCmbHUwWEUZGX6Q4IF19pEifg4dOIjUvhS42vUAU=; b=SxV08T46FdEC33n2dBlwx1mdbx8vy++8U5091bafiYUysonbJuSkfqq/TapZx8BnrxKv85fJjapQBVCTIn30HO2xl44fCvCqZWZUah0tlcW12NidudNkSojOiyTgBCHbMRJqGu9sgQn9TPuyf0X8jXXi2paY9TzXc5I0pnTHJg4= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 155966550311089.84056204488866; Tue, 4 Jun 2019 09:25:03 -0700 (PDT) Received: from localhost ([127.0.0.1]:54953 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCF7-0007lZ-9D for importer@patchew.org; Tue, 04 Jun 2019 12:24:57 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35826) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6E-00014b-29 for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6A-0005f6-Dp for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:45 -0400 Received: from relay.sw.ru ([185.231.240.75]:41692) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC68-0005C0-Hf; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5j-0005Pq-MY; Tue, 04 Jun 2019 19:15:15 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:06 +0300 Message-Id: <20190604161514.262241-5-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 04/12] block: define .*_part io handlers in BlockDriver 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add handlers supporting qiov_offset parameter: bdrv_co_preadv_part bdrv_co_pwritev_part bdrv_co_pwritev_compressed_part This is used to reduce need of defining local_qiovs and hd_qiovs in all corners of block layer code. The following patches will increase usage of this new API part by part. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- include/block/block_int.h | 15 ++++++ block/backup.c | 2 +- block/io.c | 96 +++++++++++++++++++++++++++++++-------- qemu-img.c | 4 +- 4 files changed, 95 insertions(+), 22 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 1eebc7c8f3..46e17d2e2f 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -211,6 +211,9 @@ struct BlockDriver { */ int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags); + int coroutine_fn (*bdrv_co_preadv_part)(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, size_t qiov_offset, int flags); int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags); /** @@ -230,6 +233,9 @@ struct BlockDriver { */ int coroutine_fn (*bdrv_co_pwritev)(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags); + int coroutine_fn (*bdrv_co_pwritev_part)(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, size_t qiov_offset, int flags); =20 /* * Efficiently zero a region of the disk image. Typically an image fo= rmat @@ -340,6 +346,9 @@ struct BlockDriver { =20 int coroutine_fn (*bdrv_co_pwritev_compressed)(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov); + int coroutine_fn (*bdrv_co_pwritev_compressed_part)(BlockDriverState *= bs, + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, + size_t qiov_offset); =20 int (*bdrv_snapshot_create)(BlockDriverState *bs, QEMUSnapshotInfo *sn_info); @@ -564,6 +573,12 @@ struct BlockDriver { const char *const *strong_runtime_opts; }; =20 +static inline bool block_driver_can_compress(BlockDriver *drv) +{ + return drv->bdrv_co_pwritev_compressed || + drv->bdrv_co_pwritev_compressed_part; +} + typedef struct BlockLimits { /* Alignment requirement, in bytes, for offset/length of I/O * requests. Must be a power of 2 less than INT_MAX; defaults to diff --git a/block/backup.c b/block/backup.c index 00f4f8af53..af821b8990 100644 --- a/block/backup.c +++ b/block/backup.c @@ -569,7 +569,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDr= iverState *bs, return NULL; } =20 - if (compress && target->drv->bdrv_co_pwritev_compressed =3D=3D NULL) { + if (compress && !block_driver_can_compress(target->drv)) { error_setg(errp, "Compression is not supported for this drive %s", bdrv_get_device_name(target)); return NULL; diff --git a/block/io.c b/block/io.c index ddd5902dc1..7e53a11492 100644 --- a/block/io.c +++ b/block/io.c @@ -128,7 +128,8 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **= errp) =20 /* Default alignment based on whether driver has byte interface */ bs->bl.request_alignment =3D (drv->bdrv_co_preadv || - drv->bdrv_aio_preadv) ? 1 : 512; + drv->bdrv_aio_preadv || + drv->bdrv_co_preadv_part) ? 1 : 512; =20 /* Take some limits from the children as a default */ if (bs->file) { @@ -979,11 +980,14 @@ static void bdrv_co_io_em_complete(void *opaque, int = ret) =20 static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov, int flags) + QEMUIOVector *qiov, + size_t qiov_offset, int flags) { BlockDriver *drv =3D bs->drv; int64_t sector_num; unsigned int nb_sectors; + QEMUIOVector local_qiov; + int ret; =20 assert(!(flags & ~BDRV_REQ_MASK)); assert(!(flags & BDRV_REQ_NO_FALLBACK)); @@ -992,8 +996,19 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriver= State *bs, return -ENOMEDIUM; } =20 + if (drv->bdrv_co_preadv_part) { + return drv->bdrv_co_preadv_part(bs, offset, bytes, qiov, qiov_offs= et, + flags); + } + + if (qiov_offset > 0 || bytes !=3D qiov->size) { + qemu_iovec_init_slice(&local_qiov, qiov, qiov_offset, bytes); + qiov =3D &local_qiov; + } + if (drv->bdrv_co_preadv) { - return drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags); + ret =3D drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags); + goto out; } =20 if (drv->bdrv_aio_preadv) { @@ -1005,10 +1020,12 @@ static int coroutine_fn bdrv_driver_preadv(BlockDri= verState *bs, acb =3D drv->bdrv_aio_preadv(bs, offset, bytes, qiov, flags, bdrv_co_io_em_complete, &co); if (acb =3D=3D NULL) { - return -EIO; + ret =3D -EIO; + goto out; } else { qemu_coroutine_yield(); - return co.ret; + ret =3D co.ret; + goto out; } } =20 @@ -1020,16 +1037,25 @@ static int coroutine_fn bdrv_driver_preadv(BlockDri= verState *bs, assert(bytes <=3D BDRV_REQUEST_MAX_BYTES); assert(drv->bdrv_co_readv); =20 - return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + ret =3D drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); + +out: + if (qiov =3D=3D &local_qiov) { + qemu_iovec_destroy(&local_qiov); + } + + return ret; } =20 static int coroutine_fn bdrv_driver_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t byte= s, - QEMUIOVector *qiov, int flags) + QEMUIOVector *qiov, + size_t qiov_offset, int flags) { BlockDriver *drv =3D bs->drv; int64_t sector_num; unsigned int nb_sectors; + QEMUIOVector local_qiov; int ret; =20 assert(!(flags & ~BDRV_REQ_MASK)); @@ -1039,6 +1065,18 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDri= verState *bs, return -ENOMEDIUM; } =20 + if (drv->bdrv_co_pwritev_part) { + ret =3D drv->bdrv_co_pwritev_part(bs, offset, bytes, qiov, qiov_of= fset, + flags & bs->supported_write_flags); + flags &=3D ~bs->supported_write_flags; + goto emulate_flags; + } + + if (qiov_offset > 0 || bytes !=3D qiov->size) { + qemu_iovec_init_slice(&local_qiov, qiov, qiov_offset, bytes); + qiov =3D &local_qiov; + } + if (drv->bdrv_co_pwritev) { ret =3D drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags & bs->supported_write_flags); @@ -1082,24 +1120,44 @@ emulate_flags: ret =3D bdrv_co_flush(bs); } =20 + if (qiov =3D=3D &local_qiov) { + qemu_iovec_destroy(&local_qiov); + } + return ret; } =20 static int coroutine_fn bdrv_driver_pwritev_compressed(BlockDriverState *bs, uint64_t offset, - uint64_t bytes, QEMUIOVector *qiov) + uint64_t bytes, QEMUIOVector *qiov, + size_t qiov_offset) { BlockDriver *drv =3D bs->drv; + QEMUIOVector local_qiov; + int ret; =20 if (!drv) { return -ENOMEDIUM; } =20 - if (!drv->bdrv_co_pwritev_compressed) { + if (!block_driver_can_compress(drv)) { return -ENOTSUP; } =20 - return drv->bdrv_co_pwritev_compressed(bs, offset, bytes, qiov); + if (drv->bdrv_co_pwritev_compressed_part) { + return drv->bdrv_co_pwritev_compressed_part(bs, offset, bytes, + qiov, qiov_offset); + } + + if (qiov_offset =3D=3D 0) { + return drv->bdrv_co_pwritev_compressed(bs, offset, bytes, qiov); + } + + qemu_iovec_init_slice(&local_qiov, qiov, qiov_offset, bytes); + ret =3D drv->bdrv_co_pwritev_compressed(bs, offset, bytes, &local_qiov= ); + qemu_iovec_destroy(&local_qiov); + + return ret; } =20 static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, @@ -1183,7 +1241,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum); =20 ret =3D bdrv_driver_preadv(bs, cluster_offset, pnum, - &local_qiov, 0); + &local_qiov, 0, 0); if (ret < 0) { goto err; } @@ -1201,7 +1259,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, * necessary to flush even in cache=3Dwritethrough mode. */ ret =3D bdrv_driver_pwritev(bs, cluster_offset, pnum, - &local_qiov, + &local_qiov, 0, BDRV_REQ_WRITE_UNCHANGED); } =20 @@ -1221,7 +1279,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, qemu_iovec_init(&local_qiov, qiov->niov); qemu_iovec_concat(&local_qiov, qiov, progress, pnum - skip_byt= es); ret =3D bdrv_driver_preadv(bs, offset + progress, local_qiov.s= ize, - &local_qiov, 0); + &local_qiov, 0, 0); qemu_iovec_destroy(&local_qiov); if (ret < 0) { goto err; @@ -1309,7 +1367,7 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild= *child, =20 max_bytes =3D ROUND_UP(MAX(0, total_bytes - offset), align); if (bytes <=3D max_bytes && bytes <=3D max_transfer) { - ret =3D bdrv_driver_preadv(bs, offset, bytes, qiov, 0); + ret =3D bdrv_driver_preadv(bs, offset, bytes, qiov, 0, 0); goto out; } =20 @@ -1325,7 +1383,7 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild= *child, qemu_iovec_concat(&local_qiov, qiov, bytes - bytes_remaining, = num); =20 ret =3D bdrv_driver_preadv(bs, offset + bytes - bytes_remainin= g, - num, &local_qiov, 0); + num, &local_qiov, 0, 0); max_bytes -=3D num; qemu_iovec_destroy(&local_qiov); } else { @@ -1620,7 +1678,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(Bloc= kDriverState *bs, } qemu_iovec_init_buf(&qiov, buf, num); =20 - ret =3D bdrv_driver_pwritev(bs, offset, num, &qiov, write_flag= s); + ret =3D bdrv_driver_pwritev(bs, offset, num, &qiov, 0, write_f= lags); =20 /* Keep bounce buffer around if it is big enough for all * all future requests. @@ -1776,10 +1834,10 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvCh= ild *child, bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO); ret =3D bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags); } else if (flags & BDRV_REQ_WRITE_COMPRESSED) { - ret =3D bdrv_driver_pwritev_compressed(bs, offset, bytes, qiov); + ret =3D bdrv_driver_pwritev_compressed(bs, offset, bytes, qiov, 0); } else if (bytes <=3D max_transfer) { bdrv_debug_event(bs, BLKDBG_PWRITEV); - ret =3D bdrv_driver_pwritev(bs, offset, bytes, qiov, flags); + ret =3D bdrv_driver_pwritev(bs, offset, bytes, qiov, 0, flags); } else { bdrv_debug_event(bs, BLKDBG_PWRITEV); while (bytes_remaining) { @@ -1798,7 +1856,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChil= d *child, qemu_iovec_concat(&local_qiov, qiov, bytes - bytes_remaining, = num); =20 ret =3D bdrv_driver_pwritev(bs, offset + bytes - bytes_remaini= ng, - num, &local_qiov, local_flags); + num, &local_qiov, 0, local_flags); qemu_iovec_destroy(&local_qiov); if (ret < 0) { break; diff --git a/qemu-img.c b/qemu-img.c index b0535919b1..8a62a75a71 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2329,7 +2329,7 @@ static int img_convert(int argc, char **argv) const char *preallocation =3D qemu_opt_get(opts, BLOCK_OPT_PREALLOC); =20 - if (drv && !drv->bdrv_co_pwritev_compressed) { + if (drv && !block_driver_can_compress(drv)) { error_report("Compression not supported for this file format"); ret =3D -1; goto out; @@ -2398,7 +2398,7 @@ static int img_convert(int argc, char **argv) } out_bs =3D blk_bs(s.target); =20 - if (s.compressed && !out_bs->drv->bdrv_co_pwritev_compressed) { + if (s.compressed && !block_driver_can_compress(out_bs->drv)) { error_report("Compression not supported for this file format"); ret =3D -1; goto out; --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665822; cv=none; d=zoho.com; s=zohoarc; b=DABqYrQqQgYVdNeEAoNFfp3lEbonLR8rPDkVLqAqzphCvZ4wkybEk+rrXCQIKptYqbme6OxxDjgQPwWMGBJ/PwjLodccyfYLfwegBMDSDBLG/f1F7T/regqlSA9CLi4e9VsxI36iE0eLRg4EtIXSzVGO516DRacj3n6PDzzfRV8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665822; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=P7sEm/YyQGccySxq+NUV1d4YxZTd+Rawb5a/RPCiEac=; b=oMe9JDI/IkRhld2XHMBJCDOO4EBnRNn9uCU9iGUE/vYaOh6hgJv/r8iOfI6WKXc1Jox+0jWin7V7wUnOagS1imIjxZEr0TUbDXapDcHU64lb15+hX3R6uiz8xzNTC1C6fsWa7tdNmwGJM3R+wHzeN/+a5R9Btsy67KErlLZDUaU= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665822523198.14143503728678; Tue, 4 Jun 2019 09:30:22 -0700 (PDT) Received: from localhost ([127.0.0.1]:55087 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCKG-0004Gb-Hc for importer@patchew.org; Tue, 04 Jun 2019 12:30:16 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35853) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6F-00016R-Su for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6B-0005ge-6u for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:45 -0400 Received: from relay.sw.ru ([185.231.240.75]:41652) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005Bw-Mh; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5j-0005Pq-Qk; Tue, 04 Jun 2019 19:15:15 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:07 +0300 Message-Id: <20190604161514.262241-6-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 05/12] block/io: bdrv_co_do_copy_on_readv: use and support qiov_offset 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use and support new API in bdrv_co_do_copy_on_readv. Note that in case of allocated-in-top we need to shrink read size to MIN(..) by hand, as pre-patch this was actually done implicitly by qemu_iovec_concat (and we used local_qiov.size). Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/io.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/block/io.c b/block/io.c index 7e53a11492..efd2b80293 100644 --- a/block/io.c +++ b/block/io.c @@ -1161,7 +1161,8 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, = uint64_t offset, } =20 static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, - int64_t offset, unsigned int bytes, QEMUIOVector *qiov) + int64_t offset, unsigned int bytes, + QEMUIOVector *qiov, size_t qiov_offset) { BlockDriverState *bs =3D child->bs; =20 @@ -1173,7 +1174,6 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, void *bounce_buffer; =20 BlockDriver *drv =3D bs->drv; - QEMUIOVector local_qiov; int64_t cluster_offset; int64_t cluster_bytes; size_t skip_bytes; @@ -1236,6 +1236,8 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, assert(skip_bytes < pnum); =20 if (ret <=3D 0) { + QEMUIOVector local_qiov; + /* Must copy-on-read; use the bounce buffer */ pnum =3D MIN(pnum, MAX_BOUNCE_BUFFER); qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum); @@ -1272,15 +1274,14 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bd= rvChild *child, goto err; } =20 - qemu_iovec_from_buf(qiov, progress, bounce_buffer + skip_bytes, + qemu_iovec_from_buf(qiov, qiov_offset + progress, + bounce_buffer + skip_bytes, pnum - skip_bytes); } else { /* Read directly into the destination */ - qemu_iovec_init(&local_qiov, qiov->niov); - qemu_iovec_concat(&local_qiov, qiov, progress, pnum - skip_byt= es); - ret =3D bdrv_driver_preadv(bs, offset + progress, local_qiov.s= ize, - &local_qiov, 0, 0); - qemu_iovec_destroy(&local_qiov); + ret =3D bdrv_driver_preadv(bs, offset + progress, + MIN(pnum - skip_bytes, bytes - progre= ss), + qiov, qiov_offset + progress, 0); if (ret < 0) { goto err; } @@ -1353,7 +1354,7 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild= *child, } =20 if (!ret || pnum !=3D bytes) { - ret =3D bdrv_co_do_copy_on_readv(child, offset, bytes, qiov); + ret =3D bdrv_co_do_copy_on_readv(child, offset, bytes, qiov, 0= ); goto out; } } --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665665; cv=none; d=zoho.com; s=zohoarc; b=BEosD+hn4LKB1taJ25zKnyF3GB1uRBTHPhaV+VZYPCOuBsWwaH1k4vD8NLK965CwMRwxXwkCd7AhGyM1tRNJ2Eht0z9fadIkiZXid4OP3JpyremOfC37+tYX1c1gMNTMcyt5+ySKfBMrSZrerdoNGd1NnIMU5VAhAai3ajoI3E8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665665; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=yrgsfq0T+mZGRnjRGo423/ta++iGnm6p8AIb78lb18I=; b=jXukODHkytvvh+2KJnpyKUktLtVK4nzvsf9WH/QS+CtgH9A2x+KYyd/l0oZ4KLwoVonTWyNA8Y3ej2zBz/C8IpMXYPTg1kOthiFYEUbN9RndSPsfZI0W6DOegzGqSfjT3DOk3yJKo3yqsANfb4od71m2sqQzvplWpVc7/ilYZqM= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665665210743.055055997685; Tue, 4 Jun 2019 09:27:45 -0700 (PDT) Received: from localhost ([127.0.0.1]:55043 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCHd-0001o7-5G for importer@patchew.org; Tue, 04 Jun 2019 12:27:33 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35854) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6F-00016S-TA for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6B-0005gj-7u for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:45 -0400 Received: from relay.sw.ru ([185.231.240.75]:41686) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005C6-N3; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5j-0005Pq-UJ; Tue, 04 Jun 2019 19:15:15 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:08 +0300 Message-Id: <20190604161514.262241-7-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 06/12] block/io: bdrv_co_do_copy_on_readv: lazy allocation 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Allocate bounce_buffer only if it is really needed. Also, sub-optimize allocation size (why not?). Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/io.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/block/io.c b/block/io.c index efd2b80293..a4f67aca47 100644 --- a/block/io.c +++ b/block/io.c @@ -1171,7 +1171,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, * modifying the image file. This is critical for zero-copy guest I/O * where anything might happen inside guest memory. */ - void *bounce_buffer; + void *bounce_buffer =3D NULL; =20 BlockDriver *drv =3D bs->drv; int64_t cluster_offset; @@ -1206,14 +1206,6 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdr= vChild *child, trace_bdrv_co_do_copy_on_readv(bs, offset, bytes, cluster_offset, cluster_bytes); =20 - bounce_buffer =3D qemu_try_blockalign(bs, - MIN(MIN(max_transfer, cluster_byte= s), - MAX_BOUNCE_BUFFER)); - if (bounce_buffer =3D=3D NULL) { - ret =3D -ENOMEM; - goto err; - } - while (cluster_bytes) { int64_t pnum; =20 @@ -1240,6 +1232,17 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdr= vChild *child, =20 /* Must copy-on-read; use the bounce buffer */ pnum =3D MIN(pnum, MAX_BOUNCE_BUFFER); + if (!bounce_buffer) { + int64_t max_we_need =3D MAX(pnum, cluster_bytes - pnum); + int64_t max_allowed =3D MIN(max_transfer, MAX_BOUNCE_BUFFE= R); + int64_t bounce_buffer_len =3D MIN(max_we_need, max_allowed= ); + + bounce_buffer =3D qemu_try_blockalign(bs, bounce_buffer_le= n); + if (!bounce_buffer) { + ret =3D -ENOMEM; + goto err; + } + } qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum); =20 ret =3D bdrv_driver_preadv(bs, cluster_offset, pnum, --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665320; cv=none; d=zoho.com; s=zohoarc; b=FIx1akK08vNLiq4ZYdVbmbKYzyNiUo1eQSN9e8QHvpDV181fUMLZxnTvTuxy6dQxEdrDqUp3DYg24Q5LqREfWWGsHGZQW7ey4ADLmrdErSCGFnwCiBg9fnMqQXDzT09gh+gxsONP9znsVpR2NcR0tC74pjVhKe2nj/wym5l8eoU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665320; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=cu5XCHNf1ujlH6oUK4YSVfStc6I/QqY1DJBxYWmMn9k=; b=obpaJpzVnPn46qXVog2IuEnFiCNMZpNcDTi56suS9IYhqRcCcNy1h6mrod4slm1SpxJWkWPsB68/RHmszcMrQFmVkxhUQGircwTMHsWyfKY4WbVwcx7vRxH1pgeX+M8WTbogbrIOa/q577jXrV9e8cSVWM3T9dWgdz5jjLS7SYc= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665320252735.3142484131288; Tue, 4 Jun 2019 09:22:00 -0700 (PDT) Received: from localhost ([127.0.0.1]:54907 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCC3-0004xQ-VF for importer@patchew.org; Tue, 04 Jun 2019 12:21:48 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35821) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6D-000148-KF for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6A-0005fs-Qc for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:44 -0400 Received: from relay.sw.ru ([185.231.240.75]:41680) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005Bz-Iv; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5k-0005Pq-2h; Tue, 04 Jun 2019 19:15:16 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:09 +0300 Message-Id: <20190604161514.262241-8-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 07/12] block/io: bdrv_aligned_preadv: use and support qiov_offset 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use and support new API in bdrv_co_do_copy_on_readv. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/io.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/block/io.c b/block/io.c index a4f67aca47..0cc80e2d5a 100644 --- a/block/io.c +++ b/block/io.c @@ -1309,7 +1309,7 @@ err: */ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, BdrvTrackedRequest *req, int64_t offset, unsigned int bytes, - int64_t align, QEMUIOVector *qiov, int flags) + int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags) { BlockDriverState *bs =3D child->bs; int64_t total_bytes, max_bytes; @@ -1320,7 +1320,6 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild= *child, assert(is_power_of_2(align)); assert((offset & (align - 1)) =3D=3D 0); assert((bytes & (align - 1)) =3D=3D 0); - assert(!qiov || bytes =3D=3D qiov->size); assert((bs->open_flags & BDRV_O_NO_IO) =3D=3D 0); max_transfer =3D QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT= _MAX), align); @@ -1357,7 +1356,8 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild= *child, } =20 if (!ret || pnum !=3D bytes) { - ret =3D bdrv_co_do_copy_on_readv(child, offset, bytes, qiov, 0= ); + ret =3D bdrv_co_do_copy_on_readv(child, offset, bytes, + qiov, qiov_offset); goto out; } } @@ -1371,7 +1371,7 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild= *child, =20 max_bytes =3D ROUND_UP(MAX(0, total_bytes - offset), align); if (bytes <=3D max_bytes && bytes <=3D max_transfer) { - ret =3D bdrv_driver_preadv(bs, offset, bytes, qiov, 0, 0); + ret =3D bdrv_driver_preadv(bs, offset, bytes, qiov, qiov_offset, 0= ); goto out; } =20 @@ -1379,17 +1379,12 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChi= ld *child, int num; =20 if (max_bytes) { - QEMUIOVector local_qiov; - num =3D MIN(bytes_remaining, MIN(max_bytes, max_transfer)); assert(num); - qemu_iovec_init(&local_qiov, qiov->niov); - qemu_iovec_concat(&local_qiov, qiov, bytes - bytes_remaining, = num); =20 ret =3D bdrv_driver_preadv(bs, offset + bytes - bytes_remainin= g, - num, &local_qiov, 0, 0); + num, qiov, bytes - bytes_remaining, 0= ); max_bytes -=3D num; - qemu_iovec_destroy(&local_qiov); } else { num =3D bytes_remaining; ret =3D qemu_iovec_memset(qiov, bytes - bytes_remaining, 0, @@ -1486,7 +1481,7 @@ static int bdrv_padding_rmw_read(BdrvChild *child, =20 bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); ret =3D bdrv_aligned_preadv(child, req, req->overlap_offset, bytes, - align, &local_qiov, 0); + align, &local_qiov, 0, 0); if (ret < 0) { return ret; } @@ -1504,7 +1499,7 @@ static int bdrv_padding_rmw_read(BdrvChild *child, ret =3D bdrv_aligned_preadv( child, req, req->overlap_offset + req->overlap_bytes - align, - align, align, &local_qiov, 0); + align, align, &local_qiov, 0, 0); if (ret < 0) { return ret; } @@ -1585,7 +1580,7 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child, tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ); ret =3D bdrv_aligned_preadv(child, &req, offset, bytes, bs->bl.request_alignment, - qiov, flags); + qiov, 0, flags); tracked_request_end(&req); bdrv_dec_in_flight(bs); =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665098; cv=none; d=zoho.com; s=zohoarc; b=TTyOpdYwNgLU9GcqbcnWe9mLhZ84h/6Dav0+C1iNVo2Pd4dHoE5HW4k8AeWuBj0L4kadjsOvrGPK5LEk6uymPoZWdSiqKorsfocx2JF8eyuirXQ39mgIs34bZffLJK6hME7iUug8hUbn927ca2MEz32Xjrzn/pKirxD2z1/5NzM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665098; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=UYN3LGZ+6rLtowiCpRDKpwQQg8BI7wTbp7rd4T6o2rc=; b=Mpa6hc40et+tiAWhNOR0Jq7yzMlD0lv+aKnQC6Wfq3exw2WlL1ZVzlJM0nbGW/9nLgD+s+FNfUZ9cfqLnLi9M9QqGuPOZGxu/D2TboQE+xA+VSnfmKSVBhQrE+R7gYuOw3MFNIaJAVqJxPpVA6YBZBsrISMt33FmcobHSn0ClhM= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665098673107.63462966961674; Tue, 4 Jun 2019 09:18:18 -0700 (PDT) Received: from localhost ([127.0.0.1]:54854 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC8c-0002TS-JW for importer@patchew.org; Tue, 04 Jun 2019 12:18:14 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35711) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6A-00011c-Ac for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC66-0005Y8-6w for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:40 -0400 Received: from relay.sw.ru ([185.231.240.75]:41656) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC61-0005Bv-5K; Tue, 04 Jun 2019 12:15:34 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5k-0005Pq-BF; Tue, 04 Jun 2019 19:15:16 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:10 +0300 Message-Id: <20190604161514.262241-9-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 08/12] block/io: bdrv_aligned_pwritev: use and support qiov_offset 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use and support new API in bdrv_aligned_pwritev. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/io.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/block/io.c b/block/io.c index 0cc80e2d5a..660c96527d 100644 --- a/block/io.c +++ b/block/io.c @@ -1792,7 +1792,7 @@ bdrv_co_write_req_finish(BdrvChild *child, int64_t of= fset, uint64_t bytes, */ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child, BdrvTrackedRequest *req, int64_t offset, unsigned int bytes, - int64_t align, QEMUIOVector *qiov, int flags) + int64_t align, QEMUIOVector *qiov, size_t qiov_offset, int flags) { BlockDriverState *bs =3D child->bs; BlockDriver *drv =3D bs->drv; @@ -1812,7 +1812,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChil= d *child, assert(is_power_of_2(align)); assert((offset & (align - 1)) =3D=3D 0); assert((bytes & (align - 1)) =3D=3D 0); - assert(!qiov || bytes =3D=3D qiov->size); + assert(!qiov || qiov_offset + bytes <=3D qiov->size); max_transfer =3D QEMU_ALIGN_DOWN(MIN_NON_ZERO(bs->bl.max_transfer, INT= _MAX), align); =20 @@ -1820,7 +1820,7 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChil= d *child, =20 if (!ret && bs->detect_zeroes !=3D BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF = && !(flags & BDRV_REQ_ZERO_WRITE) && drv->bdrv_co_pwrite_zeroes && - qemu_iovec_is_zero(qiov, 0, qiov->size)) { + qemu_iovec_is_zero(qiov, qiov_offset, bytes)) { flags |=3D BDRV_REQ_ZERO_WRITE; if (bs->detect_zeroes =3D=3D BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP)= { flags |=3D BDRV_REQ_MAY_UNMAP; @@ -1833,15 +1833,15 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvCh= ild *child, bdrv_debug_event(bs, BLKDBG_PWRITEV_ZERO); ret =3D bdrv_co_do_pwrite_zeroes(bs, offset, bytes, flags); } else if (flags & BDRV_REQ_WRITE_COMPRESSED) { - ret =3D bdrv_driver_pwritev_compressed(bs, offset, bytes, qiov, 0); + ret =3D bdrv_driver_pwritev_compressed(bs, offset, bytes, + qiov, qiov_offset); } else if (bytes <=3D max_transfer) { bdrv_debug_event(bs, BLKDBG_PWRITEV); - ret =3D bdrv_driver_pwritev(bs, offset, bytes, qiov, 0, flags); + ret =3D bdrv_driver_pwritev(bs, offset, bytes, qiov, qiov_offset, = flags); } else { bdrv_debug_event(bs, BLKDBG_PWRITEV); while (bytes_remaining) { int num =3D MIN(bytes_remaining, max_transfer); - QEMUIOVector local_qiov; int local_flags =3D flags; =20 assert(num); @@ -1851,12 +1851,10 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvCh= ild *child, * need to flush on the last iteration */ local_flags &=3D ~BDRV_REQ_FUA; } - qemu_iovec_init(&local_qiov, qiov->niov); - qemu_iovec_concat(&local_qiov, qiov, bytes - bytes_remaining, = num); =20 ret =3D bdrv_driver_pwritev(bs, offset + bytes - bytes_remaini= ng, - num, &local_qiov, 0, local_flags); - qemu_iovec_destroy(&local_qiov); + num, qiov, bytes - bytes_remaining, + local_flags); if (ret < 0) { break; } @@ -1899,7 +1897,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvC= hild *child, =20 qemu_iovec_init_buf(&local_qiov, pad.buf, write_bytes); ret =3D bdrv_aligned_pwritev(child, req, aligned_offset, write= _bytes, - align, &local_qiov, + align, &local_qiov, 0, flags & ~BDRV_REQ_ZERO_WRITE); if (ret < 0 || pad.merge_reads) { /* Error or all work is done */ @@ -1915,7 +1913,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvC= hild *child, /* Write the aligned part in the middle. */ uint64_t aligned_bytes =3D bytes & ~(align - 1); ret =3D bdrv_aligned_pwritev(child, req, offset, aligned_bytes, al= ign, - NULL, flags); + NULL, 0, flags); if (ret < 0) { goto out; } @@ -1929,7 +1927,8 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvC= hild *child, =20 qemu_iovec_init_buf(&local_qiov, pad.tail_buf, align); ret =3D bdrv_aligned_pwritev(child, req, offset, align, align, - &local_qiov, flags & ~BDRV_REQ_ZERO_WRI= TE); + &local_qiov, 0, + flags & ~BDRV_REQ_ZERO_WRITE); } =20 out: @@ -1982,7 +1981,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, } =20 ret =3D bdrv_aligned_pwritev(child, &req, offset, bytes, align, - qiov, flags); + qiov, 0, flags); =20 bdrv_padding_destroy(&pad); =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665211; cv=none; d=zoho.com; s=zohoarc; b=WYjs6km/9GKo1mpE7OTDtvzdHRf2a+rGpfGFqesbx5UpteV0QG72j7hhwEReQWkMEFIU7yJHfG5RiqGgOGEsp2g2z8Wkzaya931ViTmyNr2MraMsOCzDH9+xwAWH0YMB7qTZfue8idccxy/5vgR2ddVZ56OABeP0B/PIABCz+7A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665211; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=nS42DJdcPOudIkwD5xWqVpWiipuPCp4IAUFWmO5pItE=; b=PCibEQbI8G+fBzRn/RpnCc9dhMi+JrzJCUHtdv4EOezBOeHU09dQ8Z9vNzMQWr7r54o6/ximglKtinmxj0gupkuV7MPKmDKXsXIystAH3p8dChmpR4r6DsjrWsTzuoUZu1DxpQHEvxHxFAs09u5tbRquYhzlS+UCgcRz/9tyKbg= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665211688574.5486369192838; Tue, 4 Jun 2019 09:20:11 -0700 (PDT) Received: from localhost ([127.0.0.1]:54870 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCAO-0003lt-II for importer@patchew.org; Tue, 04 Jun 2019 12:20:04 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35822) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6D-000149-KJ for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6A-0005fk-Mf for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:44 -0400 Received: from relay.sw.ru ([185.231.240.75]:41662) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005C4-EL; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5k-0005Pq-GR; Tue, 04 Jun 2019 19:15:16 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:11 +0300 Message-Id: <20190604161514.262241-10-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 09/12] block/io: introduce bdrv_co_p{read, write}v_part 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Introduce extended variants of bdrv_co_preadv and bdrv_co_pwritev with qiov_offset parameter. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- include/block/block_int.h | 6 ++++++ block/io.c | 29 +++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 46e17d2e2f..8b7b5d5b84 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -940,9 +940,15 @@ extern BlockDriver bdrv_qcow2; int coroutine_fn bdrv_co_preadv(BdrvChild *child, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); +int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, + int64_t offset, unsigned int bytes, + QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags); int coroutine_fn bdrv_co_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); +int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, + int64_t offset, unsigned int bytes, + QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags); =20 static inline int coroutine_fn bdrv_co_pread(BdrvChild *child, int64_t offset, unsigned int bytes, void *buf, BdrvRequestFlags flags) diff --git a/block/io.c b/block/io.c index 660c96527d..82051730fd 100644 --- a/block/io.c +++ b/block/io.c @@ -1534,7 +1534,8 @@ static void bdrv_padding_destroy(BdrvRequestPadding *= pad) * * Function always succeeds. */ -static bool bdrv_pad_request(BlockDriverState *bs, QEMUIOVector **qiov, +static bool bdrv_pad_request(BlockDriverState *bs, + QEMUIOVector **qiov, size_t *qiov_offset, int64_t *offset, unsigned int *bytes, BdrvRequestPadding *pad) { @@ -1543,11 +1544,12 @@ static bool bdrv_pad_request(BlockDriverState *bs, = QEMUIOVector **qiov, } =20 qemu_iovec_init_extended(&pad->local_qiov, pad->buf, pad->head, - *qiov, 0, *bytes, + *qiov, *qiov_offset, *bytes, pad->buf + pad->buf_len - pad->tail, pad->tai= l); *bytes +=3D pad->head + pad->tail; *offset -=3D pad->head; *qiov =3D &pad->local_qiov; + *qiov_offset =3D 0; =20 return true; } @@ -1555,6 +1557,14 @@ static bool bdrv_pad_request(BlockDriverState *bs, Q= EMUIOVector **qiov, int coroutine_fn bdrv_co_preadv(BdrvChild *child, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + return bdrv_co_preadv_part(child, offset, bytes, qiov, 0, flags); +} + +int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, + int64_t offset, unsigned int bytes, + QEMUIOVector *qiov, size_t qiov_offset, + BdrvRequestFlags flags) { BlockDriverState *bs =3D child->bs; BdrvTrackedRequest req; @@ -1575,12 +1585,12 @@ int coroutine_fn bdrv_co_preadv(BdrvChild *child, flags |=3D BDRV_REQ_COPY_ON_READ; } =20 - bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad); + bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pad); =20 tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_READ); ret =3D bdrv_aligned_preadv(child, &req, offset, bytes, bs->bl.request_alignment, - qiov, 0, flags); + qiov, qiov_offset, flags); tracked_request_end(&req); bdrv_dec_in_flight(bs); =20 @@ -1943,6 +1953,13 @@ out: int coroutine_fn bdrv_co_pwritev(BdrvChild *child, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags) +{ + return bdrv_co_pwritev_part(child, offset, bytes, qiov, 0, flags); +} + +int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child, + int64_t offset, unsigned int bytes, QEMUIOVector *qiov, size_t qiov_of= fset, + BdrvRequestFlags flags) { BlockDriverState *bs =3D child->bs; BdrvTrackedRequest req; @@ -1974,14 +1991,14 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, goto out; } =20 - if (bdrv_pad_request(bs, &qiov, &offset, &bytes, &pad)) { + if (bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pad)) { mark_request_serialising(&req, align); wait_serialising_requests(&req); bdrv_padding_rmw_read(child, &req, &pad, false); } =20 ret =3D bdrv_aligned_pwritev(child, &req, offset, bytes, align, - qiov, 0, flags); + qiov, qiov_offset, flags); =20 bdrv_padding_destroy(&pad); =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665342; cv=none; d=zoho.com; s=zohoarc; b=ECS2xMe247Y10TDtdoHhNzjRVENrKmu1ojfdFeaWDpQU5vX1esqqK5wKgt+9AjVlUGP7AqZFIVe7FNhIInf9Pt+If64Q0cs31oYNkaGM0Xh0owcf3xOqBjLeDTiEaNq37cfw1bX+erRlLiNk89OkiavalDoylzXMpzVt9DLNmZs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665342; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=xiCQGtIt4duoQufx+ZCicnhhOaWIhF8VtfKieQJazcE=; b=CxzD2ppYyKoZztz4Az9HtA2HTrRKN3XE666q1TGGffes5M1w4/yp45spjOKwfs958V1q+sAwcFlH/I2OVU99bCL9WialmfR0FL7FR5oLJClBTzh8Ss/LVd2tOv1UHVRM4ZbprVTIiCaNnwQIJCG0v7PhDBrb5Zl78EUiWA8cEh0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665342563423.1889967135927; Tue, 4 Jun 2019 09:22:22 -0700 (PDT) Received: from localhost ([127.0.0.1]:54909 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCC7-00050N-Vu for importer@patchew.org; Tue, 04 Jun 2019 12:21:52 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35753) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6B-00012f-PS for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6A-0005fV-JX for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:43 -0400 Received: from relay.sw.ru ([185.231.240.75]:41696) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005C2-AV; Tue, 04 Jun 2019 12:15:42 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5k-0005Pq-L1; Tue, 04 Jun 2019 19:15:16 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:12 +0300 Message-Id: <20190604161514.262241-11-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 10/12] block/qcow2: refactor qcow2_co_preadv to use buffer-based io 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use buffer based io in encrypted case. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/qcow2.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index f2cb131048..8a033ae08c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2047,19 +2047,15 @@ static coroutine_fn int qcow2_co_preadv(BlockDriver= State *bs, uint64_t offset, } =20 assert(cur_bytes <=3D QCOW_MAX_CRYPT_CLUSTERS * s->cluster= _size); - qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes); - } =20 - BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - ret =3D bdrv_co_preadv(s->data_file, - cluster_offset + offset_in_cluster, - cur_bytes, &hd_qiov, 0); - if (ret < 0) { - goto fail; - } - if (bs->encrypted) { - assert(s->crypto); + BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); + ret =3D bdrv_co_pread(s->data_file, + cluster_offset + offset_in_cluster, + cur_bytes, cluster_data, 0); + if (ret < 0) { + goto fail; + } + assert((offset & (BDRV_SECTOR_SIZE - 1)) =3D=3D 0); assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) =3D=3D 0); if (qcow2_co_decrypt(bs, cluster_offset, offset, @@ -2068,6 +2064,14 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverS= tate *bs, uint64_t offset, goto fail; } qemu_iovec_from_buf(qiov, bytes_done, cluster_data, cur_by= tes); + } else { + BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); + ret =3D bdrv_co_preadv(s->data_file, + cluster_offset + offset_in_cluster, + cur_bytes, &hd_qiov, 0); + if (ret < 0) { + goto fail; + } } break; =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665345; cv=none; d=zoho.com; s=zohoarc; b=EW0Z1j6FXnFbrsK5Qkif6O3P3mE5Ni9ux1It9zcFVkUn1at0Q3qfNESZAy1hJ/vBRhocLO1Ku6hWYq0J/ZSqkJZYSq+3JL5FltglDUF5O3yigsTdHq+2Kjv6mGcsIqOWINvdRv8R9yJ31GrQuXdkvfXByJzxHeTUtMSgxQe6Y9U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665345; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=jv3wiJH0UCujl0LH9tgGnMYVaa5KkULJYVA9+c+FUd4=; b=EMjf67g9zHmDE7n7lLXiUUSQCcnUJWbdt0B+U7tCFXBvAa+CKhGrJ1e+uyPTXJgbrClfPZRJc8/WDoOe5D0p3UlvsCRMfcWqmXoY7gkk7M3obcmgjcFQEgTZlsSik5szO6+Cl9Dd9ZEjlmXv9TUCIduCEJoujgaEgtsKQjS2AyI= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665345961667.240139407708; Tue, 4 Jun 2019 09:22:25 -0700 (PDT) Received: from localhost ([127.0.0.1]:54915 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYCCZ-0005PX-Qq for importer@patchew.org; Tue, 04 Jun 2019 12:22:19 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35899) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC6H-00018h-Si for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC6B-0005hG-CA for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:46 -0400 Received: from relay.sw.ru ([185.231.240.75]:41672) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC6A-0005By-Pm; Tue, 04 Jun 2019 12:15:43 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5k-0005Pq-Oi; Tue, 04 Jun 2019 19:15:16 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:13 +0300 Message-Id: <20190604161514.262241-12-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 11/12] block/qcow2: implement .bdrv_co_preadv_part 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement and use new interface to get rid of hd_qiov. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/qcow2-cluster.c | 5 +++-- block/qcow2.c | 49 +++++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index cf892f37a8..1159d6ed2f 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -453,8 +453,9 @@ static int coroutine_fn do_perform_cow_read(BlockDriver= State *bs, * interface. This avoids double I/O throttling and request tracking, * which can lead to deadlock when block layer copy-on-read is enabled. */ - ret =3D bs->drv->bdrv_co_preadv(bs, src_cluster_offset + offset_in_clu= ster, - qiov->size, qiov, 0); + ret =3D bs->drv->bdrv_co_preadv_part(bs, + src_cluster_offset + offset_in_clus= ter, + qiov->size, qiov, 0, 0); if (ret < 0) { return ret; } diff --git a/block/qcow2.c b/block/qcow2.c index 8a033ae08c..c389ef07b0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -75,7 +75,8 @@ qcow2_co_preadv_compressed(BlockDriverState *bs, uint64_t file_cluster_offset, uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov); + QEMUIOVector *qiov, + size_t qiov_offset); =20 static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filen= ame) { @@ -1955,21 +1956,18 @@ out: return ret; } =20 -static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t off= set, - uint64_t bytes, QEMUIOVector *qiov, - int flags) +static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, + uint64_t offset, uint64_t byt= es, + QEMUIOVector *qiov, + size_t qiov_offset, int flags) { BDRVQcow2State *s =3D bs->opaque; int offset_in_cluster; int ret; unsigned int cur_bytes; /* number of bytes in current iteration */ uint64_t cluster_offset =3D 0; - uint64_t bytes_done =3D 0; - QEMUIOVector hd_qiov; uint8_t *cluster_data =3D NULL; =20 - qemu_iovec_init(&hd_qiov, qiov->niov); - while (bytes !=3D 0) { =20 /* prepare next request */ @@ -1988,34 +1986,31 @@ static coroutine_fn int qcow2_co_preadv(BlockDriver= State *bs, uint64_t offset, =20 offset_in_cluster =3D offset_into_cluster(s, offset); =20 - qemu_iovec_reset(&hd_qiov); - qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes); - switch (ret) { case QCOW2_CLUSTER_UNALLOCATED: =20 if (bs->backing) { BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); - ret =3D bdrv_co_preadv(bs->backing, offset, cur_bytes, - &hd_qiov, 0); + ret =3D bdrv_co_preadv_part(bs->backing, offset, cur_bytes, + qiov, qiov_offset, 0); if (ret < 0) { goto fail; } } else { /* Note: in this case, no need to wait */ - qemu_iovec_memset(&hd_qiov, 0, 0, cur_bytes); + qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes); } break; =20 case QCOW2_CLUSTER_ZERO_PLAIN: case QCOW2_CLUSTER_ZERO_ALLOC: - qemu_iovec_memset(&hd_qiov, 0, 0, cur_bytes); + qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes); break; =20 case QCOW2_CLUSTER_COMPRESSED: ret =3D qcow2_co_preadv_compressed(bs, cluster_offset, offset, cur_bytes, - &hd_qiov); + qiov, qiov_offset); if (ret < 0) { goto fail; } @@ -2063,12 +2058,12 @@ static coroutine_fn int qcow2_co_preadv(BlockDriver= State *bs, uint64_t offset, ret =3D -EIO; goto fail; } - qemu_iovec_from_buf(qiov, bytes_done, cluster_data, cur_by= tes); + qemu_iovec_from_buf(qiov, qiov_offset, cluster_data, cur_b= ytes); } else { BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - ret =3D bdrv_co_preadv(s->data_file, - cluster_offset + offset_in_cluster, - cur_bytes, &hd_qiov, 0); + ret =3D bdrv_co_preadv_part(s->data_file, + cluster_offset + offset_in_clust= er, + cur_bytes, qiov, qiov_offset, 0); if (ret < 0) { goto fail; } @@ -2083,12 +2078,11 @@ static coroutine_fn int qcow2_co_preadv(BlockDriver= State *bs, uint64_t offset, =20 bytes -=3D cur_bytes; offset +=3D cur_bytes; - bytes_done +=3D cur_bytes; + qiov_offset +=3D cur_bytes; } ret =3D 0; =20 fail: - qemu_iovec_destroy(&hd_qiov); qemu_vfree(cluster_data); =20 return ret; @@ -4087,7 +4081,8 @@ qcow2_co_preadv_compressed(BlockDriverState *bs, uint64_t file_cluster_offset, uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov) + QEMUIOVector *qiov, + size_t qiov_offset) { BDRVQcow2State *s =3D bs->opaque; int ret =3D 0, csize, nb_csectors; @@ -4118,7 +4113,7 @@ qcow2_co_preadv_compressed(BlockDriverState *bs, goto fail; } =20 - qemu_iovec_from_buf(qiov, 0, out_buf + offset_in_cluster, bytes); + qemu_iovec_from_buf(qiov, qiov_offset, out_buf + offset_in_cluster, by= tes); =20 fail: qemu_vfree(out_buf); @@ -4638,8 +4633,8 @@ static int qcow2_load_vmstate(BlockDriverState *bs, Q= EMUIOVector *qiov, BDRVQcow2State *s =3D bs->opaque; =20 BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD); - return bs->drv->bdrv_co_preadv(bs, qcow2_vm_state_offset(s) + pos, - qiov->size, qiov, 0); + return bs->drv->bdrv_co_preadv_part(bs, qcow2_vm_state_offset(s) + pos, + qiov->size, qiov, 0, 0); } =20 /* @@ -5179,7 +5174,7 @@ BlockDriver bdrv_qcow2 =3D { .bdrv_has_zero_init =3D bdrv_has_zero_init_1, .bdrv_co_block_status =3D qcow2_co_block_status, =20 - .bdrv_co_preadv =3D qcow2_co_preadv, + .bdrv_co_preadv_part =3D qcow2_co_preadv_part, .bdrv_co_pwritev =3D qcow2_co_pwritev, .bdrv_co_flush_to_os =3D qcow2_co_flush_to_os, =20 --=20 2.18.0 From nobody Sun May 5 18:23:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1559665098; cv=none; d=zoho.com; s=zohoarc; b=JixDVf5L2KDrAWC/IgNCy17akq76OORfSz+J2JW3Dp8l5Zd4xbKAihd56L6PtzF2OGMN2fIY2RZAp3VDNEVNhSxf6Mwdu1dhCRlljPvKpeqAJMnHjGqFkeQbNBA6VbCBqQ+oMxBD2MHF/El4iTD+LLL8Z//8f5ZW+nSRw7jDIqk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1559665098; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ACnRxG5eIlPkNH4ctyT8ZAJlcc20kMqnKcpH3CzPztE=; b=RZEm0rJsWrAv2r9hzbNpedZhVScY4Y6GTChpuEFehzUw6bfpTZl71VK1fd5Rf860gT/kj6/54VX+9nn3BVEv5e5sDNxFfDWMZh66OiGQ7rKSYifww9kGEm6t4fisIEGH/nTLvc5wVn1G1LKTNEnxeCr2iHl5wk4adeCbME/WA5g= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1559665098734870.876267876517; Tue, 4 Jun 2019 09:18:18 -0700 (PDT) Received: from localhost ([127.0.0.1]:54850 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC8Z-0002Op-JR for importer@patchew.org; Tue, 04 Jun 2019 12:18:11 -0400 Received: from eggs.gnu.org ([209.51.188.92]:35701) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hYC66-0000zS-Tj for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hYC61-0005S2-Ff for qemu-devel@nongnu.org; Tue, 04 Jun 2019 12:15:37 -0400 Received: from relay.sw.ru ([185.231.240.75]:41678) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hYC5x-0005C5-Cj; Tue, 04 Jun 2019 12:15:30 -0400 Received: from [10.94.3.0] (helo=kvm.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1hYC5k-0005Pq-Vi; Tue, 04 Jun 2019 19:15:17 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Tue, 4 Jun 2019 19:15:14 +0300 Message-Id: <20190604161514.262241-13-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190604161514.262241-1-vsementsov@virtuozzo.com> References: <20190604161514.262241-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH v2 12/12] block/qcow2: implement .bdrv_co_pwritev(_compressed)_part 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: fam@euphon.net, kwolf@redhat.com, vsementsov@virtuozzo.com, mreitz@redhat.com, stefanha@redhat.com, den@openvz.org, jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implement and use new interface to get rid of hd_qiov. Signed-off-by: Vladimir Sementsov-Ogievskiy Acked-by: Stefan Hajnoczi --- block/qcow2.h | 1 + include/qemu/iov.h | 1 + block/qcow2-cluster.c | 9 ++++--- block/qcow2.c | 60 +++++++++++++++++++++---------------------- util/iov.c | 10 ++++++++ 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 567375e56c..ea3bdb0699 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -417,6 +417,7 @@ typedef struct QCowL2Meta * from @cow_start and @cow_end into one single write operation. */ QEMUIOVector *data_qiov; + size_t data_qiov_offset; =20 /** Pointer to next L2Meta of the same write request */ struct QCowL2Meta *next; diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 29957c8a72..bffc151282 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -206,6 +206,7 @@ void qemu_iovec_init_extended( void *tail_buf, size_t tail_len); void qemu_iovec_init_slice(QEMUIOVector *qiov, QEMUIOVector *source, size_t offset, size_t len); +int qemu_iovec_subvec_niov(QEMUIOVector *qiov, size_t offset, size_t len); void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t soffset, size_t sbytes); diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 1159d6ed2f..00b1a9ab8d 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -830,7 +830,6 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta= *m) assert(start->nb_bytes <=3D UINT_MAX - end->nb_bytes); assert(start->nb_bytes + end->nb_bytes <=3D UINT_MAX - data_bytes); assert(start->offset + start->nb_bytes <=3D end->offset); - assert(!m->data_qiov || m->data_qiov->size =3D=3D data_bytes); =20 if ((start->nb_bytes =3D=3D 0 && end->nb_bytes =3D=3D 0) || m->skip_co= w) { return 0; @@ -862,7 +861,11 @@ static int perform_cow(BlockDriverState *bs, QCowL2Met= a *m) /* The part of the buffer where the end region is located */ end_buffer =3D start_buffer + buffer_size - end->nb_bytes; =20 - qemu_iovec_init(&qiov, 2 + (m->data_qiov ? m->data_qiov->niov : 0)); + qemu_iovec_init(&qiov, 2 + (m->data_qiov ? + qemu_iovec_subvec_niov(m->data_qiov, + m->data_qiov_offset, + data_bytes) + : 0)); =20 qemu_co_mutex_unlock(&s->lock); /* First we read the existing data from both COW regions. We @@ -905,7 +908,7 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta= *m) if (start->nb_bytes) { qemu_iovec_add(&qiov, start_buffer, start->nb_bytes); } - qemu_iovec_concat(&qiov, m->data_qiov, 0, data_bytes); + qemu_iovec_concat(&qiov, m->data_qiov, m->data_qiov_offset, data_b= ytes); if (end->nb_bytes) { qemu_iovec_add(&qiov, end_buffer, end->nb_bytes); } diff --git a/block/qcow2.c b/block/qcow2.c index c389ef07b0..850117cfa2 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2091,7 +2091,8 @@ fail: /* Check if it's possible to merge a write request with the writing of * the data from the COW regions */ static bool merge_cow(uint64_t offset, unsigned bytes, - QEMUIOVector *hd_qiov, QCowL2Meta *l2meta) + QEMUIOVector *qiov, size_t qiov_offset, + QCowL2Meta *l2meta) { QCowL2Meta *m; =20 @@ -2120,11 +2121,12 @@ static bool merge_cow(uint64_t offset, unsigned byt= es, =20 /* Make sure that adding both COW regions to the QEMUIOVector * does not exceed IOV_MAX */ - if (hd_qiov->niov > IOV_MAX - 2) { + if (qemu_iovec_subvec_niov(qiov, qiov_offset, bytes) > IOV_MAX - 2= ) { continue; } =20 - m->data_qiov =3D hd_qiov; + m->data_qiov =3D qiov; + m->data_qiov_offset =3D qiov_offset; return true; } =20 @@ -2205,24 +2207,22 @@ static int handle_alloc_space(BlockDriverState *bs,= QCowL2Meta *l2meta) return 0; } =20 -static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t of= fset, - uint64_t bytes, QEMUIOVector *qio= v, - int flags) +static coroutine_fn int qcow2_co_pwritev_part( + BlockDriverState *bs, uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, size_t qiov_offset, int flags) { BDRVQcow2State *s =3D bs->opaque; int offset_in_cluster; int ret; unsigned int cur_bytes; /* number of sectors in current iteration */ uint64_t cluster_offset; - QEMUIOVector hd_qiov; + QEMUIOVector encrypted_qiov; uint64_t bytes_done =3D 0; uint8_t *cluster_data =3D NULL; QCowL2Meta *l2meta =3D NULL; =20 trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes); =20 - qemu_iovec_init(&hd_qiov, qiov->niov); - qemu_co_mutex_lock(&s->lock); =20 while (bytes !=3D 0) { @@ -2255,9 +2255,6 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverS= tate *bs, uint64_t offset, =20 qemu_co_mutex_unlock(&s->lock); =20 - qemu_iovec_reset(&hd_qiov); - qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes); - if (bs->encrypted) { assert(s->crypto); if (!cluster_data) { @@ -2270,9 +2267,9 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverS= tate *bs, uint64_t offset, } } =20 - assert(hd_qiov.size <=3D - QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); - qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); + assert(cur_bytes <=3D QCOW_MAX_CRYPT_CLUSTERS * s->cluster_siz= e); + qemu_iovec_to_buf(qiov, qiov_offset + bytes_done, + cluster_data, cur_bytes); =20 if (qcow2_co_encrypt(bs, cluster_offset, offset, cluster_data, cur_bytes) < 0) { @@ -2280,8 +2277,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverS= tate *bs, uint64_t offset, goto out_unlocked; } =20 - qemu_iovec_reset(&hd_qiov); - qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes); + qemu_iovec_init_buf(&encrypted_qiov, cluster_data, cur_bytes); } =20 /* Try to efficiently initialize the physical space with zeroes */ @@ -2294,13 +2290,17 @@ static coroutine_fn int qcow2_co_pwritev(BlockDrive= rState *bs, uint64_t offset, * writing of the guest data together with that of the COW regions. * If it's not possible (or not necessary) then write the * guest data now. */ - if (!merge_cow(offset, cur_bytes, &hd_qiov, l2meta)) { + if (!merge_cow(offset, cur_bytes, + bs->encrypted ? &encrypted_qiov : qiov, + bs->encrypted ? 0 : qiov_offset + bytes_done, l2met= a)) + { BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); trace_qcow2_writev_data(qemu_coroutine_self(), cluster_offset + offset_in_cluster); - ret =3D bdrv_co_pwritev(s->data_file, - cluster_offset + offset_in_cluster, - cur_bytes, &hd_qiov, 0); + ret =3D bdrv_co_pwritev_part( + s->data_file, cluster_offset + offset_in_cluster, cur_= bytes, + bs->encrypted ? &encrypted_qiov : qiov, + bs->encrypted ? 0 : qiov_offset + bytes_done, 0); if (ret < 0) { goto out_unlocked; } @@ -2329,7 +2329,6 @@ out_locked: =20 qemu_co_mutex_unlock(&s->lock); =20 - qemu_iovec_destroy(&hd_qiov); qemu_vfree(cluster_data); trace_qcow2_writev_done_req(qemu_coroutine_self(), ret); =20 @@ -3993,8 +3992,9 @@ fail: /* XXX: put compressed sectors first, then all the cluster aligned tables to avoid losing bytes in alignment */ static coroutine_fn int -qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset, - uint64_t bytes, QEMUIOVector *qiov) +qcow2_co_pwritev_compressed_part(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, size_t qiov_offset) { BDRVQcow2State *s =3D bs->opaque; int ret; @@ -4031,7 +4031,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uin= t64_t offset, /* Zero-pad last write if image size is not cluster aligned */ memset(buf + bytes, 0, s->cluster_size - bytes); } - qemu_iovec_to_buf(qiov, 0, buf, bytes); + qemu_iovec_to_buf(qiov, qiov_offset, buf, bytes); =20 out_buf =3D g_malloc(s->cluster_size); =20 @@ -4039,7 +4039,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uin= t64_t offset, buf, s->cluster_size); if (out_len =3D=3D -ENOMEM) { /* could not compress: write normal cluster */ - ret =3D qcow2_co_pwritev(bs, offset, bytes, qiov, 0); + ret =3D qcow2_co_pwritev_part(bs, offset, bytes, qiov, qiov_offset= , 0); if (ret < 0) { goto fail; } @@ -4623,8 +4623,8 @@ static int qcow2_save_vmstate(BlockDriverState *bs, Q= EMUIOVector *qiov, BDRVQcow2State *s =3D bs->opaque; =20 BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE); - return bs->drv->bdrv_co_pwritev(bs, qcow2_vm_state_offset(s) + pos, - qiov->size, qiov, 0); + return bs->drv->bdrv_co_pwritev_part(bs, qcow2_vm_state_offset(s) + po= s, + qiov->size, qiov, 0, 0); } =20 static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, @@ -5175,7 +5175,7 @@ BlockDriver bdrv_qcow2 =3D { .bdrv_co_block_status =3D qcow2_co_block_status, =20 .bdrv_co_preadv_part =3D qcow2_co_preadv_part, - .bdrv_co_pwritev =3D qcow2_co_pwritev, + .bdrv_co_pwritev_part =3D qcow2_co_pwritev_part, .bdrv_co_flush_to_os =3D qcow2_co_flush_to_os, =20 .bdrv_co_pwrite_zeroes =3D qcow2_co_pwrite_zeroes, @@ -5183,7 +5183,7 @@ BlockDriver bdrv_qcow2 =3D { .bdrv_co_copy_range_from =3D qcow2_co_copy_range_from, .bdrv_co_copy_range_to =3D qcow2_co_copy_range_to, .bdrv_co_truncate =3D qcow2_co_truncate, - .bdrv_co_pwritev_compressed =3D qcow2_co_pwritev_compressed, + .bdrv_co_pwritev_compressed_part =3D qcow2_co_pwritev_compressed_part, .bdrv_make_empty =3D qcow2_make_empty, =20 .bdrv_snapshot_create =3D qcow2_snapshot_create, diff --git a/util/iov.c b/util/iov.c index d988a533ce..0ed75e764c 100644 --- a/util/iov.c +++ b/util/iov.c @@ -401,6 +401,16 @@ static struct iovec *qiov_slice(QEMUIOVector *qiov, return iov; } =20 +int qemu_iovec_subvec_niov(QEMUIOVector *qiov, size_t offset, size_t len) +{ + size_t head, tail; + int niov; + + qiov_slice(qiov, offset, len, &head, &tail, &niov); + + return niov; +} + /* * Compile new iovec, combining @head_buf buffer, sub-qiov of @mid_qiov, * and @tail_buf buffer into new qiov. --=20 2.18.0