qcow2: Use bytes instead of sectors for QCowL2Meta
In preparation for implementing .bdrv_co_pwritev in qcow2. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
aaa4d20b49
commit
8556739355
@ -739,13 +739,12 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m, Qcow2COWRegion *r)
|
|||||||
BDRVQcow2State *s = bs->opaque;
|
BDRVQcow2State *s = bs->opaque;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (r->nb_sectors == 0) {
|
if (r->nb_bytes == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
ret = do_perform_cow(bs, m->offset, m->alloc_offset,
|
ret = do_perform_cow(bs, m->offset, m->alloc_offset, r->offset, r->nb_bytes);
|
||||||
r->offset, r->nb_sectors * BDRV_SECTOR_SIZE);
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1196,25 +1195,20 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
|
|||||||
/*
|
/*
|
||||||
* Save info needed for meta data update.
|
* 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
|
* newly allocated cluster to the end of the (possibly shortened
|
||||||
* before) write request.
|
* 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.
|
* 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
|
* newly allocated cluster to the end of the area that the write
|
||||||
* request actually writes to (excluding COW at the end)
|
* request actually writes to (excluding COW at the end)
|
||||||
*/
|
*/
|
||||||
int requested_sectors =
|
uint64_t requested_bytes = *bytes + offset_into_cluster(s, guest_offset);
|
||||||
(*bytes + offset_into_cluster(s, guest_offset))
|
int avail_bytes = MIN(INT_MAX, nb_clusters << s->cluster_bits);
|
||||||
>> BDRV_SECTOR_BITS;
|
int nb_bytes = MIN(requested_bytes, avail_bytes);
|
||||||
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);
|
|
||||||
QCowL2Meta *old_m = *m;
|
QCowL2Meta *old_m = *m;
|
||||||
|
|
||||||
*m = g_malloc0(sizeof(**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,
|
.alloc_offset = alloc_cluster_offset,
|
||||||
.offset = start_of_cluster(s, guest_offset),
|
.offset = start_of_cluster(s, guest_offset),
|
||||||
.nb_clusters = nb_clusters,
|
.nb_clusters = nb_clusters,
|
||||||
.nb_available = nb_sectors,
|
|
||||||
|
|
||||||
.cow_start = {
|
.cow_start = {
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
.nb_sectors = alloc_n_start,
|
.nb_bytes = offset_into_cluster(s, guest_offset),
|
||||||
},
|
},
|
||||||
.cow_end = {
|
.cow_end = {
|
||||||
.offset = nb_sectors * BDRV_SECTOR_SIZE,
|
.offset = nb_bytes,
|
||||||
.nb_sectors = avail_sectors - nb_sectors,
|
.nb_bytes = avail_bytes - nb_bytes,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
qemu_co_queue_init(&(*m)->dependent_requests);
|
qemu_co_queue_init(&(*m)->dependent_requests);
|
||||||
QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
|
QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
|
||||||
|
|
||||||
*host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset);
|
*host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset);
|
||||||
*bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE)
|
*bytes = MIN(*bytes, nb_bytes - offset_into_cluster(s, guest_offset));
|
||||||
- offset_into_cluster(s, guest_offset));
|
|
||||||
assert(*bytes != 0);
|
assert(*bytes != 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -302,8 +302,8 @@ typedef struct Qcow2COWRegion {
|
|||||||
*/
|
*/
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
|
|
||||||
/** Number of sectors to copy */
|
/** Number of bytes to copy */
|
||||||
int nb_sectors;
|
int nb_bytes;
|
||||||
} Qcow2COWRegion;
|
} Qcow2COWRegion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -318,12 +318,6 @@ typedef struct QCowL2Meta
|
|||||||
/** Host offset of the first newly allocated cluster */
|
/** Host offset of the first newly allocated cluster */
|
||||||
uint64_t alloc_offset;
|
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 */
|
/** Number of newly allocated clusters */
|
||||||
int nb_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)
|
static inline uint64_t l2meta_cow_end(QCowL2Meta *m)
|
||||||
{
|
{
|
||||||
return m->offset + m->cow_end.offset
|
return m->offset + m->cow_end.offset + m->cow_end.nb_bytes;
|
||||||
+ (m->cow_end.nb_sectors << BDRV_SECTOR_BITS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2)
|
static inline uint64_t refcount_diff(uint64_t r1, uint64_t r2)
|
||||||
|
Loading…
Reference in New Issue
Block a user