/* SPDX-License-Identifier: MIT */ /* * Description: test a mem leak with IOPOLL */ #include #include #include #include #include #include #include #include #include "helpers.h" #include "liburing.h" #define FILE_SIZE (128 * 1024) #define BS 4096 #define BUFFERS (FILE_SIZE / BS) static int do_iopoll(const char *fname) { struct io_uring_sqe *sqe; struct io_uring ring; struct iovec *iov; int fd; fd = open(fname, O_RDONLY | O_DIRECT); if (fd < 0) { if (errno == EINVAL || errno == EPERM || errno == EACCES) return T_EXIT_SKIP; perror("open"); return T_EXIT_SKIP; } iov = t_create_buffers(1, 4096); t_create_ring(2, &ring, IORING_SETUP_IOPOLL); sqe = io_uring_get_sqe(&ring); io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0); io_uring_submit(&ring); close(fd); free(iov->iov_base); free(iov); return T_EXIT_PASS; } static int test(const char *fname) { if (fork()) { int stat; wait(&stat); return WEXITSTATUS(stat); } else { int ret; ret = do_iopoll(fname); exit(ret); } } int main(int argc, char *argv[]) { char buf[256]; char *fname; int i, ret; if (argc > 1) { fname = argv[1]; } else { srand((unsigned)time(NULL)); snprintf(buf, sizeof(buf), ".iopoll-leak-%u-%u", (unsigned)rand(), (unsigned)getpid()); fname = buf; t_create_file(fname, FILE_SIZE); } for (i = 0; i < 16; i++) { ret = test(fname); if (ret == T_EXIT_SKIP || ret == T_EXIT_FAIL) break; } if (fname != argv[1]) unlink(fname); return ret; }