On 10/20/2016 07:24 PM, Ed Swierk wrote:
> Shortly after I start qemu 2.7.0 with a qcow2 disk image created with
> -o cluster_size=1048576, it prints the following and dies:
> 
> block/qcow2.c:2451: qcow2_co_pwrite_zeroes: Assertion `head + count <=
> s->cluster_size' failed.
> 
> I narrowed the problem to bdrv_co_do_pwrite_zeroes(), called by
> bdrv_aligned_pwritev() with flags & BDRV_REQ_ZERO_WRITE set.
> 
> On the first loop iteration, offset=8003584, count=2093056,
> head=663552, tail=659456 and num=2093056. qcow2_co_pwrite_zeroes() is
> called with offset=8003584 and count=385024 and finds that the head
> portion is not already zero, so it returns -ENOTSUP.
> bdrv_co_do_pwrite_zeroes() falls back to a normal write, with
> max_transfer=65536.

Ah. When the cluster is larger than 64k, we HAVE to handle the entire
cluster in one operation, or else the head occupies more than one
'sector' while the assert is that at most 'sector' is unaligned.

> 
> The next iteration starts with offset incremented by 65536, count and
> num decremented by 65536, and head=0, violating the assumption that
> the entire 385024 bytes of the head remainder had been zeroed the
> first time around. Then it calls qcow2_co_pwrite_zeroes() with an
> unaligned offset=8069120 and a count=1368064 greater than the cluster
> size, triggering the assertion failure.
> 
> Changing max_transfer in the normal write case to
> MIN_NON_ZERO(alignment, MAX_WRITE_ZEROES_BOUNCE_BUFFER) appears to fix
> the problem, but I don't pretend to understand all the subtleties
> here.

That actually sounds like the right fix.  But since the bug was probably
caused by my code, I'll formalize it into a patch and see if I can
modify the testsuite to give it coverage.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to