mirror: Switch mirror_dirty_init() to byte-based iteration

Now that we have adjusted the majority of the calls this function
makes to be byte-based, it is easier to read the code if it makes
passes over the image using bytes rather than sectors.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Eric Blake 2017-09-25 09:55:21 -05:00 committed by Kevin Wolf
parent e0d7f73e63
commit 23ca459a45

View File

@ -612,15 +612,13 @@ static void mirror_throttle(MirrorBlockJob *s)
static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s) static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
{ {
int64_t sector_num, end; int64_t offset;
BlockDriverState *base = s->base; BlockDriverState *base = s->base;
BlockDriverState *bs = s->source; BlockDriverState *bs = s->source;
BlockDriverState *target_bs = blk_bs(s->target); BlockDriverState *target_bs = blk_bs(s->target);
int ret, n; int ret;
int64_t count; int64_t count;
end = s->bdev_length / BDRV_SECTOR_SIZE;
if (base == NULL && !bdrv_has_zero_init(target_bs)) { if (base == NULL && !bdrv_has_zero_init(target_bs)) {
if (!bdrv_can_write_zeroes_with_unmap(target_bs)) { if (!bdrv_can_write_zeroes_with_unmap(target_bs)) {
bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length); bdrv_set_dirty_bitmap(s->dirty_bitmap, 0, s->bdev_length);
@ -628,9 +626,9 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
} }
s->initial_zeroing_ongoing = true; s->initial_zeroing_ongoing = true;
for (sector_num = 0; sector_num < end; ) { for (offset = 0; offset < s->bdev_length; ) {
int nb_sectors = MIN(end - sector_num, int bytes = MIN(s->bdev_length - offset,
QEMU_ALIGN_DOWN(INT_MAX, s->granularity) >> BDRV_SECTOR_BITS); QEMU_ALIGN_DOWN(INT_MAX, s->granularity));
mirror_throttle(s); mirror_throttle(s);
@ -646,9 +644,8 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
continue; continue;
} }
mirror_do_zero_or_discard(s, sector_num * BDRV_SECTOR_SIZE, mirror_do_zero_or_discard(s, offset, bytes, false);
nb_sectors * BDRV_SECTOR_SIZE, false); offset += bytes;
sector_num += nb_sectors;
} }
mirror_wait_for_all_io(s); mirror_wait_for_all_io(s);
@ -656,10 +653,10 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
} }
/* First part, loop on the sectors and initialize the dirty bitmap. */ /* First part, loop on the sectors and initialize the dirty bitmap. */
for (sector_num = 0; sector_num < end; ) { for (offset = 0; offset < s->bdev_length; ) {
/* Just to make sure we are not exceeding int limit. */ /* Just to make sure we are not exceeding int limit. */
int nb_sectors = MIN(INT_MAX >> BDRV_SECTOR_BITS, int bytes = MIN(s->bdev_length - offset,
end - sector_num); QEMU_ALIGN_DOWN(INT_MAX, s->granularity));
mirror_throttle(s); mirror_throttle(s);
@ -667,23 +664,16 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob *s)
return 0; return 0;
} }
ret = bdrv_is_allocated_above(bs, base, sector_num * BDRV_SECTOR_SIZE, ret = bdrv_is_allocated_above(bs, base, offset, bytes, &count);
nb_sectors * BDRV_SECTOR_SIZE, &count);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
/* TODO: Relax this once bdrv_is_allocated_above and dirty assert(count);
* bitmaps no longer require sector alignment. */
assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
n = count >> BDRV_SECTOR_BITS;
assert(n > 0);
if (ret == 1) { if (ret == 1) {
bdrv_set_dirty_bitmap(s->dirty_bitmap, bdrv_set_dirty_bitmap(s->dirty_bitmap, offset, count);
sector_num * BDRV_SECTOR_SIZE,
n * BDRV_SECTOR_SIZE);
} }
sector_num += n; offset += count;
} }
return 0; return 0;
} }