xref: /aosp_15_r20/external/liburing/test/statx.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 statx(2) 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 #include <sys/types.h>
13*25da2beaSAndroid Build Coastguard Worker #include <sys/syscall.h>
14*25da2beaSAndroid Build Coastguard Worker #include <sys/stat.h>
15*25da2beaSAndroid Build Coastguard Worker 
16*25da2beaSAndroid Build Coastguard Worker #include "helpers.h"
17*25da2beaSAndroid Build Coastguard Worker #include "liburing.h"
18*25da2beaSAndroid Build Coastguard Worker 
19*25da2beaSAndroid Build Coastguard Worker #ifdef __NR_statx
do_statx(int dfd,const char * path,int flags,unsigned mask,struct statx * statxbuf)20*25da2beaSAndroid Build Coastguard Worker static int do_statx(int dfd, const char *path, int flags, unsigned mask,
21*25da2beaSAndroid Build Coastguard Worker 		    struct statx *statxbuf)
22*25da2beaSAndroid Build Coastguard Worker {
23*25da2beaSAndroid Build Coastguard Worker 	return syscall(__NR_statx, dfd, path, flags, mask, statxbuf);
24*25da2beaSAndroid Build Coastguard Worker }
25*25da2beaSAndroid Build Coastguard Worker #else
do_statx(int dfd,const char * path,int flags,unsigned mask,struct statx * statxbuf)26*25da2beaSAndroid Build Coastguard Worker static int do_statx(int dfd, const char *path, int flags, unsigned mask,
27*25da2beaSAndroid Build Coastguard Worker 		    struct statx *statxbuf)
28*25da2beaSAndroid Build Coastguard Worker {
29*25da2beaSAndroid Build Coastguard Worker 	errno = ENOSYS;
30*25da2beaSAndroid Build Coastguard Worker 	return -1;
31*25da2beaSAndroid Build Coastguard Worker }
32*25da2beaSAndroid Build Coastguard Worker #endif
33*25da2beaSAndroid Build Coastguard Worker 
statx_syscall_supported(void)34*25da2beaSAndroid Build Coastguard Worker static int statx_syscall_supported(void)
35*25da2beaSAndroid Build Coastguard Worker {
36*25da2beaSAndroid Build Coastguard Worker 	return errno == ENOSYS ? 0 : -1;
37*25da2beaSAndroid Build Coastguard Worker }
38*25da2beaSAndroid Build Coastguard Worker 
test_statx(struct io_uring * ring,const char * path)39*25da2beaSAndroid Build Coastguard Worker static int test_statx(struct io_uring *ring, const char *path)
40*25da2beaSAndroid Build Coastguard Worker {
41*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
42*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
43*25da2beaSAndroid Build Coastguard Worker 	struct statx x1, x2;
44*25da2beaSAndroid Build Coastguard Worker 	int ret;
45*25da2beaSAndroid Build Coastguard Worker 
46*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
47*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
48*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
49*25da2beaSAndroid Build Coastguard Worker 		goto err;
50*25da2beaSAndroid Build Coastguard Worker 	}
51*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_statx(sqe, -1, path, 0, STATX_ALL, &x1);
52*25da2beaSAndroid Build Coastguard Worker 
53*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
54*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
55*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
56*25da2beaSAndroid Build Coastguard Worker 		goto err;
57*25da2beaSAndroid Build Coastguard Worker 	}
58*25da2beaSAndroid Build Coastguard Worker 
59*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
60*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
61*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
62*25da2beaSAndroid Build Coastguard Worker 		goto err;
63*25da2beaSAndroid Build Coastguard Worker 	}
64*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
65*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
66*25da2beaSAndroid Build Coastguard Worker 	if (ret)
67*25da2beaSAndroid Build Coastguard Worker 		return ret;
68*25da2beaSAndroid Build Coastguard Worker 	ret = do_statx(-1, path, 0, STATX_ALL, &x2);
69*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0)
70*25da2beaSAndroid Build Coastguard Worker 		return statx_syscall_supported();
71*25da2beaSAndroid Build Coastguard Worker 	if (memcmp(&x1, &x2, sizeof(x1))) {
72*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Miscompare between io_uring and statx\n");
73*25da2beaSAndroid Build Coastguard Worker 		goto err;
74*25da2beaSAndroid Build Coastguard Worker 	}
75*25da2beaSAndroid Build Coastguard Worker 	return 0;
76*25da2beaSAndroid Build Coastguard Worker err:
77*25da2beaSAndroid Build Coastguard Worker 	return -1;
78*25da2beaSAndroid Build Coastguard Worker }
79*25da2beaSAndroid Build Coastguard Worker 
test_statx_fd(struct io_uring * ring,const char * path)80*25da2beaSAndroid Build Coastguard Worker static int test_statx_fd(struct io_uring *ring, const char *path)
81*25da2beaSAndroid Build Coastguard Worker {
82*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_cqe *cqe;
83*25da2beaSAndroid Build Coastguard Worker 	struct io_uring_sqe *sqe;
84*25da2beaSAndroid Build Coastguard Worker 	struct statx x1, x2;
85*25da2beaSAndroid Build Coastguard Worker 	int ret, fd;
86*25da2beaSAndroid Build Coastguard Worker 
87*25da2beaSAndroid Build Coastguard Worker 	fd = open(path, O_RDONLY);
88*25da2beaSAndroid Build Coastguard Worker 	if (fd < 0) {
89*25da2beaSAndroid Build Coastguard Worker 		perror("open");
90*25da2beaSAndroid Build Coastguard Worker 		return 1;
91*25da2beaSAndroid Build Coastguard Worker 	}
92*25da2beaSAndroid Build Coastguard Worker 
93*25da2beaSAndroid Build Coastguard Worker 	memset(&x1, 0, sizeof(x1));
94*25da2beaSAndroid Build Coastguard Worker 
95*25da2beaSAndroid Build Coastguard Worker 	sqe = io_uring_get_sqe(ring);
96*25da2beaSAndroid Build Coastguard Worker 	if (!sqe) {
97*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "get sqe failed\n");
98*25da2beaSAndroid Build Coastguard Worker 		goto err;
99*25da2beaSAndroid Build Coastguard Worker 	}
100*25da2beaSAndroid Build Coastguard Worker 	io_uring_prep_statx(sqe, fd, "", AT_EMPTY_PATH, STATX_ALL, &x1);
101*25da2beaSAndroid Build Coastguard Worker 
102*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_submit(ring);
103*25da2beaSAndroid Build Coastguard Worker 	if (ret <= 0) {
104*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "sqe submit failed: %d\n", ret);
105*25da2beaSAndroid Build Coastguard Worker 		goto err;
106*25da2beaSAndroid Build Coastguard Worker 	}
107*25da2beaSAndroid Build Coastguard Worker 
108*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_wait_cqe(ring, &cqe);
109*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0) {
110*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "wait completion %d\n", ret);
111*25da2beaSAndroid Build Coastguard Worker 		goto err;
112*25da2beaSAndroid Build Coastguard Worker 	}
113*25da2beaSAndroid Build Coastguard Worker 	ret = cqe->res;
114*25da2beaSAndroid Build Coastguard Worker 	io_uring_cqe_seen(ring, cqe);
115*25da2beaSAndroid Build Coastguard Worker 	if (ret)
116*25da2beaSAndroid Build Coastguard Worker 		return ret;
117*25da2beaSAndroid Build Coastguard Worker 	memset(&x2, 0, sizeof(x2));
118*25da2beaSAndroid Build Coastguard Worker 	ret = do_statx(fd, "", AT_EMPTY_PATH, STATX_ALL, &x2);
119*25da2beaSAndroid Build Coastguard Worker 	if (ret < 0)
120*25da2beaSAndroid Build Coastguard Worker 		return statx_syscall_supported();
121*25da2beaSAndroid Build Coastguard Worker 	if (memcmp(&x1, &x2, sizeof(x1))) {
122*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "Miscompare between io_uring and statx\n");
123*25da2beaSAndroid Build Coastguard Worker 		goto err;
124*25da2beaSAndroid Build Coastguard Worker 	}
125*25da2beaSAndroid Build Coastguard Worker 	return 0;
126*25da2beaSAndroid Build Coastguard Worker err:
127*25da2beaSAndroid Build Coastguard Worker 	return -1;
128*25da2beaSAndroid Build Coastguard Worker }
129*25da2beaSAndroid Build Coastguard Worker 
main(int argc,char * argv[])130*25da2beaSAndroid Build Coastguard Worker int main(int argc, char *argv[])
131*25da2beaSAndroid Build Coastguard Worker {
132*25da2beaSAndroid Build Coastguard Worker 	struct io_uring ring;
133*25da2beaSAndroid Build Coastguard Worker 	const char *fname;
134*25da2beaSAndroid Build Coastguard Worker 	int ret;
135*25da2beaSAndroid Build Coastguard Worker 
136*25da2beaSAndroid Build Coastguard Worker 	ret = io_uring_queue_init(8, &ring, 0);
137*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
138*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "ring setup failed\n");
139*25da2beaSAndroid Build Coastguard Worker 		return 1;
140*25da2beaSAndroid Build Coastguard Worker 	}
141*25da2beaSAndroid Build Coastguard Worker 
142*25da2beaSAndroid Build Coastguard Worker 	if (argc > 1) {
143*25da2beaSAndroid Build Coastguard Worker 		fname = argv[1];
144*25da2beaSAndroid Build Coastguard Worker 	} else {
145*25da2beaSAndroid Build Coastguard Worker 		fname = "/tmp/.statx";
146*25da2beaSAndroid Build Coastguard Worker 		t_create_file(fname, 4096);
147*25da2beaSAndroid Build Coastguard Worker 	}
148*25da2beaSAndroid Build Coastguard Worker 
149*25da2beaSAndroid Build Coastguard Worker 	ret = test_statx(&ring, fname);
150*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
151*25da2beaSAndroid Build Coastguard Worker 		if (ret == -EINVAL) {
152*25da2beaSAndroid Build Coastguard Worker 			fprintf(stdout, "statx not supported, skipping\n");
153*25da2beaSAndroid Build Coastguard Worker 			goto done;
154*25da2beaSAndroid Build Coastguard Worker 		}
155*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_statx failed: %d\n", ret);
156*25da2beaSAndroid Build Coastguard Worker 		goto err;
157*25da2beaSAndroid Build Coastguard Worker 	}
158*25da2beaSAndroid Build Coastguard Worker 
159*25da2beaSAndroid Build Coastguard Worker 	ret = test_statx_fd(&ring, fname);
160*25da2beaSAndroid Build Coastguard Worker 	if (ret) {
161*25da2beaSAndroid Build Coastguard Worker 		fprintf(stderr, "test_statx_fd failed: %d\n", ret);
162*25da2beaSAndroid Build Coastguard Worker 		goto err;
163*25da2beaSAndroid Build Coastguard Worker 	}
164*25da2beaSAndroid Build Coastguard Worker done:
165*25da2beaSAndroid Build Coastguard Worker 	if (fname != argv[1])
166*25da2beaSAndroid Build Coastguard Worker 		unlink(fname);
167*25da2beaSAndroid Build Coastguard Worker 	return 0;
168*25da2beaSAndroid Build Coastguard Worker err:
169*25da2beaSAndroid Build Coastguard Worker 	if (fname != argv[1])
170*25da2beaSAndroid Build Coastguard Worker 		unlink(fname);
171*25da2beaSAndroid Build Coastguard Worker 	return 1;
172*25da2beaSAndroid Build Coastguard Worker }
173