diff options
author | Eric Blake <eblake@redhat.com> | 2017-10-11 22:47:08 -0500 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-10-26 14:45:57 +0200 |
commit | 3182664220571d11d4fe03ecdc10fcc1e842ed32 (patch) | |
tree | a156b5da4a97164b0620bf8067130088a4cfe2f1 /block/qcow2.c | |
parent | 5b648c67e3acea3e0136d0bb1bd47341996e0e4e (diff) | |
download | qemu-3182664220571d11d4fe03ecdc10fcc1e842ed32.zip qemu-3182664220571d11d4fe03ecdc10fcc1e842ed32.tar.gz qemu-3182664220571d11d4fe03ecdc10fcc1e842ed32.tar.bz2 |
block: Convert bdrv_get_block_status_above() to bytes
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_above()
to bdrv_block_status_above() ensures that the compiler enforces that
all callers are updated. Likewise, since it a byte interface allows
an offset mapping that might not be sector aligned, split the mapping
out of the return value and into a pass-by-reference parameter. For
now, the io.c layer still assert()s that all uses are sector-aligned,
but that can be relaxed when a later patch implements byte-based
block status in the drivers.
For the most part this patch is just the addition of scaling at the
callers followed by inverse scaling at bdrv_block_status(), plus
updates for the new split return interface. But some code,
particularly bdrv_block_status(), gets a lot simpler because it no
longer has to mess with sectors. Likewise, mirror code no longer
computes s->granularity >> BDRV_SECTOR_BITS, and can therefore drop
an assertion about alignment because the loop no longer depends on
alignment (never mind that we don't really have a driver that
reports sub-sector alignments, so it's not really possible to test
the effect of sub-sector mirroring). Fix a neighboring assertion to
use is_power_of_2 while there.
For ease of review, bdrv_get_block_status() was tackled separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/qcow2.c')
-rw-r--r-- | block/qcow2.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/block/qcow2.c b/block/qcow2.c index 795be67..29d0a50 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2974,8 +2974,8 @@ finish: static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes) { - int nr; - int64_t res; + int64_t nr; + int res; int64_t start; /* TODO: Widening to sector boundaries should only be needed as @@ -2991,10 +2991,8 @@ static bool is_zero(BlockDriverState *bs, int64_t offset, int64_t bytes) if (!bytes) { return true; } - res = bdrv_get_block_status_above(bs, NULL, start >> BDRV_SECTOR_BITS, - bytes >> BDRV_SECTOR_BITS, &nr, NULL); - return res >= 0 && (res & BDRV_BLOCK_ZERO) && - nr * BDRV_SECTOR_SIZE == bytes; + res = bdrv_block_status_above(bs, NULL, start, bytes, &nr, NULL, NULL); + return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == bytes; } static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, @@ -3700,17 +3698,14 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, required = virtual_size; } else { int64_t offset; - int pnum = 0; + int64_t pnum = 0; - for (offset = 0; offset < ssize; - offset += pnum * BDRV_SECTOR_SIZE) { - int nb_sectors = MIN(ssize - offset, - BDRV_REQUEST_MAX_BYTES) / BDRV_SECTOR_SIZE; - int64_t ret; + for (offset = 0; offset < ssize; offset += pnum) { + int ret; - ret = bdrv_get_block_status_above(in_bs, NULL, - offset >> BDRV_SECTOR_BITS, - nb_sectors, &pnum, NULL); + ret = bdrv_block_status_above(in_bs, NULL, offset, + ssize - offset, &pnum, NULL, + NULL); if (ret < 0) { error_setg_errno(&local_err, -ret, "Unable to get block status"); @@ -3722,11 +3717,10 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, } else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) == (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) { /* Extend pnum to end of cluster for next iteration */ - pnum = (ROUND_UP(offset + pnum * BDRV_SECTOR_SIZE, - cluster_size) - offset) >> BDRV_SECTOR_BITS; + pnum = ROUND_UP(offset + pnum, cluster_size) - offset; /* Count clusters we've seen */ - required += offset % cluster_size + pnum * BDRV_SECTOR_SIZE; + required += offset % cluster_size + pnum; } } } |