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>
Hanna Czenczek committed
Mar 24, 2026 at 09:43 UTC
cc03b62df47a09c507e199cc043f57bdc941cc67
1 file changed
+22
-12
block/linux-aio.c
+22
-12
@@ -41,9 +41,15 @@ struct qemu_laiocb {
41
LinuxAioState *ctx;
42
struct iocb iocb;
43
ssize_t ret;
44
+ off_t offset;
45
size_t nbytes;
46
QEMUIOVector *qiov;
46
- bool is_read;
47
+
48
+ int fd;
49
+ int type;
50
+ BdrvRequestFlags flags;
51
+
52
+ uint64_t dev_max_batch;
53
QSIMPLEQ_ENTRY(qemu_laiocb) next;
54
};
55
@@ -87,7 +93,7 @@ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb)
93
ret = 0;
94
} else if (ret >= 0) {
95
/* Short reads mean EOF, pad with zeros. */
90
- if (laiocb->is_read) {
96
+ if (laiocb->type == QEMU_AIO_READ) {
97
qemu_iovec_memset(laiocb->qiov, ret, 0,
98
laiocb->qiov->size - ret);
99
} else {
@@ -367,23 +373,23 @@ static void laio_deferred_fn(void *opaque)
373
}
374
}
375
370
-static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
371
- int type, BdrvRequestFlags flags,
372
- uint64_t dev_max_batch)
376
+static int laio_do_submit(struct qemu_laiocb *laiocb)
377
{
378
LinuxAioState *s = laiocb->ctx;
379
struct iocb *iocbs = &laiocb->iocb;
380
QEMUIOVector *qiov = laiocb->qiov;
381
+ int fd = laiocb->fd;
382
+ off_t offset = laiocb->offset;
383
378
- switch (type) {
384
+ switch (laiocb->type) {
385
case QEMU_AIO_WRITE:
386
#ifdef HAVE_IO_PREP_PWRITEV2
387
{
382
- int laio_flags = (flags & BDRV_REQ_FUA) ? RWF_DSYNC : 0;
388
+ int laio_flags = (laiocb->flags & BDRV_REQ_FUA) ? RWF_DSYNC : 0;
389
io_prep_pwritev2(iocbs, fd, qiov->iov, qiov->niov, offset, laio_flags);
390
}
391
#else
386
- assert(flags == 0);
392
+ assert(laiocb->flags == 0);
393
io_prep_pwritev(iocbs, fd, qiov->iov, qiov->niov, offset);
394
#endif
395
break;
@@ -399,7 +405,7 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset,
405
/* Currently Linux kernel does not support other operations */
406
default:
407
fprintf(stderr, "%s: invalid AIO request type 0x%x.\n",
402
- __func__, type);
408
+ __func__, laiocb->type);
409
return -EIO;
410
}
411
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,
413
QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
414
s->io_q.in_queue++;
415
if (!s->io_q.blocked) {
410
- if (s->io_q.in_queue >= laio_max_batch(s, dev_max_batch)) {
416
+ if (s->io_q.in_queue >= laio_max_batch(s, laiocb->dev_max_batch)) {
417
ioq_submit(s);
418
} else {
419
defer_call(laio_deferred_fn, s);
@@ -425,14 +431,18 @@ int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov,
431
AioContext *ctx = qemu_get_current_aio_context();
432
struct qemu_laiocb laiocb = {
433
.co = qemu_coroutine_self(),
434
+ .offset = offset,
435
.nbytes = qiov ? qiov->size : 0,
436
.ctx = aio_get_linux_aio(ctx),
437
.ret = -EINPROGRESS,
431
- .is_read = (type == QEMU_AIO_READ),
438
.qiov = qiov,
439
+ .fd = fd,
440
+ .type = type,
441
+ .flags = flags,
442
+ .dev_max_batch = dev_max_batch,
443
};
444
435
- ret = laio_do_submit(fd, &laiocb, offset, type, flags, dev_max_batch);
445
+ ret = laio_do_submit(&laiocb);
446
if (ret < 0) {
447
return ret;
448
}