@samitouri / QOSamiQemu / commits / cc03b62df4

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 }