From nobody Mon Feb 9 10:53:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.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=1597786063; cv=none; d=zohomail.com; s=zohoarc; b=dvqMQiLRK3s4D+bKMKAiJLzLL450CY6NfkftLJymrf1npbP2NFbWpkmq0mdL4VN4+fNMKYCiPb+dVcYNgfTAb6lQhrAzKPOJ4pZ25dVPZbrOALU/oJRY5AcknHtcEcDGoFsZkK0pZisgwVj3p1hsR2RIqAZGguu88jdpQ0HhHaE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597786063; 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; bh=2zMOkdBoPyaTLN579fWp3hmWHLu70gEfDipo04mwjaQ=; b=YkxY1iope/MwP88HbjYqc1nGKbyNhZuZ2xpgjv1qsSb8mZZ6NbIoSrXs4Yc6+E+umcY6CUL8GY8LiiSQIlNbgpCMiMhEWhSu1ph0369UHJfdw+l02ezD6PMQVzUX4CyrSFWOU7IRD/XRNue9/agcDg7RJDMdMguyf9i5ZaH/xzI= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.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 1597786063133341.8517750785128; Tue, 18 Aug 2020 14:27:43 -0700 (PDT) Received: from localhost ([::1]:57820 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k898v-0001Ct-UD for importer@patchew.org; Tue, 18 Aug 2020 17:27:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41904) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8968-0005pz-5L; Tue, 18 Aug 2020 17:24:48 -0400 Received: from relay.sw.ru ([185.231.240.75]:41586 helo=relay3.sw.ru) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8965-0003cb-2w; Tue, 18 Aug 2020 17:24:47 -0400 Received: from [172.16.25.136] (helo=localhost.sw.ru) by relay3.sw.ru with esmtp (Exim 4.94) (envelope-from ) id 1k895p-000GtS-Kn; Wed, 19 Aug 2020 00:24:29 +0300 From: Andrey Shinkevich To: qemu-block@nongnu.org Subject: [PATCH v6 1/4] copy-on-read: Support preadv/pwritev_part functions Date: Wed, 19 Aug 2020 00:24:37 +0300 Message-Id: <1597785880-431103-2-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=185.231.240.75; envelope-from=andrey.shinkevich@virtuozzo.com; helo=relay3.sw.ru X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/18 17:24:42 X-ACL-Warn: Detected OS = Linux 3.11 and newer X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, qemu-devel@nongnu.org, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com, 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 support for the recently introduced functions bdrv_co_preadv_part() and bdrv_co_pwritev_part() to the COR-filter driver. Signed-off-by: Andrey Shinkevich Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/copy-on-read.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 2816e61..cb03e0f 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -74,21 +74,25 @@ static int64_t cor_getlength(BlockDriverState *bs) } =20 =20 -static int coroutine_fn cor_co_preadv(BlockDriverState *bs, - uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov, int flags) +static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, + size_t qiov_offset, + int flags) { - return bdrv_co_preadv(bs->file, offset, bytes, qiov, - flags | BDRV_REQ_COPY_ON_READ); + return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, + flags | BDRV_REQ_COPY_ON_READ); } =20 =20 -static int coroutine_fn cor_co_pwritev(BlockDriverState *bs, - uint64_t offset, uint64_t bytes, - QEMUIOVector *qiov, int flags) +static int coroutine_fn cor_co_pwritev_part(BlockDriverState *bs, + uint64_t offset, + uint64_t bytes, + QEMUIOVector *qiov, + size_t qiov_offset, int flags) { - - return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); + return bdrv_co_pwritev_part(bs->file, offset, bytes, qiov, qiov_offset, + flags); } =20 =20 @@ -137,8 +141,8 @@ static BlockDriver bdrv_copy_on_read =3D { =20 .bdrv_getlength =3D cor_getlength, =20 - .bdrv_co_preadv =3D cor_co_preadv, - .bdrv_co_pwritev =3D cor_co_pwritev, + .bdrv_co_preadv_part =3D cor_co_preadv_part, + .bdrv_co_pwritev_part =3D cor_co_pwritev_part, .bdrv_co_pwrite_zeroes =3D cor_co_pwrite_zeroes, .bdrv_co_pdiscard =3D cor_co_pdiscard, .bdrv_co_pwritev_compressed =3D cor_co_pwritev_compressed, --=20 1.8.3.1 From nobody Mon Feb 9 10:53:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.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=1597785956; cv=none; d=zohomail.com; s=zohoarc; b=laItVjjQDuI2X0x9qcoqlThCIIvq3MMQsyZ9d88m/AYMAltnoVs9UyABxO2mlLKZgcHAQ+wyLuoRFZdpadd+2RcM23PMprUhwhR6D542YqscYhvJpiJqcpAaqaRTmmQwZkyQy45hDGMa4UYmpVPlFJihy4rRFv2nKP2BgPm6eUE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597785956; 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; bh=oxwbtNWKeOmS11XeT9zpOpQZ6+0vJ6kw1ggMyYQrNms=; b=fgsAqCkH3GO/eIuESg7LYqSgmZmBAksOa7Wjzo/7kPWLANFVjeFauGruCvTGBxpyrim4UdaOM37/QSNGvUCwGPVyRCgNxx2W8Vs+VMAya4tdKFrz1y0L5zxxjITuN3+ijsQkOrGz+xkShmuEWAzAmC5t4Wq9MgsBCano7AKvREU= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.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 1597785956715320.21457668227947; Tue, 18 Aug 2020 14:25:56 -0700 (PDT) Received: from localhost ([::1]:52110 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k897D-0007KH-0B for importer@patchew.org; Tue, 18 Aug 2020 17:25:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41906) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8968-0005qL-5v; Tue, 18 Aug 2020 17:24:48 -0400 Received: from relay.sw.ru ([185.231.240.75]:41578 helo=relay3.sw.ru) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8965-0003cX-2d; Tue, 18 Aug 2020 17:24:47 -0400 Received: from [172.16.25.136] (helo=localhost.sw.ru) by relay3.sw.ru with esmtp (Exim 4.94) (envelope-from ) id 1k895p-000GtS-MG; Wed, 19 Aug 2020 00:24:29 +0300 From: Andrey Shinkevich To: qemu-block@nongnu.org Subject: [PATCH v6 2/4] copy-on-read: add filter append/drop functions Date: Wed, 19 Aug 2020 00:24:38 +0300 Message-Id: <1597785880-431103-3-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=185.231.240.75; envelope-from=andrey.shinkevich@virtuozzo.com; helo=relay3.sw.ru X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/18 17:24:42 X-ACL-Warn: Detected OS = Linux 3.11 and newer X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, qemu-devel@nongnu.org, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com, 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" Provide API for the COR-filter insertion/removal. Also, drop the filter child permissions for an inactive state when the filter node is being removed. Signed-off-by: Andrey Shinkevich Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/copy-on-read.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ block/copy-on-read.h | 36 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 block/copy-on-read.h diff --git a/block/copy-on-read.c b/block/copy-on-read.c index cb03e0f..150d9b7 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -23,11 +23,21 @@ #include "qemu/osdep.h" #include "block/block_int.h" #include "qemu/module.h" +#include "qapi/error.h" +#include "qapi/qmp/qdict.h" +#include "block/copy-on-read.h" + + +typedef struct BDRVStateCOR { + bool active; +} BDRVStateCOR; =20 =20 static int cor_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { + BDRVStateCOR *state =3D bs->opaque; + bs->file =3D bdrv_open_child(NULL, options, "file", bs, &child_of_bds, BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false, errp); @@ -42,6 +52,8 @@ static int cor_open(BlockDriverState *bs, QDict *options,= int flags, ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) & bs->file->bs->supported_zero_flags); =20 + state->active =3D true; + return 0; } =20 @@ -57,6 +69,17 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChi= ld *c, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { + BDRVStateCOR *s =3D bs->opaque; + + if (!s->active) { + /* + * While the filter is being removed + */ + *nperm =3D 0; + *nshared =3D BLK_PERM_ALL; + return; + } + *nperm =3D perm & PERM_PASSTHROUGH; *nshared =3D (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED; =20 @@ -135,6 +158,7 @@ static void cor_lock_medium(BlockDriverState *bs, bool = locked) =20 static BlockDriver bdrv_copy_on_read =3D { .format_name =3D "copy-on-read", + .instance_size =3D sizeof(BDRVStateCOR), =20 .bdrv_open =3D cor_open, .bdrv_child_perm =3D cor_child_perm, @@ -159,4 +183,83 @@ static void bdrv_copy_on_read_init(void) bdrv_register(&bdrv_copy_on_read); } =20 + +static BlockDriverState *create_filter_node(BlockDriverState *bs, + const char *filter_node_name, + Error **errp) +{ + QDict *opts =3D qdict_new(); + + qdict_put_str(opts, "driver", "copy-on-read"); + qdict_put_str(opts, "file", bdrv_get_node_name(bs)); + if (filter_node_name) { + qdict_put_str(opts, "node-name", filter_node_name); + } + + return bdrv_open(NULL, NULL, opts, BDRV_O_RDWR, errp); +} + + +BlockDriverState *bdrv_cor_filter_append(BlockDriverState *bs, + const char *filter_node_name, + Error **errp) +{ + BlockDriverState *cor_filter_bs; + BDRVStateCOR *state; + Error *local_err =3D NULL; + + cor_filter_bs =3D create_filter_node(bs, filter_node_name, errp); + if (cor_filter_bs =3D=3D NULL) { + error_prepend(errp, "Could not create filter node: "); + return NULL; + } + + if (!filter_node_name) { + cor_filter_bs->implicit =3D true; + } + + bdrv_drained_begin(bs); + bdrv_replace_node(bs, cor_filter_bs, &local_err); + bdrv_drained_end(bs); + + if (local_err) { + bdrv_unref(cor_filter_bs); + error_propagate(errp, local_err); + return NULL; + } + + state =3D cor_filter_bs->opaque; + state->active =3D true; + + return cor_filter_bs; +} + + +void bdrv_cor_filter_drop(BlockDriverState *cor_filter_bs) +{ + BdrvChild *child; + BlockDriverState *bs; + BDRVStateCOR *s =3D cor_filter_bs->opaque; + + child =3D bdrv_filter_child(cor_filter_bs); + if (!child) { + return; + } + bs =3D child->bs; + + /* Retain the BDS until we complete the graph change. */ + bdrv_ref(bs); + /* Hold a guest back from writing while permissions are being reset. */ + bdrv_drained_begin(bs); + /* Drop permissions before the graph change. */ + s->active =3D false; + bdrv_child_refresh_perms(cor_filter_bs, child, &error_abort); + bdrv_replace_node(cor_filter_bs, bs, &error_abort); + + bdrv_drained_end(bs); + bdrv_unref(bs); + bdrv_unref(cor_filter_bs); +} + + block_init(bdrv_copy_on_read_init); diff --git a/block/copy-on-read.h b/block/copy-on-read.h new file mode 100644 index 0000000..db03c6c --- /dev/null +++ b/block/copy-on-read.h @@ -0,0 +1,36 @@ +/* + * Copy-on-read filter block driver + * + * The filter driver performs Copy-On-Read (COR) operations + * + * Copyright (c) 2018-2020 Virtuozzo International GmbH. + * + * Author: + * Andrey Shinkevich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef COPY_ON_READ_FILTER +#define COPY_ON_READ_FILTER + +#include "block/block_int.h" +#include "block/block-copy.h" + +BlockDriverState *bdrv_cor_filter_append(BlockDriverState *bs, + const char *filter_node_name, + Error **errp); +void bdrv_cor_filter_drop(BlockDriverState *cor_filter_bs); + +#endif /* COPY_ON_READ_FILTER */ --=20 1.8.3.1 From nobody Mon Feb 9 10:53:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.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=1597786056; cv=none; d=zohomail.com; s=zohoarc; b=AZUUBWTVkAxke0LKEQXtOqOxcJt8qlaqStelYWCu0AEsjJq1e50AmTCs7U+uKqJ33dYf0RspPg8zZJ0DR3Ynok3NutICtXfwECmDkYhOmAQh4MY0MNgpN6tMw6YX2G0fbsiKcpFLRqbIcA2CbpJvmU5rK1XHPwvzBZYk+GLXRhE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597786056; 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; bh=EX43wc3xr8u7NM+tQ6aLs+k7SjWRqz+3hHffV0opa8E=; b=LTx4V991WxiFrZjW31Twxcx61Isv0JyZ3susL2B19IzXffEsfEGUihZqHw2f1qNwOEfDwWYvIJBBrvj4wjW0XkuAbx+NNdHaIhxEaKlgjU9eZ7TQiZzN/DoprDOk3ONdEA3YQi8JdoDqeyEA+TPWW3zHkW7OhozHmPpOq32t3eI= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.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 1597786056817339.4190538164372; Tue, 18 Aug 2020 14:27:36 -0700 (PDT) Received: from localhost ([::1]:57436 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k898p-00013U-E2 for importer@patchew.org; Tue, 18 Aug 2020 17:27:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41928) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8969-0005rX-F1; Tue, 18 Aug 2020 17:24:49 -0400 Received: from relay.sw.ru ([185.231.240.75]:41579 helo=relay3.sw.ru) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8965-0003cY-2i; Tue, 18 Aug 2020 17:24:49 -0400 Received: from [172.16.25.136] (helo=localhost.sw.ru) by relay3.sw.ru with esmtp (Exim 4.94) (envelope-from ) id 1k895p-000GtS-Nj; Wed, 19 Aug 2020 00:24:29 +0300 From: Andrey Shinkevich To: qemu-block@nongnu.org Subject: [PATCH v6 3/4] qapi: add filter-node-name to block-stream Date: Wed, 19 Aug 2020 00:24:39 +0300 Message-Id: <1597785880-431103-4-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=185.231.240.75; envelope-from=andrey.shinkevich@virtuozzo.com; helo=relay3.sw.ru X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/18 17:24:42 X-ACL-Warn: Detected OS = Linux 3.11 and newer X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, qemu-devel@nongnu.org, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com, 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" Provide the possibility to pass the 'filter-node-name' parameter to the block-stream job as it is done for the commit block job. That will be needed for further iotests implementations. Signed-off-by: Andrey Shinkevich Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/monitor/block-hmp-cmds.c | 4 ++-- block/stream.c | 4 +++- blockdev.c | 8 +++++++- include/block/block_int.h | 7 ++++++- qapi/block-core.json | 6 ++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 4d3db5e..4e66775 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -507,8 +507,8 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict) =20 qmp_block_stream(true, device, device, base !=3D NULL, base, false, NU= LL, false, NULL, qdict_haskey(qdict, "speed"), speed, tru= e, - BLOCKDEV_ON_ERROR_REPORT, false, false, false, false, - &error); + BLOCKDEV_ON_ERROR_REPORT, false, NULL, false, false, = false, + false, &error); =20 hmp_handle_error(mon, error); } diff --git a/block/stream.c b/block/stream.c index b9c1141..8bf6b6d 100644 --- a/block/stream.c +++ b/block/stream.c @@ -221,7 +221,9 @@ static const BlockJobDriver stream_job_driver =3D { void stream_start(const char *job_id, BlockDriverState *bs, BlockDriverState *base, const char *backing_file_str, int creation_flags, int64_t speed, - BlockdevOnError on_error, Error **errp) + BlockdevOnError on_error, + const char *filter_node_name, + Error **errp) { StreamBlockJob *s; BlockDriverState *iter; diff --git a/blockdev.c b/blockdev.c index 237fffb..800ecb3 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2476,6 +2476,7 @@ void qmp_block_stream(bool has_job_id, const char *jo= b_id, const char *device, bool has_backing_file, const char *backing_file, bool has_speed, int64_t speed, bool has_on_error, BlockdevOnError on_error, + bool has_filter_node_name, const char *filter_node_n= ame, bool has_auto_finalize, bool auto_finalize, bool has_auto_dismiss, bool auto_dismiss, Error **errp) @@ -2491,6 +2492,10 @@ void qmp_block_stream(bool has_job_id, const char *j= ob_id, const char *device, on_error =3D BLOCKDEV_ON_ERROR_REPORT; } =20 + if (!has_filter_node_name) { + filter_node_name =3D NULL; + } + bs =3D bdrv_lookup_bs(device, device, errp); if (!bs) { return; @@ -2558,7 +2563,8 @@ void qmp_block_stream(bool has_job_id, const char *jo= b_id, const char *device, } =20 stream_start(has_job_id ? job_id : NULL, bs, base_bs, base_name, - job_flags, has_speed ? speed : 0, on_error, &local_err); + job_flags, has_speed ? speed : 0, on_error, + filter_node_name, &local_err); if (local_err) { error_propagate(errp, local_err); goto out; diff --git a/include/block/block_int.h b/include/block/block_int.h index 465a601..3efde33 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -1122,6 +1122,9 @@ int is_windows_drive(const char *filename); * See @BlockJobCreateFlags * @speed: The maximum speed, in bytes per second, or 0 for unlimited. * @on_error: The action to take upon error. + * @filter_node_name: The node name that should be assigned to the filter + * driver that the commit job inserts into the graph above @bs. NULL means + * that a node name should be autogenerated. * @errp: Error object. * * Start a streaming operation on @bs. Clusters that are unallocated @@ -1134,7 +1137,9 @@ int is_windows_drive(const char *filename); void stream_start(const char *job_id, BlockDriverState *bs, BlockDriverState *base, const char *backing_file_str, int creation_flags, int64_t speed, - BlockdevOnError on_error, Error **errp); + BlockdevOnError on_error, + const char *filter_node_name, + Error **errp); =20 /** * commit_start: diff --git a/qapi/block-core.json b/qapi/block-core.json index 0b8ccd3..1db6ce1 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2524,6 +2524,11 @@ # 'stop' and 'enospc' can only be used if the block device # supports io-status (see BlockInfo). Since 1.3. # +# @filter-node-name: the node name that should be assigned to the +# filter driver that the stream job inserts into the gr= aph +# above @device. If this option is not given, a node na= me is +# autogenerated. (Since: 5.1) +# # @auto-finalize: When false, this job will wait in a PENDING state after = it has # finished its work, waiting for @block-job-finalize before # making any block graph changes. @@ -2554,6 +2559,7 @@ 'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*base-node': 'str', '*backing-file': 'str', '*speed': 'int', '*on-error': 'BlockdevOnError', + '*filter-node-name': 'str', '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } =20 ## --=20 1.8.3.1 From nobody Mon Feb 9 10:53:16 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.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=1597785957; cv=none; d=zohomail.com; s=zohoarc; b=icw8TFthf1GgY18I6brQ+eQBtFsioalkWOM2elcPfE8mWfV+TIV5M4wE91l/ds5BQ8nFq2gWo0aWjGHTBI389kAoBx3fK1rTBFG6QPCcN7uOYWtj0GHVcYAGgnDiPtnNtLGldurlnhYxU8w+ggq93nRaC3OqoOn5DVs6ZLoEI9Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597785957; 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; bh=0dFYKCLexLqjBZn8Ciquj/F0DVkaIyBLCZT7GjHzTdU=; b=O55wDoQZFXlJOJjjX05esxUtPPitMFT3XyQ7mUxFL3068efztqzBLtL2izaVLigH427iChFXVonJpUjEluFExlqdr7HBJ0hNeFmoY6jdqgNG7e+1dHQLFiqEFZYpn93kgomJ29G0vvC08AjZx5rTnC5BA5PURLdNFIO/x92kz0w= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.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 1597785957103429.0459908393202; Tue, 18 Aug 2020 14:25:57 -0700 (PDT) Received: from localhost ([::1]:52144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k897D-0007Kz-Mg for importer@patchew.org; Tue, 18 Aug 2020 17:25:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41910) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8968-0005r8-G9; Tue, 18 Aug 2020 17:24:48 -0400 Received: from relay.sw.ru ([185.231.240.75]:41584 helo=relay3.sw.ru) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8965-0003ca-2i; Tue, 18 Aug 2020 17:24:48 -0400 Received: from [172.16.25.136] (helo=localhost.sw.ru) by relay3.sw.ru with esmtp (Exim 4.94) (envelope-from ) id 1k895p-000GtS-PL; Wed, 19 Aug 2020 00:24:29 +0300 From: Andrey Shinkevich To: qemu-block@nongnu.org Subject: [PATCH v6 4/4] block: apply COR-filter to block-stream jobs Date: Wed, 19 Aug 2020 00:24:40 +0300 Message-Id: <1597785880-431103-5-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1597785880-431103-1-git-send-email-andrey.shinkevich@virtuozzo.com> Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=185.231.240.75; envelope-from=andrey.shinkevich@virtuozzo.com; helo=relay3.sw.ru X-detected-operating-system: by eggs.gnu.org: First seen = 2020/08/18 17:24:42 X-ACL-Warn: Detected OS = Linux 3.11 and newer X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, armbru@redhat.com, qemu-devel@nongnu.org, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com, 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" The patch completes the series with the COR-filter insertion to any block-stream operation. It also makes changes to the iotests 030. The test case 'test_stream_parallel' was deleted due to multiple errors. Signed-off-by: Andrey Shinkevich --- block/stream.c | 76 ++++++++++++++++++++++++++++++++----------= ---- tests/qemu-iotests/030 | 50 +++--------------------------- tests/qemu-iotests/030.out | 4 +-- 3 files changed, 61 insertions(+), 69 deletions(-) diff --git a/block/stream.c b/block/stream.c index 8bf6b6d..0b11979 100644 --- a/block/stream.c +++ b/block/stream.c @@ -19,6 +19,7 @@ #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" #include "sysemu/block-backend.h" +#include "block/copy-on-read.h" =20 enum { /* @@ -33,8 +34,11 @@ typedef struct StreamBlockJob { BlockJob common; BlockDriverState *base_overlay; /* COW overlay (stream from this) */ BlockDriverState *above_base; /* Node directly above the base */ + BlockDriverState *cor_filter_bs; + BlockDriverState *target_bs; BlockdevOnError on_error; char *backing_file_str; + char *base_fmt; bool bs_read_only; bool chain_frozen; } StreamBlockJob; @@ -53,34 +57,26 @@ static void stream_abort(Job *job) StreamBlockJob *s =3D container_of(job, StreamBlockJob, common.job); =20 if (s->chain_frozen) { - BlockJob *bjob =3D &s->common; - bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->above_base); + bdrv_unfreeze_backing_chain(s->cor_filter_bs, s->above_base); } } =20 static int stream_prepare(Job *job) { StreamBlockJob *s =3D container_of(job, StreamBlockJob, common.job); - BlockJob *bjob =3D &s->common; - BlockDriverState *bs =3D blk_bs(bjob->blk); + BlockDriverState *bs =3D s->target_bs; BlockDriverState *unfiltered_bs =3D bdrv_skip_filters(bs); BlockDriverState *base =3D bdrv_filter_or_cow_bs(s->above_base); Error *local_err =3D NULL; int ret =3D 0; =20 - bdrv_unfreeze_backing_chain(bs, s->above_base); + bdrv_unfreeze_backing_chain(s->cor_filter_bs, s->above_base); s->chain_frozen =3D false; =20 if (bdrv_cow_child(unfiltered_bs)) { - const char *base_id =3D NULL, *base_fmt =3D NULL; - if (base) { - base_id =3D s->backing_file_str; - if (base->drv) { - base_fmt =3D base->drv->format_name; - } - } bdrv_set_backing_hd(unfiltered_bs, base, &local_err); - ret =3D bdrv_change_backing_file(unfiltered_bs, base_id, base_fmt); + ret =3D bdrv_change_backing_file(unfiltered_bs, s->backing_file_st= r, + s->base_fmt); if (local_err) { error_report_err(local_err); return -EPERM; @@ -94,7 +90,9 @@ static void stream_clean(Job *job) { StreamBlockJob *s =3D container_of(job, StreamBlockJob, common.job); BlockJob *bjob =3D &s->common; - BlockDriverState *bs =3D blk_bs(bjob->blk); + BlockDriverState *bs =3D s->target_bs; + + bdrv_cor_filter_drop(s->cor_filter_bs); =20 /* Reopen the image back in read-only mode if necessary */ if (s->bs_read_only) { @@ -104,13 +102,14 @@ static void stream_clean(Job *job) } =20 g_free(s->backing_file_str); + g_free(s->base_fmt); } =20 static int coroutine_fn stream_run(Job *job, Error **errp) { StreamBlockJob *s =3D container_of(job, StreamBlockJob, common.job); BlockBackend *blk =3D s->common.blk; - BlockDriverState *bs =3D blk_bs(blk); + BlockDriverState *bs =3D s->target_bs; BlockDriverState *unfiltered_bs =3D bdrv_skip_filters(bs); bool enable_cor =3D !bdrv_cow_child(s->base_overlay); int64_t len; @@ -231,6 +230,12 @@ void stream_start(const char *job_id, BlockDriverState= *bs, int basic_flags =3D BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGE= D; BlockDriverState *base_overlay =3D bdrv_find_overlay(bs, base); BlockDriverState *above_base; + BlockDriverState *cor_filter_bs =3D NULL; + char *base_fmt =3D NULL; + + if (base && base->drv) { + base_fmt =3D g_strdup(base->drv->format_name); + } =20 if (!base_overlay) { error_setg(errp, "'%s' is not in the backing chain of '%s'", @@ -264,17 +269,36 @@ void stream_start(const char *job_id, BlockDriverStat= e *bs, } } =20 - /* Prevent concurrent jobs trying to modify the graph structure here, = we - * already have our own plans. Also don't allow resize as the image si= ze is - * queried only at the job start and then cached. */ - s =3D block_job_create(job_id, &stream_job_driver, NULL, bs, - basic_flags | BLK_PERM_GRAPH_MOD, - basic_flags | BLK_PERM_WRITE, + cor_filter_bs =3D bdrv_cor_filter_append(bs, filter_node_name, errp); + if (cor_filter_bs =3D=3D NULL) { + goto fail; + } + + if (bdrv_freeze_backing_chain(cor_filter_bs, bs, errp) < 0) { + bdrv_cor_filter_drop(cor_filter_bs); + cor_filter_bs =3D NULL; + goto fail; + } + + s =3D block_job_create(job_id, &stream_job_driver, NULL, cor_filter_bs, + BLK_PERM_CONSISTENT_READ, + basic_flags | BLK_PERM_WRITE | BLK_PERM_GRAPH_MOD, speed, creation_flags, NULL, NULL, errp); if (!s) { goto fail; } =20 + /* + * Prevent concurrent jobs trying to modify the graph structure here, = we + * already have our own plans. Also don't allow resize as the image si= ze is + * queried only at the job start and then cached. + */ + if (block_job_add_bdrv(&s->common, "active node", bs, + basic_flags | BLK_PERM_GRAPH_MOD, + basic_flags | BLK_PERM_WRITE, &error_abort)) { + goto fail; + } + /* Block all intermediate nodes between bs and base, because they will * disappear from the chain after this operation. The streaming job re= ads * every block only once, assuming that it doesn't change, so forbid w= rites @@ -294,6 +318,9 @@ void stream_start(const char *job_id, BlockDriverState = *bs, =20 s->base_overlay =3D base_overlay; s->above_base =3D above_base; + s->cor_filter_bs =3D cor_filter_bs; + s->target_bs =3D bs; + s->base_fmt =3D base_fmt; s->backing_file_str =3D g_strdup(backing_file_str); s->bs_read_only =3D bs_read_only; s->chain_frozen =3D true; @@ -307,5 +334,10 @@ fail: if (bs_read_only) { bdrv_reopen_set_read_only(bs, true, NULL); } - bdrv_unfreeze_backing_chain(bs, above_base); + if (cor_filter_bs) { + bdrv_unfreeze_backing_chain(cor_filter_bs, above_base); + bdrv_cor_filter_drop(cor_filter_bs); + } else { + bdrv_unfreeze_backing_chain(bs, above_base); + } } diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index 1cdd7e2..fec9d89 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -221,60 +221,20 @@ class TestParallelOps(iotests.QMPTestCase): for img in self.imgs: os.remove(img) =20 - # Test that it's possible to run several block-stream operations - # in parallel in the same snapshot chain - def test_stream_parallel(self): - self.assert_no_active_block_jobs() - - # Check that the maps don't match before the streaming operations - for i in range(2, self.num_imgs, 2): - self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-rU', '-c',= 'map', self.imgs[i]), - qemu_io('-f', iotests.imgfmt, '-rU', '-c',= 'map', self.imgs[i-1]), - 'image file map matches backing file befor= e streaming') - - # Create all streaming jobs - pending_jobs =3D [] - for i in range(2, self.num_imgs, 2): - node_name =3D 'node%d' % i - job_id =3D 'stream-%s' % node_name - pending_jobs.append(job_id) - result =3D self.vm.qmp('block-stream', device=3Dnode_name, job= _id=3Djob_id, base=3Dself.imgs[i-2], speed=3D512*1024) - self.assert_qmp(result, 'return', {}) - - for job in pending_jobs: - result =3D self.vm.qmp('block-job-set-speed', device=3Djob, sp= eed=3D0) - self.assert_qmp(result, 'return', {}) - - # Wait for all jobs to be finished. - while len(pending_jobs) > 0: - for event in self.vm.get_qmp_events(wait=3DTrue): - if event['event'] =3D=3D 'BLOCK_JOB_COMPLETED': - job_id =3D self.dictpath(event, 'data/device') - self.assertTrue(job_id in pending_jobs) - self.assert_qmp_absent(event, 'data/error') - pending_jobs.remove(job_id) - - self.assert_no_active_block_jobs() - self.vm.shutdown() - - # Check that all maps match now - for i in range(2, self.num_imgs, 2): - self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', se= lf.imgs[i]), - qemu_io('-f', iotests.imgfmt, '-c', 'map', se= lf.imgs[i-1]), - 'image file map does not match backing file a= fter streaming') - # Test that it's not possible to perform two block-stream # operations if there are nodes involved in both. def test_overlapping_1(self): self.assert_no_active_block_jobs() =20 # Set a speed limit to make sure that this job blocks the rest - result =3D self.vm.qmp('block-stream', device=3D'node4', job_id=3D= 'stream-node4', base=3Dself.imgs[1], speed=3D1024*1024) + result =3D self.vm.qmp('block-stream', device=3D'node4', + job_id=3D'stream-node4', base=3Dself.imgs[1], + filter_node_name=3D'stream-filter', speed=3D1= 024*1024) self.assert_qmp(result, 'return', {}) =20 result =3D self.vm.qmp('block-stream', device=3D'node5', job_id=3D= 'stream-node5', base=3Dself.imgs[2]) self.assert_qmp(result, 'error/desc', - "Node 'node4' is busy: block device is in use by block job: st= ream") + "Node 'stream-filter' is busy: block device is in use by block= job: stream") =20 result =3D self.vm.qmp('block-stream', device=3D'node3', job_id=3D= 'stream-node3', base=3Dself.imgs[2]) self.assert_qmp(result, 'error/desc', @@ -287,7 +247,7 @@ class TestParallelOps(iotests.QMPTestCase): # block-commit should also fail if it touches nodes used by the st= ream job result =3D self.vm.qmp('block-commit', device=3D'drive0', base=3Ds= elf.imgs[4], job_id=3D'commit-node4') self.assert_qmp(result, 'error/desc', - "Node 'node4' is busy: block device is in use by block job: st= ream") + "Node 'stream-filter' is busy: block device is in use by block= job: stream") =20 result =3D self.vm.qmp('block-commit', device=3D'drive0', base=3Ds= elf.imgs[1], top=3Dself.imgs[3], job_id=3D'commit-node1') self.assert_qmp(result, 'error/desc', diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out index 6d9bee1..5eb508d 100644 --- a/tests/qemu-iotests/030.out +++ b/tests/qemu-iotests/030.out @@ -1,5 +1,5 @@ -........................... +.......................... ---------------------------------------------------------------------- -Ran 27 tests +Ran 26 tests =20 OK --=20 1.8.3.1