On 4/28/20 9:16 AM, Kevin Wolf wrote:
Yes. Although now I'm wondering if the two should remain separate or should
just be a single driver callback where flags can include BDRV_REQ_ZERO_WRITE
to distinguish whether exposing the backing file vs. reading as all zeroes
is intended, or if that is merging too much.
I don't think the implementations for both things are too similar, so
you might just end up having two if branches and then two separate
implementations in the block drivers.
Yeah, the more I think about it, the more two callbacks still make
sense. .bdrv_make_empty may or may not need a flag, but .bdrv_make_zero
definitely does (because that's where we want a difference between
making the entire image zero no matter the delay, vs. only making it all
zero if it is is fast).
If anything, bdrv_make_empty() is more related to discard than
write_zeroes. But we use the discard code for it in qcow2 only as a
fallback because in the most common cases, making an image completely
empty means effectively just creating an entirely new L1 and refcount
table, which is much faster than individually discarding all clusters.
For bdrv_make_zero() I don't see an opportunity for such optimisations,
so I don't really see a reason to have a separate callback. Unless you
do know one?
The optimization I have in mind is adding a qcow2 autoclear bit to track
when an image is known to read as all zero - at which point
.bdrv_make_zero instantly returns success. For raw files, a possible
optimization is to truncate to size 0 and then back to the full size,
when it is known that truncation forces read-as-zero. For NBD, I'm
still playing with whether adding new 64-bit transactions for a bulk
zero will be useful, and even if not, maybe special-casing
NBD_CMD_WRITE_ZEROES with a size of 0 to do a bulk zero, if both server
and client negotiated that particular meaning.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org