Skip to content

Commit

Permalink
qcow2: Use bytes instead of sectors for QCowL2Meta
Browse files Browse the repository at this point in the history
In preparation for implementing .bdrv_co_pwritev in qcow2.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
  • Loading branch information
kevmw committed Jun 16, 2016
1 parent aaa4d20 commit 8556739
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 30 deletions.
32 changes: 12 additions & 20 deletions block/qcow2-cluster.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand Down
13 changes: 3 additions & 10 deletions block/qcow2.h
Expand Up @@ -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;

/**
Expand All @@ -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;

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 8556739

Please sign in to comment.