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