1 #define _LARGEFILE_SOURCE
2 #define _FILE_OFFSET_BITS 64
3
4 #include <liburing.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <sys/resource.h>
13 #include <unistd.h>
14
15 static const int RSIZE = 2;
16 static const int OPEN_FLAGS = O_RDWR | O_CREAT;
17 static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
18
19 #define DIE(...) do {\
20 fprintf(stderr, __VA_ARGS__);\
21 abort();\
22 } while(0);
23
do_write(struct io_uring * ring,int fd,off_t offset)24 static int do_write(struct io_uring *ring, int fd, off_t offset)
25 {
26 char buf[] = "some test write buf";
27 struct io_uring_sqe *sqe;
28 struct io_uring_cqe *cqe;
29 int res, ret;
30
31 sqe = io_uring_get_sqe(ring);
32 if (!sqe) {
33 fprintf(stderr, "failed to get sqe\n");
34 return 1;
35 }
36 io_uring_prep_write(sqe, fd, buf, sizeof(buf), offset);
37
38 ret = io_uring_submit(ring);
39 if (ret < 0) {
40 fprintf(stderr, "failed to submit write: %s\n", strerror(-ret));
41 return 1;
42 }
43
44 ret = io_uring_wait_cqe(ring, &cqe);
45 if (ret < 0) {
46 fprintf(stderr, "wait_cqe failed: %s\n", strerror(-ret));
47 return 1;
48 }
49
50 res = cqe->res;
51 io_uring_cqe_seen(ring, cqe);
52 if (res < 0) {
53 fprintf(stderr, "write failed: %s\n", strerror(-res));
54 return 1;
55 }
56
57 return 0;
58 }
59
test_open_write(struct io_uring * ring,int dfd,const char * fn)60 static int test_open_write(struct io_uring *ring, int dfd, const char *fn)
61 {
62 struct io_uring_sqe *sqe;
63 struct io_uring_cqe *cqe;
64 int ret, fd = -1;
65
66 sqe = io_uring_get_sqe(ring);
67 if (!sqe) {
68 fprintf(stderr, "failed to get sqe\n");
69 return 1;
70 }
71 io_uring_prep_openat(sqe, dfd, fn, OPEN_FLAGS, OPEN_MODE);
72
73 ret = io_uring_submit(ring);
74 if (ret < 0) {
75 fprintf(stderr, "failed to submit openat: %s\n", strerror(-ret));
76 return 1;
77 }
78
79 ret = io_uring_wait_cqe(ring, &cqe);
80 if (ret < 0) {
81 fprintf(stderr, "wait_cqe failed: %s\n", strerror(-ret));
82 return 1;
83 }
84
85 fd = cqe->res;
86 io_uring_cqe_seen(ring, cqe);
87 if (fd < 0) {
88 fprintf(stderr, "openat failed: %s\n", strerror(-fd));
89 return 1;
90 }
91
92 return do_write(ring, fd, 1ULL << 32);
93 }
94
main(int argc,char * argv[])95 int main(int argc, char *argv[])
96 {
97 struct io_uring ring;
98 int dfd, ret;
99
100 if (argc > 1)
101 return 0;
102
103 dfd = open("/tmp", O_RDONLY | O_DIRECTORY);
104 if (dfd < 0)
105 DIE("open /tmp: %s\n", strerror(errno));
106
107 ret = io_uring_queue_init(RSIZE, &ring, 0);
108 if (ret < 0)
109 DIE("failed to init io_uring: %s\n", strerror(-ret));
110
111 ret = test_open_write(&ring, dfd, "io_uring_openat_write_test1");
112
113 io_uring_queue_exit(&ring);
114 close(dfd);
115 unlink("/tmp/io_uring_openat_write_test1");
116 return ret;
117 }
118