xref: /aosp_15_r20/external/liburing/test/link.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
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