mirror of https://github.com/proxmox/mirror_qemu
qed: Make qed_read_table() synchronous
Note that this code is generally not running in coroutine context, so this is an actual blocking synchronous operation. We'll fix this in a moment. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>master
parent
3b7cd9fd8f
commit
11273076e9
|
@ -18,59 +18,39 @@
|
||||||
#include "qed.h"
|
#include "qed.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
|
|
||||||
typedef struct {
|
static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
|
||||||
GenericCB gencb;
|
BlockCompletionFunc *cb, void *opaque)
|
||||||
BDRVQEDState *s;
|
|
||||||
QEDTable *table;
|
|
||||||
|
|
||||||
struct iovec iov;
|
|
||||||
QEMUIOVector qiov;
|
|
||||||
} QEDReadTableCB;
|
|
||||||
|
|
||||||
static void qed_read_table_cb(void *opaque, int ret)
|
|
||||||
{
|
{
|
||||||
QEDReadTableCB *read_table_cb = opaque;
|
QEMUIOVector qiov;
|
||||||
QEDTable *table = read_table_cb->table;
|
int noffsets;
|
||||||
BDRVQEDState *s = read_table_cb->s;
|
int i, ret;
|
||||||
int noffsets = read_table_cb->qiov.size / sizeof(uint64_t);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Handle I/O error */
|
struct iovec iov = {
|
||||||
if (ret) {
|
.iov_base = table->offsets,
|
||||||
|
.iov_len = s->header.cluster_size * s->header.table_size,
|
||||||
|
};
|
||||||
|
qemu_iovec_init_external(&qiov, &iov, 1);
|
||||||
|
|
||||||
|
trace_qed_read_table(s, offset, table);
|
||||||
|
|
||||||
|
ret = bdrv_preadv(s->bs->file, offset, &qiov);
|
||||||
|
if (ret < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Byteswap offsets */
|
/* Byteswap offsets */
|
||||||
qed_acquire(s);
|
qed_acquire(s);
|
||||||
|
noffsets = qiov.size / sizeof(uint64_t);
|
||||||
for (i = 0; i < noffsets; i++) {
|
for (i = 0; i < noffsets; i++) {
|
||||||
table->offsets[i] = le64_to_cpu(table->offsets[i]);
|
table->offsets[i] = le64_to_cpu(table->offsets[i]);
|
||||||
}
|
}
|
||||||
qed_release(s);
|
qed_release(s);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
/* Completion */
|
/* Completion */
|
||||||
trace_qed_read_table_cb(s, read_table_cb->table, ret);
|
trace_qed_read_table_cb(s, table, ret);
|
||||||
gencb_complete(&read_table_cb->gencb, ret);
|
cb(opaque, ret);
|
||||||
}
|
|
||||||
|
|
||||||
static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
|
|
||||||
BlockCompletionFunc *cb, void *opaque)
|
|
||||||
{
|
|
||||||
QEDReadTableCB *read_table_cb = gencb_alloc(sizeof(*read_table_cb),
|
|
||||||
cb, opaque);
|
|
||||||
QEMUIOVector *qiov = &read_table_cb->qiov;
|
|
||||||
|
|
||||||
trace_qed_read_table(s, offset, table);
|
|
||||||
|
|
||||||
read_table_cb->s = s;
|
|
||||||
read_table_cb->table = table;
|
|
||||||
read_table_cb->iov.iov_base = table->offsets,
|
|
||||||
read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size,
|
|
||||||
|
|
||||||
qemu_iovec_init_external(qiov, &read_table_cb->iov, 1);
|
|
||||||
bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov,
|
|
||||||
qiov->size / BDRV_SECTOR_SIZE,
|
|
||||||
qed_read_table_cb, read_table_cb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in New Issue