mirror of https://github.com/proxmox/mirror_qemu
qcow/qcow2: Allocate QCowAIOCB structure using stack
instead of calling qemi_aio_get use stack Signed-off-by: Frediano Ziglio <freddy77@gmail.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>master
parent
e4ea78ee76
commit
f5cd8173e7
52
block/qcow.c
52
block/qcow.c
|
@ -505,28 +505,12 @@ typedef struct QCowAIOCB {
|
||||||
BlockDriverAIOCB *hd_aiocb;
|
BlockDriverAIOCB *hd_aiocb;
|
||||||
} QCowAIOCB;
|
} QCowAIOCB;
|
||||||
|
|
||||||
static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
|
|
||||||
{
|
|
||||||
QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
|
|
||||||
if (acb->hd_aiocb)
|
|
||||||
bdrv_aio_cancel(acb->hd_aiocb);
|
|
||||||
qemu_aio_release(acb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static AIOPool qcow_aio_pool = {
|
|
||||||
.aiocb_size = sizeof(QCowAIOCB),
|
|
||||||
.cancel = qcow_aio_cancel,
|
|
||||||
};
|
|
||||||
|
|
||||||
static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
|
static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
|
||||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||||
int is_write)
|
int is_write, QCowAIOCB *acb)
|
||||||
{
|
{
|
||||||
QCowAIOCB *acb;
|
memset(acb, 0, sizeof(*acb));
|
||||||
|
acb->common.bs = bs;
|
||||||
acb = qemu_aio_get(&qcow_aio_pool, bs, NULL, NULL);
|
|
||||||
if (!acb)
|
|
||||||
return NULL;
|
|
||||||
acb->hd_aiocb = NULL;
|
acb->hd_aiocb = NULL;
|
||||||
acb->sector_num = sector_num;
|
acb->sector_num = sector_num;
|
||||||
acb->qiov = qiov;
|
acb->qiov = qiov;
|
||||||
|
@ -545,9 +529,8 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
|
||||||
return acb;
|
return acb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_aio_read_cb(void *opaque)
|
static int qcow_aio_read_cb(QCowAIOCB *acb)
|
||||||
{
|
{
|
||||||
QCowAIOCB *acb = opaque;
|
|
||||||
BlockDriverState *bs = acb->common.bs;
|
BlockDriverState *bs = acb->common.bs;
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int index_in_cluster;
|
int index_in_cluster;
|
||||||
|
@ -636,29 +619,27 @@ static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, QEMUIOVector *qiov)
|
int nb_sectors, QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
QCowAIOCB *acb;
|
QCowAIOCB acb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
|
qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0, &acb);
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
do {
|
do {
|
||||||
ret = qcow_aio_read_cb(acb);
|
ret = qcow_aio_read_cb(&acb);
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
if (acb->qiov->niov > 1) {
|
if (acb.qiov->niov > 1) {
|
||||||
qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
|
qemu_iovec_from_buffer(acb.qiov, acb.orig_buf, acb.qiov->size);
|
||||||
qemu_vfree(acb->orig_buf);
|
qemu_vfree(acb.orig_buf);
|
||||||
}
|
}
|
||||||
qemu_aio_release(acb);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_aio_write_cb(void *opaque)
|
static int qcow_aio_write_cb(QCowAIOCB *acb)
|
||||||
{
|
{
|
||||||
QCowAIOCB *acb = opaque;
|
|
||||||
BlockDriverState *bs = acb->common.bs;
|
BlockDriverState *bs = acb->common.bs;
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int index_in_cluster;
|
int index_in_cluster;
|
||||||
|
@ -716,23 +697,22 @@ static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, QEMUIOVector *qiov)
|
int nb_sectors, QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
QCowAIOCB *acb;
|
QCowAIOCB acb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
s->cluster_cache_offset = -1; /* disable compressed cache */
|
s->cluster_cache_offset = -1; /* disable compressed cache */
|
||||||
|
|
||||||
acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
|
qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1, &acb);
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
do {
|
do {
|
||||||
ret = qcow_aio_write_cb(acb);
|
ret = qcow_aio_write_cb(&acb);
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
if (acb->qiov->niov > 1) {
|
if (acb.qiov->niov > 1) {
|
||||||
qemu_vfree(acb->orig_buf);
|
qemu_vfree(acb.orig_buf);
|
||||||
}
|
}
|
||||||
qemu_aio_release(acb);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,17 +392,6 @@ typedef struct QCowAIOCB {
|
||||||
QLIST_ENTRY(QCowAIOCB) next_depend;
|
QLIST_ENTRY(QCowAIOCB) next_depend;
|
||||||
} QCowAIOCB;
|
} QCowAIOCB;
|
||||||
|
|
||||||
static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
|
|
||||||
{
|
|
||||||
QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
|
|
||||||
qemu_aio_release(acb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static AIOPool qcow2_aio_pool = {
|
|
||||||
.aiocb_size = sizeof(QCowAIOCB),
|
|
||||||
.cancel = qcow2_aio_cancel,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns 0 when the request is completed successfully, 1 when there is still
|
* Returns 0 when the request is completed successfully, 1 when there is still
|
||||||
* a part left to do and -errno in error cases.
|
* a part left to do and -errno in error cases.
|
||||||
|
@ -532,13 +521,10 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
|
||||||
static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
|
static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
|
||||||
QEMUIOVector *qiov, int nb_sectors,
|
QEMUIOVector *qiov, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb,
|
BlockDriverCompletionFunc *cb,
|
||||||
void *opaque, int is_write)
|
void *opaque, int is_write, QCowAIOCB *acb)
|
||||||
{
|
{
|
||||||
QCowAIOCB *acb;
|
memset(acb, 0, sizeof(*acb));
|
||||||
|
acb->common.bs = bs;
|
||||||
acb = qemu_aio_get(&qcow2_aio_pool, bs, cb, opaque);
|
|
||||||
if (!acb)
|
|
||||||
return NULL;
|
|
||||||
acb->sector_num = sector_num;
|
acb->sector_num = sector_num;
|
||||||
acb->qiov = qiov;
|
acb->qiov = qiov;
|
||||||
acb->is_write = is_write;
|
acb->is_write = is_write;
|
||||||
|
@ -558,19 +544,18 @@ static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
|
||||||
int nb_sectors, QEMUIOVector *qiov)
|
int nb_sectors, QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
QCowAIOCB *acb;
|
QCowAIOCB acb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0);
|
qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0, &acb);
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
do {
|
do {
|
||||||
ret = qcow2_aio_read_cb(acb);
|
ret = qcow2_aio_read_cb(&acb);
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
qemu_iovec_destroy(&acb->hd_qiov);
|
qemu_iovec_destroy(&acb.hd_qiov);
|
||||||
qemu_aio_release(acb);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -674,20 +659,19 @@ static int qcow2_co_writev(BlockDriverState *bs,
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
QCowAIOCB *acb;
|
QCowAIOCB acb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1);
|
qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1, &acb);
|
||||||
s->cluster_cache_offset = -1; /* disable compressed cache */
|
s->cluster_cache_offset = -1; /* disable compressed cache */
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
do {
|
do {
|
||||||
ret = qcow2_aio_write_cb(acb);
|
ret = qcow2_aio_write_cb(&acb);
|
||||||
} while (ret > 0);
|
} while (ret > 0);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
qemu_iovec_destroy(&acb->hd_qiov);
|
qemu_iovec_destroy(&acb.hd_qiov);
|
||||||
qemu_aio_release(acb);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue