qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v5 1/5] block/io: fix bdrv_co_block_status_above


From: Alberto Garcia
Subject: Re: [PATCH v5 1/5] block/io: fix bdrv_co_block_status_above
Date: Wed, 19 Aug 2020 13:34:22 +0200
User-agent: Notmuch/0.18.2 (http://notmuchmail.org) Emacs/24.4.1 (i586-pc-linux-gnu)

On Wed 19 Aug 2020 11:48:25 AM CEST, Vladimir Sementsov-Ogievskiy wrote:
>>> +             * The top layer deferred to this layer, and because this 
>>> layer is
>>> +             * short, any zeroes that we synthesize beyond EOF behave as 
>>> if they
>>> +             * were allocated at this layer
>>>                */
>>> +            assert(ret & BDRV_BLOCK_EOF);
>>>               *pnum = bytes;
>>> +            if (file) {
>>> +                *file = p;
>>> +            }
>>> +            return BDRV_BLOCK_ZERO | BDRV_BLOCK_ALLOCATED;
>> 
>> You don't add BDRV_BLOCK_EOF to the return code here ?
>
> No we shouldn't, as this is the end of backing file when the top layer
> is larger.

Ok, but maybe the original request also reaches EOF on the top layer.

An example that does not actually involve short backing files: let's say
that the size of the active image is 1MB and the backing file is 2MB.

We do 'write -z 960k 63k', that zeroes the last cluster minus a 1KB
tail, so qcow2_co_pwrite_zeroes() calls is_zero() to check if that last
1KB already contains zeroes.

bdrv_co_block_status_above() on the top layer returns BDRV_BLOCK_EOF: no
allocation, no zeros, we simply reached EOF. So we go to the backing
image to see what's there. This is also unallocated, there's no backing
file this time and want_zero is set, so this returns BDRV_BLOCK_ZERO.
However the backing file is longer so bdrv_co_block_status() does not
return BDRV_BLOCK_EOF this time.

If the backing file would have been the same size (1MB) we would have
BDRV_BLOCK_ZERO | BDRV_BLOCK_EOF, but if it's longer or (with your
patch) shorter then BDRV_BLOCK_EOF disappears.

Now, I don't see anyone else using BDRV_BLOCK_EOF for anything so this
does not have any practical effect at the moment, but is this worth
fixing?.

>>> +        res = bdrv_block_status_above(bs, NULL, offset, bytes, &nr, NULL, 
>>> NULL);
>>> +        offset += nr;
>>> +        bytes -= nr;
>>> +    } while (res >= 0 && (res & BDRV_BLOCK_ZERO) && nr && bytes);
>> 
>> About this last "... && nr && bytes", I think 'nr' already implies
>> 'bytes', maybe you want to use an assertion instead?
>
> No, on the last iteration, bytes would be 0 and nr is a last
> chunk. So, if we check only nr, we'll do one extra call of
> bdrv_block_status_above with bytes=0, I don't want do it.

You're right !

Berto



reply via email to

[Prev in Thread] Current Thread [Next in Thread]