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