From nobody Sat Apr 27 19:08:58 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1641815802488340.90674237922246; Mon, 10 Jan 2022 03:56:42 -0800 (PST) Received: from localhost ([::1]:40086 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n6tI1-0001Xe-Cb for importer@patchew.org; Mon, 10 Jan 2022 06:56:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:36998) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n6tFI-0007yx-O9 for qemu-devel@nongnu.org; Mon, 10 Jan 2022 06:53:55 -0500 Received: from kerio.kamp.de ([195.62.97.192]:51470) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n6tFG-0001g1-Q2 for qemu-devel@nongnu.org; Mon, 10 Jan 2022 06:53:52 -0500 Received: from submission.kamp.de ([195.62.97.28]) by kerio.kamp.de with ESMTPS (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)) for qemu-devel@nongnu.org; Mon, 10 Jan 2022 12:42:00 +0100 Received: (qmail 63032 invoked from network); 10 Jan 2022 11:42:00 -0000 Received: from lieven-pc.kamp-intra.net (HELO lieven-pc) (relay@kamp.de@::ffff:172.21.12.60) by submission.kamp.de with ESMTPS (DHE-RSA-AES256-GCM-SHA384 encrypted) ESMTPA; 10 Jan 2022 11:42:00 -0000 Received: by lieven-pc (Postfix, from userid 1060) id 6715A13D99C; Mon, 10 Jan 2022 12:42:00 +0100 (CET) X-Footer: a2FtcC5kZQ== From: Peter Lieven To: qemu-block@nongnu.org Subject: [PATCH 1/2] block/rbd: fix handling of holes in .bdrv_co_block_status Date: Mon, 10 Jan 2022 12:41:53 +0100 Message-Id: <20220110114154.3774072-2-pl@kamp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220110114154.3774072-1-pl@kamp.de> References: <20220110114154.3774072-1-pl@kamp.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=195.62.97.192; envelope-from=pl@kamp.de; helo=kerio.kamp.de 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=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, idryomov@redhat.com, berrange@redhat.com, qemu-stable@nongnu.org, Peter Lieven , qemu-devel@nongnu.org, ct@flyingcircus.io, pbonzini@redhat.com, idryomov@gmail.com, mreitz@redhat.com, dillaman@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1641815804730100001 Content-Type: text/plain; charset="utf-8" the assumption that we can't hit a hole if we do not diff against a snapsho= t was wrong. We can see a hole in an image if we diff against base if there exists an ol= der snapshot of the image and we have discarded blocks in the image where the snapshot h= as data. Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b Cc: qemu-stable@nongnu.org Signed-off-by: Peter Lieven --- block/rbd.c | 55 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/block/rbd.c b/block/rbd.c index def96292e0..5e9dc91d81 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -1279,13 +1279,24 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, = size_t len, RBDDiffIterateReq *req =3D opaque; =20 assert(req->offs + req->bytes <=3D offs); - /* - * we do not diff against a snapshot so we should never receive a call= back - * for a hole. - */ - assert(exists); =20 - if (!req->exists && offs > req->offs) { + if (req->exists && offs > req->offs + req->bytes) { + /* + * we started in an allocated area and jumped over an unallocated = area, + * req->bytes contains the length of the allocated area before the + * unallocated area. stop further processing. + */ + return QEMU_RBD_EXIT_DIFF_ITERATE2; + } + if (req->exists && !exists) { + /* + * we started in an allocated area and reached a hole. req->bytes + * contains the length of the allocated area before the hole. + * stop further processing. + */ + return QEMU_RBD_EXIT_DIFF_ITERATE2; + } + if (!req->exists && exists && offs > req->offs) { /* * we started in an unallocated area and hit the first allocated * block. req->bytes must be set to the length of the unallocated = area @@ -1295,17 +1306,19 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, = size_t len, return QEMU_RBD_EXIT_DIFF_ITERATE2; } =20 - if (req->exists && offs > req->offs + req->bytes) { - /* - * we started in an allocated area and jumped over an unallocated = area, - * req->bytes contains the length of the allocated area before the - * unallocated area. stop further processing. - */ - return QEMU_RBD_EXIT_DIFF_ITERATE2; - } + /* + * assert that we caught all cases above and allocation state has not + * changed during callbacks. + */ + assert(exists =3D=3D req->exists || !req->bytes); + req->exists =3D exists; =20 - req->bytes +=3D len; - req->exists =3D true; + /* + * assert that we either return an unallocated block or have got callb= acks + * for all allocated blocks present. + */ + assert(!req->exists || offs =3D=3D req->offs + req->bytes); + req->bytes =3D offs + len - req->offs; =20 return 0; } @@ -1354,13 +1367,13 @@ static int coroutine_fn qemu_rbd_co_block_status(Bl= ockDriverState *bs, } assert(req.bytes <=3D bytes); if (!req.exists) { - if (r =3D=3D 0) { + if (r =3D=3D 0 && !req.bytes) { /* - * rbd_diff_iterate2 does not invoke callbacks for unallocated - * areas. This here catches the case where no callback was - * invoked at all (req.bytes =3D=3D 0). + * rbd_diff_iterate2 does not invoke callbacks for unallocated= areas + * except for the case where an overlay has a hole where the p= arent + * or an older snapshot of the image has not. This here catche= s the + * case where no callback was invoked at all. */ - assert(req.bytes =3D=3D 0); req.bytes =3D bytes; } status =3D BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID; --=20 2.25.1 From nobody Sat Apr 27 19:08:58 2024 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1641815007141375.2432216016673; Mon, 10 Jan 2022 03:43:27 -0800 (PST) Received: from localhost ([::1]:60454 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n6t5B-0003zl-GH for importer@patchew.org; Mon, 10 Jan 2022 06:43:25 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33286) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n6t40-0002tt-Ss for qemu-devel@nongnu.org; Mon, 10 Jan 2022 06:42:13 -0500 Received: from kerio.kamp.de ([195.62.97.192]:51196) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n6t3z-0008R0-7T for qemu-devel@nongnu.org; Mon, 10 Jan 2022 06:42:12 -0500 Received: from submission.kamp.de ([195.62.97.28]) by kerio.kamp.de with ESMTPS (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256 bits)) for qemu-devel@nongnu.org; Mon, 10 Jan 2022 12:42:00 +0100 Received: (qmail 63033 invoked from network); 10 Jan 2022 11:42:00 -0000 Received: from lieven-pc.kamp-intra.net (HELO lieven-pc) (relay@kamp.de@::ffff:172.21.12.60) by submission.kamp.de with ESMTPS (DHE-RSA-AES256-GCM-SHA384 encrypted) ESMTPA; 10 Jan 2022 11:42:00 -0000 Received: by lieven-pc (Postfix, from userid 1060) id 6ABD413D99E; Mon, 10 Jan 2022 12:42:00 +0100 (CET) X-Footer: a2FtcC5kZQ== From: Peter Lieven To: qemu-block@nongnu.org Subject: [PATCH 2/2] block/rbd: workaround for ceph issue #53784 Date: Mon, 10 Jan 2022 12:41:54 +0100 Message-Id: <20220110114154.3774072-3-pl@kamp.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220110114154.3774072-1-pl@kamp.de> References: <20220110114154.3774072-1-pl@kamp.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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=195.62.97.192; envelope-from=pl@kamp.de; helo=kerio.kamp.de 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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, idryomov@redhat.com, berrange@redhat.com, qemu-stable@nongnu.org, Peter Lieven , qemu-devel@nongnu.org, ct@flyingcircus.io, pbonzini@redhat.com, idryomov@gmail.com, mreitz@redhat.com, dillaman@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1641815009767100003 Content-Type: text/plain; charset="utf-8" librbd had a bug until early 2022 that affected all versions of ceph that supported fast-diff. This bug results in reporting of incorrect offsets if the offset parameter to rbd_diff_iterate2 is not object aligned. Work around this bug by rounding down the offset to object boundaries. Fixes: https://tracker.ceph.com/issues/53784 Cc: qemu-stable@nongnu.org Signed-off-by: Peter Lieven Tested-by: Stefano Garzarella --- block/rbd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/block/rbd.c b/block/rbd.c index 5e9dc91d81..260cb9f4b4 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -1333,6 +1333,7 @@ static int coroutine_fn qemu_rbd_co_block_status(Bloc= kDriverState *bs, int status, r; RBDDiffIterateReq req =3D { .offs =3D offset }; uint64_t features, flags; + int64_t head; =20 assert(offset + bytes <=3D s->image_size); =20 @@ -1360,6 +1361,19 @@ static int coroutine_fn qemu_rbd_co_block_status(Blo= ckDriverState *bs, return status; } =20 + /* + * librbd had a bug until early 2022 that affected all versions of cep= h that + * supported fast-diff. This bug results in reporting of incorrect off= sets + * if the offset parameter to rbd_diff_iterate2 is not object aligned. + * Work around this bug by rounding down the offset to object boundari= es. + * + * See: https://tracker.ceph.com/issues/53784 + */ + head =3D offset & (s->object_size - 1); + offset -=3D head; + req.offs -=3D head; + bytes +=3D head; + r =3D rbd_diff_iterate2(s->image, NULL, offset, bytes, true, true, qemu_rbd_diff_iterate_cb, &req); if (r < 0 && r !=3D QEMU_RBD_EXIT_DIFF_ITERATE2) { @@ -1379,7 +1393,8 @@ static int coroutine_fn qemu_rbd_co_block_status(Bloc= kDriverState *bs, status =3D BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID; } =20 - *pnum =3D req.bytes; + assert(req.bytes > head); + *pnum =3D req.bytes - head; return status; } =20 --=20 2.25.1