From eb06dcfde747e46bd08bedf9def2e6cb536c39e3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 May 2020 15:33:53 +0200 Subject: [PATCH] TODO!!! test/implicit-rwf_nowait.c Once this proves the problem, we need a more detailed commit message... --- test/Makefile | 4 +- test/implicit-rwf_nowait.c | 162 +++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 test/implicit-rwf_nowait.c diff --git a/test/Makefile b/test/Makefile index ff4d4b8ec04a..50a75588aca7 100644 --- a/test/Makefile +++ b/test/Makefile @@ -21,7 +21,7 @@ all_targets += poll poll-cancel ring-leak fsync io_uring_setup io_uring_register file-update accept-reuse poll-v-poll fadvise madvise \ short-read openat2 probe shared-wq personality eventfd \ send_recv eventfd-ring across-fork sq-poll-kthread splice \ - lfs-openat lfs-openat-write + lfs-openat lfs-openat-write implicit-rwf_nowait include ../Makefile.quiet @@ -53,7 +53,7 @@ test_srcs := poll.c poll-cancel.c ring-leak.c fsync.c io_uring_setup.c \ file-update.c accept-reuse.c poll-v-poll.c fadvise.c \ madvise.c short-read.c openat2.c probe.c shared-wq.c \ personality.c eventfd.c eventfd-ring.c across-fork.c sq-poll-kthread.c \ - splice.c lfs-openat.c lfs-openat-write.c + splice.c lfs-openat.c lfs-openat-write.c implicit-rwf-nowait.c ifdef CONFIG_HAVE_STATX test_srcs += statx.c diff --git a/test/implicit-rwf_nowait.c b/test/implicit-rwf_nowait.c new file mode 100644 index 000000000000..581df209d295 --- /dev/null +++ b/test/implicit-rwf_nowait.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Description: Implicit RWF_NOWAIT bug + * + */ +#include +#include +#include +#include +#include +#include + +#include "liburing.h" + +#define BLOCK 4096 + +#ifndef RWF_NOWAIT +#define RWF_NOWAIT 8 +#endif + +static int get_file_fd(void) +{ + ssize_t ret; + char *buf; + int fd; + + fd = open("testfile", O_RDWR | O_CREAT, 0644); + if (fd < 0) { + perror("open file"); + return -1; + } + + buf = malloc(BLOCK); + memset(buf, 0xff, BLOCK); + ret = pwrite(fd, buf, BLOCK, 0); + if (ret != BLOCK) { + if (ret < 0) + perror("write"); + else + printf("Short write\n"); + goto err; + } + ret = pwrite(fd, buf, BLOCK, BLOCK); + if (ret != BLOCK) { + if (ret < 0) + perror("write"); + else + printf("Short write\n"); + goto err; + } + fsync(fd); + + if (posix_fadvise(fd, BLOCK, BLOCK, POSIX_FADV_DONTNEED)) { + perror("fadvise"); +err: + close(fd); + free(buf); + return -1; + } + + free(buf); + return fd; +} + +static void put_file_fd(int fd) +{ + close(fd); + unlink("testfile"); +} + +int main(int argc, char *argv[]) +{ + struct io_uring ring; + struct io_uring_sqe *sqe; + struct io_uring_cqe *cqe; + struct iovec iov; + int ret, fd; + + iov.iov_base = malloc(2*BLOCK); + iov.iov_len = BLOCK; + + ret = io_uring_queue_init(1, &ring, 0); + if (ret) { + printf("ring setup failed\n"); + return 1; + + } + + sqe = io_uring_get_sqe(&ring); + if (!sqe) { + printf("get sqe failed\n"); + return 1; + } + + fd = get_file_fd(); + if (fd < 0) + return 1; + + io_uring_prep_readv(sqe, fd, &iov, 1, 0); + io_uring_sqe_set_data(sqe, (void *)(uintptr_t)0x11111111); + ret = io_uring_submit(&ring); + if (ret != 1) { + printf("Got submit %d, expected 1\n", ret); + goto err; + } + + ret = io_uring_wait_cqe(&ring, &cqe); + if (ret) { + printf("Ring wait got %d\n", ret); + goto err; + } + ret = (uintptr_t)io_uring_cqe_get_data(cqe); + if (ret != 0x11111111) { + printf("Got invalid data 0x%08x, expected 0x11111111\n", ret); + goto err; + } + io_uring_cq_advance(&ring, 1); + + if (cqe->res != BLOCK) { + printf("cqe res=%d != %u\n", cqe->res, BLOCK); + goto err; + } + + sqe = io_uring_get_sqe(&ring); + if (!sqe) { + printf("get sqe failed\n"); + return 1; + } + + iov.iov_len = 2*BLOCK; + io_uring_prep_readv(sqe, fd, &iov, 1, 0); + // Impliet by broken kernels? sqe->rw_flags = RWF_NOWAIT; + io_uring_sqe_set_data(sqe, (void *)(uintptr_t)0x22222222); + ret = io_uring_submit(&ring); + if (ret != 1) { + printf("Got submit %d, expected 1\n", ret); + goto err; + } + + ret = io_uring_wait_cqe(&ring, &cqe); + if (ret) { + printf("Ring peek got %d\n", ret); + goto err; + } + ret = (uintptr_t)io_uring_cqe_get_data(cqe); + if (ret != 0x22222222) { + printf("Got invalid data 0x%08x, expected 0x22222222\n", ret); + goto err; + } + io_uring_cq_advance(&ring, 1); + + if (cqe->res != 2*BLOCK) { + printf("cqe res=%d != %u\n", cqe->res, 2*BLOCK); + goto err; + } + + put_file_fd(fd); + return 0; +err: + put_file_fd(fd); + return 1; +} -- 2.17.1