From nobody Sun Feb 8 16:34:19 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1499961120686826.8951856812067; Thu, 13 Jul 2017 08:52:00 -0700 (PDT) Received: from localhost ([::1]:60816 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVgPF-0001Vc-7q for importer@patchew.org; Thu, 13 Jul 2017 11:51:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53878) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dVgLE-0004pJ-3T for qemu-devel@nongnu.org; Thu, 13 Jul 2017 11:47:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dVgLC-0005pv-Ol for qemu-devel@nongnu.org; Thu, 13 Jul 2017 11:47:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59886) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dVgL7-0005nh-EQ; Thu, 13 Jul 2017 11:47:41 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F37654E4CB; Thu, 13 Jul 2017 15:47:39 +0000 (UTC) Received: from red.redhat.com (ovpn-121-60.rdu2.redhat.com [10.10.121.60]) by smtp.corp.redhat.com (Postfix) with ESMTP id B672E709F3; Thu, 13 Jul 2017 15:47:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com F37654E4CB Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eblake@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com F37654E4CB From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 13 Jul 2017 10:46:55 -0500 Message-Id: <20170713154711.32374-8-eblake@redhat.com> In-Reply-To: <20170713154711.32374-1-eblake@redhat.com> References: <20170713154711.32374-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 13 Jul 2017 15:47:40 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 07/23] block: Convert bdrv_get_block_status() to bytes 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: kwolf@redhat.com, famz@redhat.com, qemu-block@nongnu.org, el13635@mail.ntua.gr, Max Reitz , Stefan Hajnoczi , jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We are gradually moving away from sector-based interfaces, towards byte-based. In the common case, allocation is unlikely to ever use values that are not naturally sector-aligned, but it is possible that byte-based values will let us be more precise about allocation at the end of an unaligned file that can do byte-based access. Changing the name of the function from bdrv_get_block_status() to bdrv_block_status() ensures that the compiler enforces that all callers are updated. For now, the io.c layer still assert()s that all callers are sector-aligned, but that can be relaxed when a later patch implements byte-based block status in the drivers. Note that we have an inherent limitation in the BDRV_BLOCK_* return values: BDRV_BLOCK_OFFSET_VALID can only return the start of a sector, even if we later relax the interface to query for the status starting at an intermediate byte; document the obvious interpretation that valid offsets are always sector-relative. Therefore, for the most part this patch is just the addition of scaling at the callers followed by inverse scaling at bdrv_block_status(). But some code, particularly bdrv_is_allocated(), gets a lot simpler because it no longer has to mess with sectors. For ease of review, bdrv_get_block_status_above() will be tackled separately. Signed-off-by: Eric Blake --- v3: clamp bytes to 32-bits, rather than asserting v2: rebase to earlier changes --- include/block/block.h | 12 +++++++----- block/io.c | 31 +++++++++++++++++++------------ block/qcow2-cluster.c | 2 +- qemu-img.c | 20 +++++++++++--------- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index e729396..581011b 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -138,8 +138,10 @@ typedef struct HDGeometry { * * If BDRV_BLOCK_OFFSET_VALID is set, bits 9-62 (BDRV_BLOCK_OFFSET_MASK) * represent the offset in the returned BDS that is allocated for the - * corresponding raw data; however, whether that offset actually contains - * data also depends on BDRV_BLOCK_DATA and BDRV_BLOCK_ZERO, as follows: + * corresponding raw data. Individual bytes are at the same sector-relati= ve + * locations (and thus, this bit cannot be set for mappings which are + * not equivalent modulo 512). However, whether that offset actually + * contains data also depends on BDRV_BLOCK_DATA, as follows: * * DATA ZERO OFFSET_VALID * t t t sectors read as zero, returned file is zero at o= ffset @@ -422,9 +424,9 @@ int bdrv_has_zero_init_1(BlockDriverState *bs); int bdrv_has_zero_init(BlockDriverState *bs); bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs); bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); -int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum, - BlockDriverState **file); +int64_t bdrv_block_status(BlockDriverState *bs, int64_t offset, + int64_t bytes, int64_t *pnum, + BlockDriverState **file); int64_t bdrv_get_block_status_above(BlockDriverState *bs, BlockDriverState *base, int64_t sector_num, diff --git a/block/io.c b/block/io.c index 37a9714..dcea3e3 100644 --- a/block/io.c +++ b/block/io.c @@ -671,7 +671,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags f= lags) { int64_t target_size, ret, bytes, offset =3D 0; BlockDriverState *bs =3D child->bs; - int n; /* sectors */ target_size =3D bdrv_getlength(bs); if (target_size < 0) { @@ -683,24 +682,23 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags= flags) if (bytes <=3D 0) { return 0; } - ret =3D bdrv_get_block_status(bs, offset >> BDRV_SECTOR_BITS, - bytes >> BDRV_SECTOR_BITS, &n, NULL); + ret =3D bdrv_block_status(bs, offset, bytes, &bytes, NULL); if (ret < 0) { error_report("error getting block status at offset %" PRId64 "= : %s", offset, strerror(-ret)); return ret; } if (ret & BDRV_BLOCK_ZERO) { - offset +=3D n * BDRV_SECTOR_BITS; + offset +=3D bytes; continue; } - ret =3D bdrv_pwrite_zeroes(child, offset, n * BDRV_SECTOR_SIZE, fl= ags); + ret =3D bdrv_pwrite_zeroes(child, offset, bytes, flags); if (ret < 0) { error_report("error writing zeroes at offset %" PRId64 ": %s", offset, strerror(-ret)); return ret; } - offset +=3D n * BDRV_SECTOR_SIZE; + offset +=3D bytes; } } @@ -1959,13 +1957,22 @@ int64_t bdrv_get_block_status_above(BlockDriverStat= e *bs, nb_sectors, pnum, file); } -int64_t bdrv_get_block_status(BlockDriverState *bs, - int64_t sector_num, - int nb_sectors, int *pnum, - BlockDriverState **file) +int64_t bdrv_block_status(BlockDriverState *bs, + int64_t offset, int64_t bytes, int64_t *pnum, + BlockDriverState **file) { - return bdrv_get_block_status_above(bs, backing_bs(bs), - sector_num, nb_sectors, pnum, file); + int64_t ret; + int n; + + assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE)); + bytes =3D MIN(bytes, BDRV_REQUEST_MAX_BYTES); + ret =3D bdrv_get_block_status_above(bs, backing_bs(bs), + offset >> BDRV_SECTOR_BITS, + bytes >> BDRV_SECTOR_BITS, &n, file); + if (pnum) { + *pnum =3D n * BDRV_SECTOR_SIZE; + } + return ret; } int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index f06c08f..0185986 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1567,7 +1567,7 @@ static int discard_single_l2(BlockDriverState *bs, ui= nt64_t offset, * cluster is already marked as zero, or if it's unallocated and we * don't have a backing file. * - * TODO We might want to use bdrv_get_block_status(bs) here, but w= e're + * TODO We might want to use bdrv_block_status(bs) here, but we're * holding s->lock, so that doesn't work today. * * If full_discard is true, the sector should not read back as zer= oes, diff --git a/qemu-img.c b/qemu-img.c index f7332f4..149dab2 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1592,9 +1592,14 @@ static int convert_iteration_sectors(ImgConvertState= *s, int64_t sector_num) if (s->sector_next_status <=3D sector_num) { if (s->target_has_backing) { - ret =3D bdrv_get_block_status(blk_bs(s->src[src_cur]), - sector_num - src_cur_offset, - n, &n, NULL); + int64_t count =3D n * BDRV_SECTOR_SIZE; + + ret =3D bdrv_block_status(blk_bs(s->src[src_cur]), + (sector_num - src_cur_offset) * + BDRV_SECTOR_SIZE, + count, &count, NULL); + assert(ret < 0 || QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)); + n =3D count >> BDRV_SECTOR_BITS; } else { ret =3D bdrv_get_block_status_above(blk_bs(s->src[src_cur]), N= ULL, sector_num - src_cur_offset, @@ -2671,9 +2676,7 @@ static int get_block_status(BlockDriverState *bs, int= 64_t offset, int depth; BlockDriverState *file; bool has_offset; - int nb_sectors =3D bytes >> BDRV_SECTOR_BITS; - assert(bytes < INT_MAX); /* As an optimization, we could cache the current range of unallocated * clusters in each file of the chain, and avoid querying the same * range repeatedly. @@ -2681,12 +2684,11 @@ static int get_block_status(BlockDriverState *bs, i= nt64_t offset, depth =3D 0; for (;;) { - ret =3D bdrv_get_block_status(bs, offset >> BDRV_SECTOR_BITS, nb_s= ectors, - &nb_sectors, &file); + ret =3D bdrv_block_status(bs, offset, bytes, &bytes, &file); if (ret < 0) { return ret; } - assert(nb_sectors); + assert(bytes); if (ret & (BDRV_BLOCK_ZERO|BDRV_BLOCK_DATA)) { break; } @@ -2703,7 +2705,7 @@ static int get_block_status(BlockDriverState *bs, int= 64_t offset, *e =3D (MapEntry) { .start =3D offset, - .length =3D nb_sectors * BDRV_SECTOR_SIZE, + .length =3D bytes, .data =3D !!(ret & BDRV_BLOCK_DATA), .zero =3D !!(ret & BDRV_BLOCK_ZERO), .offset =3D ret & BDRV_BLOCK_OFFSET_MASK, --=20 2.9.4