提交 ddd2ef2c 编写于 作者: D Denis V. Lunev 提交者: Stefan Hajnoczi

block/parallels: improve image writing performance further

Try to perform IO for the biggest continuous block possible.
All blocks abscent in the image are accounted in the same type
and preallocation is made for all of them at once.

The performance for sequential write is increased from 200 Mb/sec to
235 Mb/sec on my SSD HDD.
Signed-off-by: NDenis V. Lunev <den@openvz.org>
Reviewed-by: NRoman Kagan <rkagan@parallels.com>
Signed-off-by: NRoman Kagan <rkagan@parallels.com>
Message-id: 1430207220-24458-28-git-send-email-den@openvz.org
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
上级 19f5dc15
......@@ -183,43 +183,47 @@ static int64_t block_status(BDRVParallelsState *s, int64_t sector_num,
return start_off;
}
static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num)
static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum)
{
BDRVParallelsState *s = bs->opaque;
uint32_t idx, offset;
int64_t pos;
uint32_t idx, to_allocate, i;
int64_t pos, space;
idx = sector_num / s->tracks;
offset = sector_num % s->tracks;
pos = block_status(s, sector_num, nb_sectors, pnum);
if (pos > 0) {
return pos;
}
idx = sector_num / s->tracks;
if (idx >= s->bat_size) {
return -EINVAL;
}
if (s->bat_bitmap[idx] != 0) {
return bat2sect(s, idx) + offset;
}
pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS;
if (s->data_end + s->tracks > pos) {
to_allocate = (sector_num + *pnum + s->tracks - 1) / s->tracks - idx;
space = to_allocate * s->tracks;
if (s->data_end + space > bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS) {
int ret;
space += s->prealloc_size;
if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
ret = bdrv_write_zeroes(bs->file, s->data_end,
s->prealloc_size, 0);
ret = bdrv_write_zeroes(bs->file, s->data_end, space, 0);
} else {
ret = bdrv_truncate(bs->file,
(s->data_end + s->prealloc_size) << BDRV_SECTOR_BITS);
(s->data_end + space) << BDRV_SECTOR_BITS);
}
if (ret < 0) {
return ret;
}
}
pos = s->data_end;
s->data_end += s->tracks;
s->bat_bitmap[idx] = cpu_to_le32(pos / s->off_multiplier);
for (i = 0; i < to_allocate; i++) {
s->bat_bitmap[idx + i] = cpu_to_le32(s->data_end / s->off_multiplier);
s->data_end += s->tracks;
bitmap_set(s->bat_dirty_bmap,
bat_entry_off(idx) / s->bat_dirty_block, 1);
}
bitmap_set(s->bat_dirty_bmap, bat_entry_off(idx) / s->bat_dirty_block, 1);
return bat2sect(s, idx) + offset;
return bat2sect(s, idx) + sector_num % s->tracks;
}
......@@ -287,14 +291,13 @@ static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
int n, nbytes;
qemu_co_mutex_lock(&s->lock);
position = allocate_cluster(bs, sector_num);
position = allocate_clusters(bs, sector_num, nb_sectors, &n);
qemu_co_mutex_unlock(&s->lock);
if (position < 0) {
ret = (int)position;
break;
}
n = cluster_remainder(s, sector_num, nb_sectors);
nbytes = n << BDRV_SECTOR_BITS;
qemu_iovec_reset(&hd_qiov);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册