From: Andres Freund Date: Fri, 13 Sep 2019 19:10:10 +0000 (-0700) Subject: engines/io_uring: Fully clear out previous SQE contents. X-Git-Tag: fio-3.16~2^2 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=34d6090ea96ddaa4e2a0f914939e2b8ff7008bec;ds=sidebyside engines/io_uring: Fully clear out previous SQE contents. Without this change SQEs can contain data set in previous submissions. E.g. a WRITE following an fdatasync would have still have IORING_FSYNC_DATASYNC set in sync_flags, which shares storage with the WRITE's rw_flags. Which was not reset, causing all writes to be synchronous. Similarly, an fsync following a READ/WRITE would not reset off/addr/len, which causes errors, because the kernel's io_prep_fsync returns an error if e.g. addr is not 0. While this could also be fixed by resetting only the unused fields in the respective branches, it seems less failure prone to start with a zeroed out sqe. --- diff --git a/engines/io_uring.c b/engines/io_uring.c index 53cb60c5..e5edfcd2 100644 --- a/engines/io_uring.c +++ b/engines/io_uring.c @@ -152,15 +152,16 @@ static int fio_ioring_prep(struct thread_data *td, struct io_u *io_u) struct io_uring_sqe *sqe; sqe = &ld->sqes[io_u->index]; + + /* zero out fields not used in this submission */ + memset(sqe, 0, sizeof(*sqe)); + if (o->registerfiles) { sqe->fd = f->engine_pos; sqe->flags = IOSQE_FIXED_FILE; } else { sqe->fd = f->fd; - sqe->flags = 0; } - sqe->ioprio = 0; - sqe->buf_index = 0; if (io_u->ddir == DDIR_READ || io_u->ddir == DDIR_WRITE) { if (o->fixedbufs) { @@ -187,7 +188,6 @@ static int fio_ioring_prep(struct thread_data *td, struct io_u *io_u) sqe->sync_range_flags = td->o.sync_file_range; sqe->opcode = IORING_OP_SYNC_FILE_RANGE; } else { - sqe->fsync_flags = 0; if (io_u->ddir == DDIR_DATASYNC) sqe->fsync_flags |= IORING_FSYNC_DATASYNC; sqe->opcode = IORING_OP_FSYNC;