1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker * Description: run various linked sqe tests
4*25da2beaSAndroid Build Coastguard Worker *
5*25da2beaSAndroid Build Coastguard Worker */
6*25da2beaSAndroid Build Coastguard Worker #include <errno.h>
7*25da2beaSAndroid Build Coastguard Worker #include <stdio.h>
8*25da2beaSAndroid Build Coastguard Worker #include <unistd.h>
9*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
10*25da2beaSAndroid Build Coastguard Worker #include <string.h>
11*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
12*25da2beaSAndroid Build Coastguard Worker
13*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
14*25da2beaSAndroid Build Coastguard Worker
15*25da2beaSAndroid Build Coastguard Worker static int no_hardlink;
16*25da2beaSAndroid Build Coastguard Worker
17*25da2beaSAndroid Build Coastguard Worker /*
18*25da2beaSAndroid Build Coastguard Worker * Timer with single nop
19*25da2beaSAndroid Build Coastguard Worker */
test_single_hardlink(struct io_uring * ring)20*25da2beaSAndroid Build Coastguard Worker static int test_single_hardlink(struct io_uring *ring)
21*25da2beaSAndroid Build Coastguard Worker {
22*25da2beaSAndroid Build Coastguard Worker struct __kernel_timespec ts;
23*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
24*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
25*25da2beaSAndroid Build Coastguard Worker int ret, i;
26*25da2beaSAndroid Build Coastguard Worker
27*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
28*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
29*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "get sqe failed\n");
30*25da2beaSAndroid Build Coastguard Worker goto err;
31*25da2beaSAndroid Build Coastguard Worker }
32*25da2beaSAndroid Build Coastguard Worker ts.tv_sec = 0;
33*25da2beaSAndroid Build Coastguard Worker ts.tv_nsec = 10000000ULL;
34*25da2beaSAndroid Build Coastguard Worker io_uring_prep_timeout(sqe, &ts, 0, 0);
35*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK | IOSQE_IO_HARDLINK;
36*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 1;
37*25da2beaSAndroid Build Coastguard Worker
38*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
39*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
40*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "get sqe failed\n");
41*25da2beaSAndroid Build Coastguard Worker goto err;
42*25da2beaSAndroid Build Coastguard Worker }
43*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
44*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 2;
45*25da2beaSAndroid Build Coastguard Worker
46*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
47*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
48*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "sqe submit failed: %d\n", ret);
49*25da2beaSAndroid Build Coastguard Worker goto err;
50*25da2beaSAndroid Build Coastguard Worker }
51*25da2beaSAndroid Build Coastguard Worker
52*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
53*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
54*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
55*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "wait completion %d\n", ret);
56*25da2beaSAndroid Build Coastguard Worker goto err;
57*25da2beaSAndroid Build Coastguard Worker }
58*25da2beaSAndroid Build Coastguard Worker if (!cqe) {
59*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "failed to get cqe\n");
60*25da2beaSAndroid Build Coastguard Worker goto err;
61*25da2beaSAndroid Build Coastguard Worker }
62*25da2beaSAndroid Build Coastguard Worker if (no_hardlink)
63*25da2beaSAndroid Build Coastguard Worker goto next;
64*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 1 && cqe->res == -EINVAL) {
65*25da2beaSAndroid Build Coastguard Worker fprintf(stdout, "Hard links not supported, skipping\n");
66*25da2beaSAndroid Build Coastguard Worker no_hardlink = 1;
67*25da2beaSAndroid Build Coastguard Worker goto next;
68*25da2beaSAndroid Build Coastguard Worker }
69*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 1 && cqe->res != -ETIME) {
70*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "timeout failed with %d\n", cqe->res);
71*25da2beaSAndroid Build Coastguard Worker goto err;
72*25da2beaSAndroid Build Coastguard Worker }
73*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 2 && cqe->res) {
74*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "nop failed with %d\n", cqe->res);
75*25da2beaSAndroid Build Coastguard Worker goto err;
76*25da2beaSAndroid Build Coastguard Worker }
77*25da2beaSAndroid Build Coastguard Worker next:
78*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
79*25da2beaSAndroid Build Coastguard Worker }
80*25da2beaSAndroid Build Coastguard Worker
81*25da2beaSAndroid Build Coastguard Worker return 0;
82*25da2beaSAndroid Build Coastguard Worker err:
83*25da2beaSAndroid Build Coastguard Worker return 1;
84*25da2beaSAndroid Build Coastguard Worker }
85*25da2beaSAndroid Build Coastguard Worker
86*25da2beaSAndroid Build Coastguard Worker /*
87*25da2beaSAndroid Build Coastguard Worker * Timer -> timer -> nop
88*25da2beaSAndroid Build Coastguard Worker */
test_double_hardlink(struct io_uring * ring)89*25da2beaSAndroid Build Coastguard Worker static int test_double_hardlink(struct io_uring *ring)
90*25da2beaSAndroid Build Coastguard Worker {
91*25da2beaSAndroid Build Coastguard Worker struct __kernel_timespec ts1, ts2;
92*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
93*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
94*25da2beaSAndroid Build Coastguard Worker int ret, i;
95*25da2beaSAndroid Build Coastguard Worker
96*25da2beaSAndroid Build Coastguard Worker if (no_hardlink)
97*25da2beaSAndroid Build Coastguard Worker return 0;
98*25da2beaSAndroid Build Coastguard Worker
99*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
100*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
101*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "get sqe failed\n");
102*25da2beaSAndroid Build Coastguard Worker goto err;
103*25da2beaSAndroid Build Coastguard Worker }
104*25da2beaSAndroid Build Coastguard Worker ts1.tv_sec = 0;
105*25da2beaSAndroid Build Coastguard Worker ts1.tv_nsec = 10000000ULL;
106*25da2beaSAndroid Build Coastguard Worker io_uring_prep_timeout(sqe, &ts1, 0, 0);
107*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK | IOSQE_IO_HARDLINK;
108*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 1;
109*25da2beaSAndroid Build Coastguard Worker
110*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
111*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
112*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "get sqe failed\n");
113*25da2beaSAndroid Build Coastguard Worker goto err;
114*25da2beaSAndroid Build Coastguard Worker }
115*25da2beaSAndroid Build Coastguard Worker ts2.tv_sec = 0;
116*25da2beaSAndroid Build Coastguard Worker ts2.tv_nsec = 15000000ULL;
117*25da2beaSAndroid Build Coastguard Worker io_uring_prep_timeout(sqe, &ts2, 0, 0);
118*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK | IOSQE_IO_HARDLINK;
119*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 2;
120*25da2beaSAndroid Build Coastguard Worker
121*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
122*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
123*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "get sqe failed\n");
124*25da2beaSAndroid Build Coastguard Worker goto err;
125*25da2beaSAndroid Build Coastguard Worker }
126*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
127*25da2beaSAndroid Build Coastguard Worker sqe->user_data = 3;
128*25da2beaSAndroid Build Coastguard Worker
129*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
130*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
131*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "sqe submit failed: %d\n", ret);
132*25da2beaSAndroid Build Coastguard Worker goto err;
133*25da2beaSAndroid Build Coastguard Worker }
134*25da2beaSAndroid Build Coastguard Worker
135*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < 3; i++) {
136*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
137*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
138*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "wait completion %d\n", ret);
139*25da2beaSAndroid Build Coastguard Worker goto err;
140*25da2beaSAndroid Build Coastguard Worker }
141*25da2beaSAndroid Build Coastguard Worker if (!cqe) {
142*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "failed to get cqe\n");
143*25da2beaSAndroid Build Coastguard Worker goto err;
144*25da2beaSAndroid Build Coastguard Worker }
145*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 1 && cqe->res != -ETIME) {
146*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "timeout failed with %d\n", cqe->res);
147*25da2beaSAndroid Build Coastguard Worker goto err;
148*25da2beaSAndroid Build Coastguard Worker }
149*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 2 && cqe->res != -ETIME) {
150*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "timeout failed with %d\n", cqe->res);
151*25da2beaSAndroid Build Coastguard Worker goto err;
152*25da2beaSAndroid Build Coastguard Worker }
153*25da2beaSAndroid Build Coastguard Worker if (cqe->user_data == 3 && cqe->res) {
154*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "nop failed with %d\n", cqe->res);
155*25da2beaSAndroid Build Coastguard Worker goto err;
156*25da2beaSAndroid Build Coastguard Worker }
157*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
158*25da2beaSAndroid Build Coastguard Worker }
159*25da2beaSAndroid Build Coastguard Worker
160*25da2beaSAndroid Build Coastguard Worker return 0;
161*25da2beaSAndroid Build Coastguard Worker err:
162*25da2beaSAndroid Build Coastguard Worker return 1;
163*25da2beaSAndroid Build Coastguard Worker
164*25da2beaSAndroid Build Coastguard Worker }
165*25da2beaSAndroid Build Coastguard Worker
166*25da2beaSAndroid Build Coastguard Worker /*
167*25da2beaSAndroid Build Coastguard Worker * Test failing head of chain, and dependent getting -ECANCELED
168*25da2beaSAndroid Build Coastguard Worker */
test_single_link_fail(struct io_uring * ring)169*25da2beaSAndroid Build Coastguard Worker static int test_single_link_fail(struct io_uring *ring)
170*25da2beaSAndroid Build Coastguard Worker {
171*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
172*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
173*25da2beaSAndroid Build Coastguard Worker int ret, i;
174*25da2beaSAndroid Build Coastguard Worker
175*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
176*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
177*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
178*25da2beaSAndroid Build Coastguard Worker goto err;
179*25da2beaSAndroid Build Coastguard Worker }
180*25da2beaSAndroid Build Coastguard Worker
181*25da2beaSAndroid Build Coastguard Worker io_uring_prep_remove_buffers(sqe, 10, 1);
182*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
183*25da2beaSAndroid Build Coastguard Worker
184*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
185*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
186*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
187*25da2beaSAndroid Build Coastguard Worker goto err;
188*25da2beaSAndroid Build Coastguard Worker }
189*25da2beaSAndroid Build Coastguard Worker
190*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
191*25da2beaSAndroid Build Coastguard Worker
192*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
193*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
194*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
195*25da2beaSAndroid Build Coastguard Worker goto err;
196*25da2beaSAndroid Build Coastguard Worker }
197*25da2beaSAndroid Build Coastguard Worker
198*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
199*25da2beaSAndroid Build Coastguard Worker ret = io_uring_peek_cqe(ring, &cqe);
200*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
201*25da2beaSAndroid Build Coastguard Worker printf("wait completion %d\n", ret);
202*25da2beaSAndroid Build Coastguard Worker goto err;
203*25da2beaSAndroid Build Coastguard Worker }
204*25da2beaSAndroid Build Coastguard Worker if (!cqe) {
205*25da2beaSAndroid Build Coastguard Worker printf("failed to get cqe\n");
206*25da2beaSAndroid Build Coastguard Worker goto err;
207*25da2beaSAndroid Build Coastguard Worker }
208*25da2beaSAndroid Build Coastguard Worker if (i == 0 && cqe->res != -ENOENT) {
209*25da2beaSAndroid Build Coastguard Worker printf("sqe0 failed with %d, wanted -ENOENT\n", cqe->res);
210*25da2beaSAndroid Build Coastguard Worker goto err;
211*25da2beaSAndroid Build Coastguard Worker }
212*25da2beaSAndroid Build Coastguard Worker if (i == 1 && cqe->res != -ECANCELED) {
213*25da2beaSAndroid Build Coastguard Worker printf("sqe1 failed with %d, wanted -ECANCELED\n", cqe->res);
214*25da2beaSAndroid Build Coastguard Worker goto err;
215*25da2beaSAndroid Build Coastguard Worker }
216*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
217*25da2beaSAndroid Build Coastguard Worker }
218*25da2beaSAndroid Build Coastguard Worker
219*25da2beaSAndroid Build Coastguard Worker return 0;
220*25da2beaSAndroid Build Coastguard Worker err:
221*25da2beaSAndroid Build Coastguard Worker return 1;
222*25da2beaSAndroid Build Coastguard Worker }
223*25da2beaSAndroid Build Coastguard Worker
224*25da2beaSAndroid Build Coastguard Worker /*
225*25da2beaSAndroid Build Coastguard Worker * Test two independent chains
226*25da2beaSAndroid Build Coastguard Worker */
test_double_chain(struct io_uring * ring)227*25da2beaSAndroid Build Coastguard Worker static int test_double_chain(struct io_uring *ring)
228*25da2beaSAndroid Build Coastguard Worker {
229*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
230*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
231*25da2beaSAndroid Build Coastguard Worker int ret, i;
232*25da2beaSAndroid Build Coastguard Worker
233*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
234*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
235*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
236*25da2beaSAndroid Build Coastguard Worker goto err;
237*25da2beaSAndroid Build Coastguard Worker }
238*25da2beaSAndroid Build Coastguard Worker
239*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
240*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
241*25da2beaSAndroid Build Coastguard Worker
242*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
243*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
244*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
245*25da2beaSAndroid Build Coastguard Worker goto err;
246*25da2beaSAndroid Build Coastguard Worker }
247*25da2beaSAndroid Build Coastguard Worker
248*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
249*25da2beaSAndroid Build Coastguard Worker
250*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
251*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
252*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
253*25da2beaSAndroid Build Coastguard Worker goto err;
254*25da2beaSAndroid Build Coastguard Worker }
255*25da2beaSAndroid Build Coastguard Worker
256*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
257*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
258*25da2beaSAndroid Build Coastguard Worker
259*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
260*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
261*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
262*25da2beaSAndroid Build Coastguard Worker goto err;
263*25da2beaSAndroid Build Coastguard Worker }
264*25da2beaSAndroid Build Coastguard Worker
265*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
266*25da2beaSAndroid Build Coastguard Worker
267*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
268*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
269*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
270*25da2beaSAndroid Build Coastguard Worker goto err;
271*25da2beaSAndroid Build Coastguard Worker }
272*25da2beaSAndroid Build Coastguard Worker
273*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
274*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
275*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
276*25da2beaSAndroid Build Coastguard Worker printf("wait completion %d\n", ret);
277*25da2beaSAndroid Build Coastguard Worker goto err;
278*25da2beaSAndroid Build Coastguard Worker }
279*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
280*25da2beaSAndroid Build Coastguard Worker }
281*25da2beaSAndroid Build Coastguard Worker
282*25da2beaSAndroid Build Coastguard Worker return 0;
283*25da2beaSAndroid Build Coastguard Worker err:
284*25da2beaSAndroid Build Coastguard Worker return 1;
285*25da2beaSAndroid Build Coastguard Worker }
286*25da2beaSAndroid Build Coastguard Worker
287*25da2beaSAndroid Build Coastguard Worker /*
288*25da2beaSAndroid Build Coastguard Worker * Test multiple dependents
289*25da2beaSAndroid Build Coastguard Worker */
test_double_link(struct io_uring * ring)290*25da2beaSAndroid Build Coastguard Worker static int test_double_link(struct io_uring *ring)
291*25da2beaSAndroid Build Coastguard Worker {
292*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
293*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
294*25da2beaSAndroid Build Coastguard Worker int ret, i;
295*25da2beaSAndroid Build Coastguard Worker
296*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
297*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
298*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
299*25da2beaSAndroid Build Coastguard Worker goto err;
300*25da2beaSAndroid Build Coastguard Worker }
301*25da2beaSAndroid Build Coastguard Worker
302*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
303*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
304*25da2beaSAndroid Build Coastguard Worker
305*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
306*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
307*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
308*25da2beaSAndroid Build Coastguard Worker goto err;
309*25da2beaSAndroid Build Coastguard Worker }
310*25da2beaSAndroid Build Coastguard Worker
311*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
312*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
313*25da2beaSAndroid Build Coastguard Worker
314*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
315*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
316*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
317*25da2beaSAndroid Build Coastguard Worker goto err;
318*25da2beaSAndroid Build Coastguard Worker }
319*25da2beaSAndroid Build Coastguard Worker
320*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
321*25da2beaSAndroid Build Coastguard Worker
322*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
323*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
324*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
325*25da2beaSAndroid Build Coastguard Worker goto err;
326*25da2beaSAndroid Build Coastguard Worker }
327*25da2beaSAndroid Build Coastguard Worker
328*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < 3; i++) {
329*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
330*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
331*25da2beaSAndroid Build Coastguard Worker printf("wait completion %d\n", ret);
332*25da2beaSAndroid Build Coastguard Worker goto err;
333*25da2beaSAndroid Build Coastguard Worker }
334*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
335*25da2beaSAndroid Build Coastguard Worker }
336*25da2beaSAndroid Build Coastguard Worker
337*25da2beaSAndroid Build Coastguard Worker return 0;
338*25da2beaSAndroid Build Coastguard Worker err:
339*25da2beaSAndroid Build Coastguard Worker return 1;
340*25da2beaSAndroid Build Coastguard Worker }
341*25da2beaSAndroid Build Coastguard Worker
342*25da2beaSAndroid Build Coastguard Worker /*
343*25da2beaSAndroid Build Coastguard Worker * Test single dependency
344*25da2beaSAndroid Build Coastguard Worker */
test_single_link(struct io_uring * ring)345*25da2beaSAndroid Build Coastguard Worker static int test_single_link(struct io_uring *ring)
346*25da2beaSAndroid Build Coastguard Worker {
347*25da2beaSAndroid Build Coastguard Worker struct io_uring_cqe *cqe;
348*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
349*25da2beaSAndroid Build Coastguard Worker int ret, i;
350*25da2beaSAndroid Build Coastguard Worker
351*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
352*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
353*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
354*25da2beaSAndroid Build Coastguard Worker goto err;
355*25da2beaSAndroid Build Coastguard Worker }
356*25da2beaSAndroid Build Coastguard Worker
357*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
358*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
359*25da2beaSAndroid Build Coastguard Worker
360*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(ring);
361*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
362*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
363*25da2beaSAndroid Build Coastguard Worker goto err;
364*25da2beaSAndroid Build Coastguard Worker }
365*25da2beaSAndroid Build Coastguard Worker
366*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
367*25da2beaSAndroid Build Coastguard Worker
368*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit(ring);
369*25da2beaSAndroid Build Coastguard Worker if (ret <= 0) {
370*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
371*25da2beaSAndroid Build Coastguard Worker goto err;
372*25da2beaSAndroid Build Coastguard Worker }
373*25da2beaSAndroid Build Coastguard Worker
374*25da2beaSAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
375*25da2beaSAndroid Build Coastguard Worker ret = io_uring_wait_cqe(ring, &cqe);
376*25da2beaSAndroid Build Coastguard Worker if (ret < 0) {
377*25da2beaSAndroid Build Coastguard Worker printf("wait completion %d\n", ret);
378*25da2beaSAndroid Build Coastguard Worker goto err;
379*25da2beaSAndroid Build Coastguard Worker }
380*25da2beaSAndroid Build Coastguard Worker io_uring_cqe_seen(ring, cqe);
381*25da2beaSAndroid Build Coastguard Worker }
382*25da2beaSAndroid Build Coastguard Worker
383*25da2beaSAndroid Build Coastguard Worker return 0;
384*25da2beaSAndroid Build Coastguard Worker err:
385*25da2beaSAndroid Build Coastguard Worker return 1;
386*25da2beaSAndroid Build Coastguard Worker }
387*25da2beaSAndroid Build Coastguard Worker
test_early_fail_and_wait(void)388*25da2beaSAndroid Build Coastguard Worker static int test_early_fail_and_wait(void)
389*25da2beaSAndroid Build Coastguard Worker {
390*25da2beaSAndroid Build Coastguard Worker struct io_uring ring;
391*25da2beaSAndroid Build Coastguard Worker struct io_uring_sqe *sqe;
392*25da2beaSAndroid Build Coastguard Worker int ret, invalid_fd = 42;
393*25da2beaSAndroid Build Coastguard Worker struct iovec iov = { .iov_base = NULL, .iov_len = 0 };
394*25da2beaSAndroid Build Coastguard Worker
395*25da2beaSAndroid Build Coastguard Worker /* create a new ring as it leaves it dirty */
396*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(8, &ring, 0);
397*25da2beaSAndroid Build Coastguard Worker if (ret) {
398*25da2beaSAndroid Build Coastguard Worker printf("ring setup failed\n");
399*25da2beaSAndroid Build Coastguard Worker return 1;
400*25da2beaSAndroid Build Coastguard Worker }
401*25da2beaSAndroid Build Coastguard Worker
402*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&ring);
403*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
404*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
405*25da2beaSAndroid Build Coastguard Worker goto err;
406*25da2beaSAndroid Build Coastguard Worker }
407*25da2beaSAndroid Build Coastguard Worker
408*25da2beaSAndroid Build Coastguard Worker io_uring_prep_readv(sqe, invalid_fd, &iov, 1, 0);
409*25da2beaSAndroid Build Coastguard Worker sqe->flags |= IOSQE_IO_LINK;
410*25da2beaSAndroid Build Coastguard Worker
411*25da2beaSAndroid Build Coastguard Worker sqe = io_uring_get_sqe(&ring);
412*25da2beaSAndroid Build Coastguard Worker if (!sqe) {
413*25da2beaSAndroid Build Coastguard Worker printf("get sqe failed\n");
414*25da2beaSAndroid Build Coastguard Worker goto err;
415*25da2beaSAndroid Build Coastguard Worker }
416*25da2beaSAndroid Build Coastguard Worker
417*25da2beaSAndroid Build Coastguard Worker io_uring_prep_nop(sqe);
418*25da2beaSAndroid Build Coastguard Worker
419*25da2beaSAndroid Build Coastguard Worker ret = io_uring_submit_and_wait(&ring, 2);
420*25da2beaSAndroid Build Coastguard Worker if (ret <= 0 && ret != -EAGAIN) {
421*25da2beaSAndroid Build Coastguard Worker printf("sqe submit failed: %d\n", ret);
422*25da2beaSAndroid Build Coastguard Worker goto err;
423*25da2beaSAndroid Build Coastguard Worker }
424*25da2beaSAndroid Build Coastguard Worker
425*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&ring);
426*25da2beaSAndroid Build Coastguard Worker return 0;
427*25da2beaSAndroid Build Coastguard Worker err:
428*25da2beaSAndroid Build Coastguard Worker io_uring_queue_exit(&ring);
429*25da2beaSAndroid Build Coastguard Worker return 1;
430*25da2beaSAndroid Build Coastguard Worker }
431*25da2beaSAndroid Build Coastguard Worker
main(int argc,char * argv[])432*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
433*25da2beaSAndroid Build Coastguard Worker {
434*25da2beaSAndroid Build Coastguard Worker struct io_uring ring, poll_ring;
435*25da2beaSAndroid Build Coastguard Worker int ret;
436*25da2beaSAndroid Build Coastguard Worker
437*25da2beaSAndroid Build Coastguard Worker if (argc > 1)
438*25da2beaSAndroid Build Coastguard Worker return 0;
439*25da2beaSAndroid Build Coastguard Worker
440*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(8, &ring, 0);
441*25da2beaSAndroid Build Coastguard Worker if (ret) {
442*25da2beaSAndroid Build Coastguard Worker printf("ring setup failed\n");
443*25da2beaSAndroid Build Coastguard Worker return 1;
444*25da2beaSAndroid Build Coastguard Worker
445*25da2beaSAndroid Build Coastguard Worker }
446*25da2beaSAndroid Build Coastguard Worker
447*25da2beaSAndroid Build Coastguard Worker ret = io_uring_queue_init(8, &poll_ring, IORING_SETUP_IOPOLL);
448*25da2beaSAndroid Build Coastguard Worker if (ret) {
449*25da2beaSAndroid Build Coastguard Worker printf("poll_ring setup failed\n");
450*25da2beaSAndroid Build Coastguard Worker return 1;
451*25da2beaSAndroid Build Coastguard Worker }
452*25da2beaSAndroid Build Coastguard Worker
453*25da2beaSAndroid Build Coastguard Worker ret = test_single_link(&ring);
454*25da2beaSAndroid Build Coastguard Worker if (ret) {
455*25da2beaSAndroid Build Coastguard Worker printf("test_single_link failed\n");
456*25da2beaSAndroid Build Coastguard Worker return ret;
457*25da2beaSAndroid Build Coastguard Worker }
458*25da2beaSAndroid Build Coastguard Worker
459*25da2beaSAndroid Build Coastguard Worker ret = test_double_link(&ring);
460*25da2beaSAndroid Build Coastguard Worker if (ret) {
461*25da2beaSAndroid Build Coastguard Worker printf("test_double_link failed\n");
462*25da2beaSAndroid Build Coastguard Worker return ret;
463*25da2beaSAndroid Build Coastguard Worker }
464*25da2beaSAndroid Build Coastguard Worker
465*25da2beaSAndroid Build Coastguard Worker ret = test_double_chain(&ring);
466*25da2beaSAndroid Build Coastguard Worker if (ret) {
467*25da2beaSAndroid Build Coastguard Worker printf("test_double_chain failed\n");
468*25da2beaSAndroid Build Coastguard Worker return ret;
469*25da2beaSAndroid Build Coastguard Worker }
470*25da2beaSAndroid Build Coastguard Worker
471*25da2beaSAndroid Build Coastguard Worker ret = test_single_link_fail(&poll_ring);
472*25da2beaSAndroid Build Coastguard Worker if (ret) {
473*25da2beaSAndroid Build Coastguard Worker printf("test_single_link_fail failed\n");
474*25da2beaSAndroid Build Coastguard Worker return ret;
475*25da2beaSAndroid Build Coastguard Worker }
476*25da2beaSAndroid Build Coastguard Worker
477*25da2beaSAndroid Build Coastguard Worker ret = test_single_hardlink(&ring);
478*25da2beaSAndroid Build Coastguard Worker if (ret) {
479*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_single_hardlink\n");
480*25da2beaSAndroid Build Coastguard Worker return ret;
481*25da2beaSAndroid Build Coastguard Worker }
482*25da2beaSAndroid Build Coastguard Worker
483*25da2beaSAndroid Build Coastguard Worker ret = test_double_hardlink(&ring);
484*25da2beaSAndroid Build Coastguard Worker if (ret) {
485*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_double_hardlink\n");
486*25da2beaSAndroid Build Coastguard Worker return ret;
487*25da2beaSAndroid Build Coastguard Worker }
488*25da2beaSAndroid Build Coastguard Worker
489*25da2beaSAndroid Build Coastguard Worker ret = test_early_fail_and_wait();
490*25da2beaSAndroid Build Coastguard Worker if (ret) {
491*25da2beaSAndroid Build Coastguard Worker fprintf(stderr, "test_early_fail_and_wait\n");
492*25da2beaSAndroid Build Coastguard Worker return ret;
493*25da2beaSAndroid Build Coastguard Worker }
494*25da2beaSAndroid Build Coastguard Worker
495*25da2beaSAndroid Build Coastguard Worker return 0;
496*25da2beaSAndroid Build Coastguard Worker }
497