X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=engines%2Flibaio.c;h=c2f47d8bc87aee1b2b76d117c1f8d7c2532ea35a;hb=95bcd815e5ce55d6cdd8eb83bda5ee411f37bdc9;hp=da43f18ce1571b7c729ceb35fce02ec1aae00e12;hpb=f8fe35e8c9e88dd681ea151251d75f6116a958b4;p=fio.git diff --git a/engines/libaio.c b/engines/libaio.c index da43f18c..c2f47d8b 100644 --- a/engines/libaio.c +++ b/engines/libaio.c @@ -18,6 +18,7 @@ struct libaio_data { io_context_t aio_ctx; struct io_event *aio_events; + struct io_u *sync_io_u; }; static int fio_libaio_prep(struct thread_data fio_unused *td, struct io_u *io_u) @@ -25,9 +26,9 @@ static int fio_libaio_prep(struct thread_data fio_unused *td, struct io_u *io_u) struct fio_file *f = io_u->file; if (io_u->ddir == DDIR_READ) - io_prep_pread(&io_u->iocb, f->fd, io_u->buf, io_u->buflen, io_u->offset); + io_prep_pread(&io_u->iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset); else if (io_u->ddir == DDIR_WRITE) - io_prep_pwrite(&io_u->iocb, f->fd, io_u->buf, io_u->buflen, io_u->offset); + io_prep_pwrite(&io_u->iocb, f->fd, io_u->xfer_buf, io_u->xfer_buflen, io_u->offset); else if (io_u->ddir == DDIR_SYNC) io_prep_fsync(&io_u->iocb, f->fd); else @@ -40,6 +41,13 @@ static struct io_u *fio_libaio_event(struct thread_data *td, int event) { struct libaio_data *ld = td->io_ops->data; + if (ld->sync_io_u) { + struct io_u *ret = ld->sync_io_u; + + ld->sync_io_u = NULL; + return ret; + } + return ev_to_iou(ld->aio_events + event); } @@ -49,6 +57,9 @@ static int fio_libaio_getevents(struct thread_data *td, int min, int max, struct libaio_data *ld = td->io_ops->data; long r; + if (ld->sync_io_u) + return 1; + do { r = io_getevents(ld->aio_ctx, min, max, ld->aio_events, t); if (r >= min) @@ -77,18 +88,34 @@ static int fio_libaio_queue(struct thread_data *td, struct io_u *io_u) do { ret = io_submit(ld->aio_ctx, 1, &iocb); if (ret == 1) - return 0; + break; else if (ret == -EAGAIN || !ret) usleep(100); else if (ret == -EINTR) continue; - else + else if (ret == -EINVAL && io_u->ddir == DDIR_SYNC) { + /* + * the async fsync doesn't currently seem to be + * supported, so just fsync if we fail with EINVAL + * for a sync. since buffered io is also sync + * with libaio (still), we don't have pending + * requests to flush first. + */ + if (fsync(io_u->file->fd) < 0) + ret = errno; + else { + ret = 1; + ld->sync_io_u = io_u; + } + break; + } else break; } while (1); if (ret <= 0) { - io_u->resid = io_u->buflen; + io_u->resid = io_u->xfer_buflen; io_u->error = -ret; + td_verror(td, io_u->error); return 1; }