xref: /aosp_15_r20/external/liburing/test/fallocate.c (revision 25da2bea747f3a93b4c30fd9708b0618ef55a0e6)
1*25da2beaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: MIT */
2*25da2beaSAndroid Build Coastguard Worker /*
3*25da2beaSAndroid Build Coastguard Worker  * Description: test io_uring fallocate
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 <sys/types.h>
10*25da2beaSAndroid Build Coastguard Worker #include <sys/stat.h>
11*25da2beaSAndroid Build Coastguard Worker #include <sys/resource.h>
12*25da2beaSAndroid Build Coastguard Worker #include <stdlib.h>
13*25da2beaSAndroid Build Coastguard Worker #include <string.h>
14*25da2beaSAndroid Build Coastguard Worker #include <fcntl.h>
15*25da2beaSAndroid Build Coastguard Worker 
16*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
17*25da2beaSAndroid Build Coastguard Worker 
18*25da2beaSAndroid Build Coastguard Worker static int no_fallocate;
19*25da2beaSAndroid Build Coastguard Worker 
test_fallocate_rlimit(struct io_uring * ring)20*25da2beaSAndroid Build Coastguard Worker static int test_fallocate_rlimit(struct io_uring *ring)
21*25da2beaSAndroid Build Coastguard Worker {
22*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
23*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
24*25da2beaSAndroid Build Coastguard Worker 	struct rlimit rlim;
25*25da2beaSAndroid Build Coastguard Worker 	char buf[32];
26*25da2beaSAndroid Build Coastguard Worker 	int fd, ret;
27*25da2beaSAndroid Build Coastguard Worker 
28*25da2beaSAndroid Build Coastguard Worker 	if (getrlimit(RLIMIT_FSIZE, &rlim) < 0) {
29*25da2beaSAndroid Build Coastguard Worker 		perror("getrlimit");
30*25da2beaSAndroid Build Coastguard Worker 		return 1;
31*25da2beaSAndroid Build Coastguard Worker 	}
32*25da2beaSAndroid Build Coastguard Worker 	rlim.rlim_cur = 64 * 1024;
33*25da2beaSAndroid Build Coastguard Worker 	rlim.rlim_max = 64 * 1024;
34*25da2beaSAndroid Build Coastguard Worker 	if (setrlimit(RLIMIT_FSIZE, &rlim) < 0) {
35*25da2beaSAndroid Build Coastguard Worker 		perror("setrlimit");
36*25da2beaSAndroid Build Coastguard Worker 		return 1;
37*25da2beaSAndroid Build Coastguard Worker 	}
38*25da2beaSAndroid Build Coastguard Worker 
39*25da2beaSAndroid Build Coastguard Worker 	sprintf(buf, "./XXXXXX");
40*25da2beaSAndroid Build Coastguard Worker 	fd = mkstemp(buf);
41*25da2beaSAndroid Build Coastguard Worker 	if (fd < 0) {
42*25da2beaSAndroid Build Coastguard Worker 		perror("open");
43*25da2beaSAndroid Build Coastguard Worker 		return 1;
44*25da2beaSAndroid Build Coastguard Worker 	}
45*25da2beaSAndroid Build Coastguard Worker 	unlink(buf);
46*25da2beaSAndroid Build Coastguard Worker 
47*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
48*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
49*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
50*25da2beaSAndroid Build Coastguard Worker 		goto err;
51*25da2beaSAndroid Build Coastguard Worker 	}
52*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_fallocate(sqe, fd, 0, 0, 128*1024);
53*25da2beaSAndroid Build Coastguard Worker 
54*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
55*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
56*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
57*25da2beaSAndroid Build Coastguard Worker 		goto err;
58*25da2beaSAndroid Build Coastguard Worker 	}
59*25da2beaSAndroid Build Coastguard Worker 
60*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
61*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
62*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
63*25da2beaSAndroid Build Coastguard Worker 		goto err;
64*25da2beaSAndroid Build Coastguard Worker 	}
65*25da2beaSAndroid Build Coastguard Worker 
66*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res == -EINVAL) {
67*25da2beaSAndroid Build Coastguard Worker 		fprintf(stdout, "Fallocate not supported, skipping\n");
68*25da2beaSAndroid Build Coastguard Worker 		no_fallocate = 1;
69*25da2beaSAndroid Build Coastguard Worker 		goto out;
70*25da2beaSAndroid Build Coastguard Worker 	} else if (cqe->res != -EFBIG) {
71*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Expected -EFBIG: %d\n", cqe->res);
72*25da2beaSAndroid Build Coastguard Worker 		goto err;
73*25da2beaSAndroid Build Coastguard Worker 	}
74*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
75*25da2beaSAndroid Build Coastguard Worker out:
76*25da2beaSAndroid Build Coastguard Worker 	return 0;
77*25da2beaSAndroid Build Coastguard Worker err:
78*25da2beaSAndroid Build Coastguard Worker 	return 1;
79*25da2beaSAndroid Build Coastguard Worker }
80*25da2beaSAndroid Build Coastguard Worker 
test_fallocate(struct io_uring * ring)81*25da2beaSAndroid Build Coastguard Worker static int test_fallocate(struct io_uring *ring)
82*25da2beaSAndroid Build Coastguard Worker {
83*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
84*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
85*25da2beaSAndroid Build Coastguard Worker 	struct stat st;
86*25da2beaSAndroid Build Coastguard Worker 	char buf[32];
87*25da2beaSAndroid Build Coastguard Worker 	int fd, ret;
88*25da2beaSAndroid Build Coastguard Worker 
89*25da2beaSAndroid Build Coastguard Worker 	sprintf(buf, "./XXXXXX");
90*25da2beaSAndroid Build Coastguard Worker 	fd = mkstemp(buf);
91*25da2beaSAndroid Build Coastguard Worker 	if (fd < 0) {
92*25da2beaSAndroid Build Coastguard Worker 		perror("open");
93*25da2beaSAndroid Build Coastguard Worker 		return 1;
94*25da2beaSAndroid Build Coastguard Worker 	}
95*25da2beaSAndroid Build Coastguard Worker 	unlink(buf);
96*25da2beaSAndroid Build Coastguard Worker 
97*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
98*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
99*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
100*25da2beaSAndroid Build Coastguard Worker 		goto err;
101*25da2beaSAndroid Build Coastguard Worker 	}
102*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_fallocate(sqe, fd, 0, 0, 128*1024);
103*25da2beaSAndroid Build Coastguard Worker 
104*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
105*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
106*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
107*25da2beaSAndroid Build Coastguard Worker 		goto err;
108*25da2beaSAndroid Build Coastguard Worker 	}
109*25da2beaSAndroid Build Coastguard Worker 
110*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
111*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
112*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
113*25da2beaSAndroid Build Coastguard Worker 		goto err;
114*25da2beaSAndroid Build Coastguard Worker 	}
115*25da2beaSAndroid Build Coastguard Worker 
116*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res == -EINVAL) {
117*25da2beaSAndroid Build Coastguard Worker 		fprintf(stdout, "Fallocate not supported, skipping\n");
118*25da2beaSAndroid Build Coastguard Worker 		no_fallocate = 1;
119*25da2beaSAndroid Build Coastguard Worker 		goto out;
120*25da2beaSAndroid Build Coastguard Worker 	}
121*25da2beaSAndroid Build Coastguard Worker 	if (cqe->res) {
122*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "cqe->res=%d\n", cqe->res);
123*25da2beaSAndroid Build Coastguard Worker 		goto err;
124*25da2beaSAndroid Build Coastguard Worker 	}
125*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
126*25da2beaSAndroid Build Coastguard Worker 
127*25da2beaSAndroid Build Coastguard Worker 	if (fstat(fd, &st) < 0) {
128*25da2beaSAndroid Build Coastguard Worker 		perror("stat");
129*25da2beaSAndroid Build Coastguard Worker 		goto err;
130*25da2beaSAndroid Build Coastguard Worker 	}
131*25da2beaSAndroid Build Coastguard Worker 
132*25da2beaSAndroid Build Coastguard Worker 	if (st.st_size != 128*1024) {
133*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Size mismatch: %llu\n",
134*25da2beaSAndroid Build Coastguard Worker 					(unsigned long long) st.st_size);
135*25da2beaSAndroid Build Coastguard Worker 		goto err;
136*25da2beaSAndroid Build Coastguard Worker 	}
137*25da2beaSAndroid Build Coastguard Worker 
138*25da2beaSAndroid Build Coastguard Worker out:
139*25da2beaSAndroid Build Coastguard Worker 	return 0;
140*25da2beaSAndroid Build Coastguard Worker err:
141*25da2beaSAndroid Build Coastguard Worker 	return 1;
142*25da2beaSAndroid Build Coastguard Worker }
143*25da2beaSAndroid Build Coastguard Worker 
test_fallocate_fsync(struct io_uring * ring)144*25da2beaSAndroid Build Coastguard Worker static int test_fallocate_fsync(struct io_uring *ring)
145*25da2beaSAndroid Build Coastguard Worker {
146*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
147*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
148*25da2beaSAndroid Build Coastguard Worker 	struct stat st;
149*25da2beaSAndroid Build Coastguard Worker 	char buf[32];
150*25da2beaSAndroid Build Coastguard Worker 	int fd, ret, i;
151*25da2beaSAndroid Build Coastguard Worker 
152*25da2beaSAndroid Build Coastguard Worker 	if (no_fallocate)
153*25da2beaSAndroid Build Coastguard Worker 		return 0;
154*25da2beaSAndroid Build Coastguard Worker 
155*25da2beaSAndroid Build Coastguard Worker 	sprintf(buf, "./XXXXXX");
156*25da2beaSAndroid Build Coastguard Worker 	fd = mkstemp(buf);
157*25da2beaSAndroid Build Coastguard Worker 	if (fd < 0) {
158*25da2beaSAndroid Build Coastguard Worker 		perror("open");
159*25da2beaSAndroid Build Coastguard Worker 		return 1;
160*25da2beaSAndroid Build Coastguard Worker 	}
161*25da2beaSAndroid Build Coastguard Worker 	unlink(buf);
162*25da2beaSAndroid Build Coastguard Worker 
163*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
164*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
165*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
166*25da2beaSAndroid Build Coastguard Worker 		goto err;
167*25da2beaSAndroid Build Coastguard Worker 	}
168*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_fallocate(sqe, fd, 0, 0, 128*1024);
169*25da2beaSAndroid Build Coastguard Worker 	sqe->flags |= IOSQE_IO_LINK;
170*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 1;
171*25da2beaSAndroid Build Coastguard Worker 
172*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
173*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
174*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
175*25da2beaSAndroid Build Coastguard Worker 		goto err;
176*25da2beaSAndroid Build Coastguard Worker 	}
177*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_fsync(sqe, fd, 0);
178*25da2beaSAndroid Build Coastguard Worker 	sqe->user_data = 2;
179*25da2beaSAndroid Build Coastguard Worker 
180*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
181*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
182*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
183*25da2beaSAndroid Build Coastguard Worker 		goto err;
184*25da2beaSAndroid Build Coastguard Worker 	}
185*25da2beaSAndroid Build Coastguard Worker 
186*25da2beaSAndroid Build Coastguard Worker 	for (i = 0; i < 2; i++) {
187*25da2beaSAndroid Build Coastguard Worker 		ret = io_uring_wait_cqe(ring, &cqe);
188*25da2beaSAndroid Build Coastguard Worker 		if (ret < 0) {
189*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "wait completion %d\n", ret);
190*25da2beaSAndroid Build Coastguard Worker 			goto err;
191*25da2beaSAndroid Build Coastguard Worker 		}
192*25da2beaSAndroid Build Coastguard Worker 		if (cqe->res) {
193*25da2beaSAndroid Build Coastguard Worker 			fprintf(stderr, "cqe->res=%d,data=%" PRIu64 "\n", cqe->res,
194*25da2beaSAndroid Build Coastguard Worker 							(uint64_t) cqe->user_data);
195*25da2beaSAndroid Build Coastguard Worker 			goto err;
196*25da2beaSAndroid Build Coastguard Worker 		}
197*25da2beaSAndroid Build Coastguard Worker 		io_uring_cqe_seen(ring, cqe);
198*25da2beaSAndroid Build Coastguard Worker 	}
199*25da2beaSAndroid Build Coastguard Worker 
200*25da2beaSAndroid Build Coastguard Worker 	if (fstat(fd, &st) < 0) {
201*25da2beaSAndroid Build Coastguard Worker 		perror("stat");
202*25da2beaSAndroid Build Coastguard Worker 		goto err;
203*25da2beaSAndroid Build Coastguard Worker 	}
204*25da2beaSAndroid Build Coastguard Worker 
205*25da2beaSAndroid Build Coastguard Worker 	if (st.st_size != 128*1024) {
206*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Size mismatch: %llu\n",
207*25da2beaSAndroid Build Coastguard Worker 					(unsigned long long) st.st_size);
208*25da2beaSAndroid Build Coastguard Worker 		goto err;
209*25da2beaSAndroid Build Coastguard Worker 	}
210*25da2beaSAndroid Build Coastguard Worker 
211*25da2beaSAndroid Build Coastguard Worker 	return 0;
212*25da2beaSAndroid Build Coastguard Worker err:
213*25da2beaSAndroid Build Coastguard Worker 	return 1;
214*25da2beaSAndroid Build Coastguard Worker }
215*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])216*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
217*25da2beaSAndroid Build Coastguard Worker {
218*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
219*25da2beaSAndroid Build Coastguard Worker 	int ret;
220*25da2beaSAndroid Build Coastguard Worker 
221*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1)
222*25da2beaSAndroid Build Coastguard Worker 		return 0;
223*25da2beaSAndroid Build Coastguard Worker 
224*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
225*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
226*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring setup failed\n");
227*25da2beaSAndroid Build Coastguard Worker 		return 1;
228*25da2beaSAndroid Build Coastguard Worker 	}
229*25da2beaSAndroid Build Coastguard Worker 
230*25da2beaSAndroid Build Coastguard Worker 	ret = test_fallocate(&ring);
231*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
232*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_fallocate failed\n");
233*25da2beaSAndroid Build Coastguard Worker 		return ret;
234*25da2beaSAndroid Build Coastguard Worker 	}
235*25da2beaSAndroid Build Coastguard Worker 
236*25da2beaSAndroid Build Coastguard Worker 	ret = test_fallocate_fsync(&ring);
237*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
238*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_fallocate_fsync failed\n");
239*25da2beaSAndroid Build Coastguard Worker 		return ret;
240*25da2beaSAndroid Build Coastguard Worker 	}
241*25da2beaSAndroid Build Coastguard Worker 
242*25da2beaSAndroid Build Coastguard Worker 	ret = test_fallocate_rlimit(&ring);
243*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
244*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_fallocate_rlimit failed\n");
245*25da2beaSAndroid Build Coastguard Worker 		return ret;
246*25da2beaSAndroid Build Coastguard Worker 	}
247*25da2beaSAndroid Build Coastguard Worker 
248*25da2beaSAndroid Build Coastguard Worker 	return 0;
249*25da2beaSAndroid Build Coastguard Worker }
250