linux-aio: Put all parameters into qemu_laiocb
Put all request parameters into the qemu_laiocb struct, which will allow re-submitting the tail of short reads/writes. Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Hanna Czenczek <hreitz@redhat.com> Message-ID: <20260324084338.37453-2-hreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
committed by
Kevin Wolf
parent
51fc8443c1
commit
cc03b62df4
@@ -41,9 +41,15 @@ struct qemu_laiocb {
|
||||
LinuxAioState *ctx;
|
||||
struct iocb iocb;
|
||||
ssize_t ret;
|
||||
off_t offset;
|
||||
size_t nbytes;
|
||||
QEMUIOVector *qiov;
|
||||
bool is_read;
|
||||
|
||||
int fd;
|
||||
int type;
|
||||
BdrvRequestFlags flags;
|
||||
|
||||
uint64_t dev_max_batch;
|
||||
QSIMPLEQ_ENTRY(qemu_laiocb) next;
|
||||
};
|
||||
|
||||
@@ -87,7 +93,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
|
||||
ret = 0;
|
||||
} else if (ret >= 0) {
|
||||
/* Short reads mean EOF, pad with zeros. */
|
||||
if (laiocb->is_read) {
|
||||
if (laiocb->type == QEMU_AIO_READ) {
|
||||
qemu_iovec_memset(laiocb->qiov, ret, 0,
|
||||
laiocb->qiov->size - ret);
|
||||
} else {
|
||||
@@ -367,23 +373,23 @@ static void laio_deferred_fn(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||
int type, BdrvRequestFlags flags,
|
||||
uint64_t dev_max_batch)
|
||||
static int laio_do_submit(struct qemu_laiocb *laiocb)
|
||||
{
|
||||
LinuxAioState *s = laiocb->ctx;
|
||||
struct iocb *iocbs = &laiocb->iocb;
|
||||
QEMUIOVector *qiov = laiocb->qiov;
|
||||
int fd = laiocb->fd;
|
||||
off_t offset = laiocb->offset;
|
||||
|
||||
switch (type) {
|
||||
switch (laiocb->type) {
|
||||
case QEMU_AIO_WRITE:
|
||||
#ifdef HAVE_IO_PREP_PWRITEV2
|
||||
{
|
||||
int laio_flags = (flags & BDRV_REQ_FUA) ? RWF_DSYNC : 0;
|
||||
int laio_flags = (laiocb->flags & BDRV_REQ_FUA) ? RWF_DSYNC : 0;
|
||||
io_prep_pwritev2(iocbs, fd, qiov->iov, qiov->niov, offset, laio_flags);
|
||||
}
|
||||
#else
|
||||
assert(flags == 0);
|
||||
assert(laiocb->flags == 0);
|
||||
io_prep_pwritev(iocbs, fd, qiov->iov, qiov->niov, offset);
|
||||
#endif
|
||||
break;
|
||||
@@ -399,7 +405,7 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||
/* Currently Linux kernel does not support other operations */
|
||||
default:
|
||||
fprintf(stderr, "%s: invalid AIO request type 0x%x.\n",
|
||||
__func__, type);
|
||||
__func__, laiocb->type);
|
||||
return -EIO;
|
||||
}
|
||||
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
|
||||
@@ -407,7 +413,7 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
|
||||
QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
|
||||
s->io_q.in_queue++;
|
||||
if (!s->io_q.blocked) {
|
||||
if (s->io_q.in_queue >= laio_max_batch(s, dev_max_batch)) {
|
||||
if (s->io_q.in_queue >= laio_max_batch(s, laiocb->dev_max_batch)) {
|
||||
ioq_submit(s);
|
||||
} else {
|
||||
defer_call(laio_deferred_fn, s);
|
||||
@@ -425,14 +431,18 @@ int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov,
|
||||
AioContext *ctx = qemu_get_current_aio_context();
|
||||
struct qemu_laiocb laiocb = {
|
||||
.co = qemu_coroutine_self(),
|
||||
.offset = offset,
|
||||
.nbytes = qiov ? qiov->size : 0,
|
||||
.ctx = aio_get_linux_aio(ctx),
|
||||
.ret = -EINPROGRESS,
|
||||
.is_read = (type == QEMU_AIO_READ),
|
||||
.qiov = qiov,
|
||||
.fd = fd,
|
||||
.type = type,
|
||||
.flags = flags,
|
||||
.dev_max_batch = dev_max_batch,
|
||||
};
|
||||
|
||||
ret = laio_do_submit(fd, &laiocb, offset, type, flags, dev_max_batch);
|
||||
ret = laio_do_submit(&laiocb);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user