1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Description: Single depth submit+wait poll hang test
4 *
5 */
6 #include <errno.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <fcntl.h>
12
13 #include "helpers.h"
14 #include "liburing.h"
15
16 #define BLOCKS 4096
17
main(int argc,char * argv[])18 int main(int argc, char *argv[])
19 {
20 struct io_uring ring;
21 struct io_uring_sqe *sqe;
22 struct io_uring_cqe *cqe;
23 struct iovec iov;
24 char buf[32];
25 off_t offset;
26 unsigned blocks;
27 int ret, fd;
28
29 if (argc > 1)
30 return T_EXIT_SKIP;
31
32 t_posix_memalign(&iov.iov_base, 4096, 4096);
33 iov.iov_len = 4096;
34
35 ret = io_uring_queue_init(1, &ring, IORING_SETUP_IOPOLL);
36 if (ret) {
37 fprintf(stderr, "ring setup failed\n");
38 return T_EXIT_FAIL;
39
40 }
41
42 sprintf(buf, "./XXXXXX");
43 fd = mkostemp(buf, O_WRONLY | O_DIRECT | O_CREAT);
44 if (fd < 0) {
45 if (errno == EINVAL)
46 return T_EXIT_SKIP;
47 perror("mkostemp");
48 return T_EXIT_FAIL;
49 }
50
51 offset = 0;
52 blocks = BLOCKS;
53 do {
54 sqe = io_uring_get_sqe(&ring);
55 if (!sqe) {
56 fprintf(stderr, "get sqe failed\n");
57 goto err;
58 }
59 io_uring_prep_writev(sqe, fd, &iov, 1, offset);
60 ret = io_uring_submit_and_wait(&ring, 1);
61 if (ret < 0) {
62 fprintf(stderr, "submit_and_wait: %d\n", ret);
63 goto err;
64 }
65 ret = io_uring_wait_cqe(&ring, &cqe);
66 if (ret < 0) {
67 fprintf(stderr, "wait completion: %d\n", ret);
68 goto err;
69 }
70 if (cqe->res != 4096) {
71 if (cqe->res == -EOPNOTSUPP)
72 goto skipped;
73 goto err;
74 }
75 io_uring_cqe_seen(&ring, cqe);
76 offset += 4096;
77 } while (--blocks);
78
79 close(fd);
80 unlink(buf);
81 free(iov.iov_base);
82 return T_EXIT_PASS;
83 err:
84 close(fd);
85 unlink(buf);
86 free(iov.iov_base);
87 return T_EXIT_FAIL;
88 skipped:
89 fprintf(stderr, "Polling not supported in current dir, test skipped\n");
90 close(fd);
91 unlink(buf);
92 return T_EXIT_SKIP;
93 }
94