Am 26.05.2016 um 16:35 hat Eric Blake geschrieben:
> On 05/26/2016 07:41 AM, Denis V. Lunev wrote:
> > On 05/26/2016 06:48 AM, Eric Blake wrote:
> >> is_zero_cluster() and is_zero_cluster_top_locked() are used only
> >> by qcow2_co_write_zeroes(). The former is too broad (we don't
> >> care if the sectors we are about to overwrite are non-zero, only
> >> that all other sectors in the cluster are zero), so it needs to
> >> be called up to twice but with smaller limits - rename it along
> >> with adding the neeeded parameter. The latter can be inlined for
> >> more compact code.
> >>
> >> The testsuite change shows that we now have a sparser top file
> >> when an unaligned write_zeroes overwrites the only portion of
> >> the backing file with data.
> >>
> >> Based on a patch proposal by Denis V. Lunev.
> >>
>
> >> -
> >> - if (!is_zero_cluster(bs, sector_num)) {
> >> + /* check whether remainder of cluster already reads as zero */
> >> + if (!(is_zero_sectors(bs, cl_start, head) &&
> >> + is_zero_sectors(bs, sector_num + nb_sectors,
> >> + -tail & (s->cluster_sectors - 1)))) {
> >
> > can we have cluster_sectors != 2^n?
>
> No. cluster_sectors is an inherent property of the qcow2 file format:
>
>
> 20 - 23: cluster_bits
> Number of bits that are used for addressing an offset
> within a cluster (1 << cluster_bits is the cluster
> size).
> Must not be less than 9 (i.e. 512 byte clusters).
>
>
> As the file format uses a bit shift value, you are guaranteed to have a
> power of two amount of sectors within a cluster.
>
> If you prefer, I could have written '-tail % s->cluster_sectors', but as
> % on a negative signed integer gives different results than what you get
> for an unsigned number, I felt that & was nicer than % for making it
> more obvious that I'm grabbing particular bits.
>
> If you can think of any cleaner expression that represents the number of
> sectors occurring after the tail until the next cluster boundary, I'm
> game; the hardest part is that when tail is 0, we want the number passed
> to is_zero_sectors() to also be 0, not s->cluster_sectors (so the naive
> 's->cluster_sectors - tail' is wrong).
The obvious one would be translating your English into C:
tail ? s->cluster_sectors - tail : 0
Another option which doesn't require an unsigned type would be
(s->cluster_sectors - tail) % s->cluster_sectors.
I'm okay with merging the "more interesting" version, though I must
admit that I had to read it twice.
Kevin
pgpkMNmJVGWNS.pgp
Description: PGP signature
