diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index b7671fc1def8..b24230b12c16 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -739,13 +739,12 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r) BDRVQcow2State *s = bs->opaque; int ret; - if (r->nb_sectors == 0) { + if (r->nb_bytes == 0) { return 0; } qemu_co_mutex_unlock(&s->lock); - ret = do_perform_cow(bs, m->offset, m->alloc_offset, - r->offset, r->nb_sectors * BDRV_SECTOR_SIZE); + ret = do_perform_cow(bs, m->offset, m->alloc_offset, r->offset, r->nb_bytes); qemu_co_mutex_lock(&s->lock); if (ret < 0) { @@ -1196,25 +1195,20 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, /* * Save info needed for meta data update. * - * requested_sectors: Number of sectors from the start of the first + * requested_bytes: Number of bytes from the start of the first * newly allocated cluster to the end of the (possibly shortened * before) write request. * - * avail_sectors: Number of sectors from the start of the first + * avail_bytes: Number of bytes from the start of the first * newly allocated to the end of the last newly allocated cluster. * - * nb_sectors: The number of sectors from the start of the first + * nb_bytes: The number of bytes from the start of the first * newly allocated cluster to the end of the area that the write * request actually writes to (excluding COW at the end) */ - int requested_sectors = - (*bytes + offset_into_cluster(s, guest_offset)) - >> BDRV_SECTOR_BITS; - int avail_sectors = nb_clusters - << (s->cluster_bits - BDRV_SECTOR_BITS); - int alloc_n_start = offset_into_cluster(s, guest_offset) - >> BDRV_SECTOR_BITS; - int nb_sectors = MIN(requested_sectors, avail_sectors); + uint64_t requested_bytes = *bytes + offset_into_cluster(s, guest_offset); + int avail_bytes = MIN(INT_MAX, nb_clusters << s->cluster_bits); + int nb_bytes = MIN(requested_bytes, avail_bytes); QCowL2Meta *old_m = *m; *m = g_malloc0(sizeof(**m)); @@ -1225,23 +1219,21 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, .alloc_offset = alloc_cluster_offset, .offset = start_of_cluster(s, guest_offset), .nb_clusters = nb_clusters, - .nb_available = nb_sectors, .cow_start = { .offset = 0, - .nb_sectors = alloc_n_start, + .nb_bytes = offset_into_cluster(s, guest_offset), }, .cow_end = { - .offset = nb_sectors * BDRV_SECTOR_SIZE, - .nb_sectors = avail_sectors - nb_sectors, + .offset = nb_bytes, + .nb_bytes = avail_bytes - nb_bytes, }, }; qemu_co_queue_init(&(*m)->dependent_requests); QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset); - *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE) - - offset_into_cluster(s, guest_offset)); + *bytes = MIN(*bytes, nb_bytes - offset_into_cluster(s, guest_offset)); assert(*bytes != 0); return 1; diff --git a/block/qcow2.h b/block/qcow2.h index e2c42d55147f..175b0c1740a0 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -302,8 +302,8 @@ typedef struct Qcow2COWRegion { */ uint64_t offset; - /** Number of sectors to copy */ - int nb_sectors; + /** Number of bytes to copy */ + int nb_bytes; } Qcow2COWRegion; /** @@ -318,12 +318,6 @@ typedef struct QCowL2Meta /** Host offset of the first newly allocated cluster */ uint64_t alloc_offset; - /** - * Number of sectors from the start of the first allocated cluster to - * the end of the (possibly shortened) request - */ - int nb_available; - /** Number of newly allocated clusters */ int nb_clusters; @@ -471,8 +465,7 @@ static inline uint64_t l2meta_cow_start(QCowL2Meta *m) static inline uint64_t l2meta_cow_end(QCowL2Meta *m) { - return m->offset + m->cow_end.offset - + (m->cow_end.nb_sectors << BDRV_SECTOR_BITS); + return m->offset + m->cow_end.offset + m->cow_end.nb_bytes; } static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2)