diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-06-09 19:50:30 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-06-09 19:50:30 -0600 |
commit | 65c90e04ba67d2b19ec7bbb4d684a176fbb316c3 (patch) | |
tree | 003267c61f67d0bc7b710a378b43202252d09e33 /test | |
parent | 929fedfcb25df9f2dba553c4df7ec2950ac62fc4 (diff) | |
download | liburing-65c90e04ba67d2b19ec7bbb4d684a176fbb316c3.tar.gz liburing-65c90e04ba67d2b19ec7bbb4d684a176fbb316c3.tar.bz2 |
Add test/close-opath.c
This tests whether we can close an O_PATH opened fd. Test program
is an edited version of one from Clay Harris <bugs@claycon.org>, found
here:
https://claycon.org/software/io_uring/tests/close_opath.c
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile | 4 | ||||
-rw-r--r-- | test/close-opath.c | 122 |
2 files changed, 124 insertions, 2 deletions
diff --git a/test/Makefile b/test/Makefile index 7df550d..93e58f4 100644 --- a/test/Makefile +++ b/test/Makefile @@ -22,7 +22,7 @@ all_targets += poll poll-cancel ring-leak fsync io_uring_setup io_uring_register short-read openat2 probe shared-wq personality eventfd \ send_recv eventfd-ring across-fork sq-poll-kthread splice \ lfs-openat lfs-openat-write iopoll d4ae271dfaae-test \ - eventfd-disable + eventfd-disable close-opath include ../Makefile.quiet @@ -55,7 +55,7 @@ test_srcs := poll.c poll-cancel.c ring-leak.c fsync.c io_uring_setup.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 iopoll.c d4ae271dfaae-test.c \ - eventfd-disable.c + eventfd-disable.c close-opath.c ifdef CONFIG_HAVE_STATX test_srcs += statx.c diff --git a/test/close-opath.c b/test/close-opath.c new file mode 100644 index 0000000..884bda9 --- /dev/null +++ b/test/close-opath.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT + +#define _GNU_SOURCE 1 +#define _FILE_OFFSET_BITS 64 + +// Test program for io_uring IORING_OP_CLOSE with O_PATH file. +// Author: Clayton Harris <bugs@claycon.org>, 2020-06-07 + +// linux 5.6.14-300.fc32.x86_64 +// gcc 10.1.1-1.fc32 +// liburing.x86_64 0.5-1.fc32 + +// gcc -O2 -Wall -Wextra -std=c11 -o close_opath close_opath.c -luring +// ./close_opath testfilepath + +#include <errno.h> +#include <fcntl.h> +#include <liburing.h> +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +typedef struct +{ + const char *const flnames; + const int oflags; +} oflgs_t; + +static int test_io_uring_close(struct io_uring *ring, int fd) +{ + struct io_uring_sqe *sqe; + struct io_uring_cqe *cqe; + int ret; + + sqe = io_uring_get_sqe(ring); + if (!sqe) { + fprintf(stderr, "io_uring_get_sqe() failed\n"); + return -ENOENT; + } + + io_uring_prep_close(sqe, fd); + + ret = io_uring_submit(ring); + if (ret < 0) { + fprintf(stderr, "io_uring_submit() failed, errno %d: %s\n", + -ret, strerror(-ret)); + return ret; + } + + ret = io_uring_wait_cqe(ring, &cqe); + if (ret < 0) { + fprintf(stderr, "io_uring_wait_cqe() failed, errno %d: %s\n", + -ret, strerror(-ret)); + return ret; + } + + ret = cqe->res; + io_uring_cqe_seen(ring, cqe); + + if (ret < 0 && ret != -EOPNOTSUPP) { + fprintf(stderr, "io_uring close() failed, errno %d: %s\n", + -ret, strerror(-ret)); + return ret; + } + + return 0; +} + +static int open_file(const char *path, const oflgs_t *oflgs) +{ + int fd; + + fd = openat(AT_FDCWD, path, oflgs->oflags, 0); + if (fd < 0) { + int err = errno; + fprintf(stderr, "openat(%s, %s) failed, errno %d: %s\n", + path, oflgs->flnames, err, strerror(err)); + return -err; + } + + return fd; +} + +int main(int argc, char *argv[]) +{ + const char *fname = "."; + struct io_uring ring; + int ret, i; + static const oflgs_t oflgs[] = { + { "O_RDONLY", O_RDONLY }, + { "O_PATH", O_PATH } + }; + + ret = io_uring_queue_init(2, &ring, 0); + if (ret < 0) { + fprintf(stderr, "io_uring_queue_init() failed, errno %d: %s\n", + -ret, strerror(-ret)); + return 0x02; + } + +#define OFLGS_SIZE (sizeof(oflgs) / sizeof(oflgs[0])) + + ret = 0; + for (i = 0; i < OFLGS_SIZE; i++) { + int fd; + + fd = open_file(fname, &oflgs[i]); + if (fd < 0) { + ret |= 0x02; + break; + } + + /* Should always succeed */ + if (test_io_uring_close(&ring, fd) < 0) + ret |= 0x04 << i; + } +#undef OFLGS_SIZE + + io_uring_queue_exit(&ring); + return ret; +} |