On 07/03/2017 05:14 PM, Eric Blake wrote: > Not all callers care about which BDS owns the mapping for a given > range of the file. In particular, bdrv_is_allocated() cares more > about finding the largest run of allocated data from the guest > perspective, whether or not that data is consecutive from the > host perspective. Therefore, doing subsequent refinements such > as checking how much of the format-layer allocation also satisfies > BDRV_BLOCK_ZERO at the protocol layer is wasted work - in the best > case, it just costs extra CPU cycles during a single > bdrv_is_allocated(), but in the worst case, it results in a smaller > *pnum, and forces callers to iterate through more status probes when > visiting the entire file for even more extra CPU cycles. > > This patch only optimizes the block layer. But subsequent patches > will tweak the driver callback to be byte-based, and in the process, > can also pass this hint through to the driver. > > Signed-off-by: Eric Blake <[email protected]> >
> @@ -1810,12 +1817,13 @@ static int64_t coroutine_fn
> bdrv_co_get_block_status(BlockDriverState *bs,
> }
> }
>
> - if (local_file && local_file != bs &&
> + if (!allocation && local_file && local_file != bs &&
> (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
> (ret & BDRV_BLOCK_OFFSET_VALID)) {
> int file_pnum;
>
> - ret2 = bdrv_co_get_block_status(local_file, ret >> BDRV_SECTOR_BITS,
> + ret2 = bdrv_co_get_block_status(local_file, true,
> + ret >> BDRV_SECTOR_BITS,
> *pnum, &file_pnum, NULL);
> if (ret2 >= 0) {
> /* Ignore errors. This is just providing extra information, it
Hmm. My initial thinking here was that if we already have a good primary
status, we want our secondary status (where we are probing bs->file for
whether we can add BDRV_BLOCK_ZERO) to be as fast as possible, so I
hard-coded the answer that favors is_allocated (I have to be careful
describing this, since v3 will switch from 'bool allocated=true' to
'bool mapping=false' to express that same request). But it turns out
that, at least for file-posix.c (for that matter, for several protocol
drivers), it's a LOT faster to just blindly state that the entire file
is allocated and data than it is to lseek(SEEK_HOLE). So favoring
allocation status instead of mapping status defeats the purpose, and
this should be s/true/allocation/ (which is always false at this point)
[or conversely s/false/mapping/, which is always true, in v3].
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature
