blob: d354d19fb095a60a910817ccc0e4f62d7e1af60e [file] [log] [blame]
Jens Axboee5024352020-02-11 20:34:12 -07001/* SPDX-License-Identifier: MIT */
Jens Axboe41d442b2019-12-14 22:44:40 -07002/*
William Dauchy7e3188b2020-01-04 16:23:14 +01003 * Description: run various statx(2) tests
Jens Axboe41d442b2019-12-14 22:44:40 -07004 *
5 */
6#include <errno.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <stdlib.h>
10#include <string.h>
11#include <fcntl.h>
12#include <sys/types.h>
Jens Axboe41d442b2019-12-14 22:44:40 -070013#include <sys/syscall.h>
14#include <linux/stat.h>
15
16#include "liburing.h"
17
Jens Axboe41d442b2019-12-14 22:44:40 -070018static int do_statx(int dfd, const char *path, int flags, unsigned mask,
19 struct statx *statxbuf)
20{
Tobias Klausercb7c6262020-07-09 23:34:52 +020021 return syscall(__NR_statx, dfd, path, flags, mask, statxbuf);
Jens Axboe41d442b2019-12-14 22:44:40 -070022}
Jens Axboe41d442b2019-12-14 22:44:40 -070023
24static int create_file(const char *file, size_t size)
25{
26 ssize_t ret;
27 char *buf;
28 int fd;
29
30 buf = malloc(size);
31 memset(buf, 0xaa, size);
32
33 fd = open(file, O_WRONLY | O_CREAT, 0644);
34 if (fd < 0) {
35 perror("open file");
36 return 1;
37 }
38 ret = write(fd, buf, size);
39 close(fd);
40 return ret != size;
41}
42
Tobias Klausercb7c6262020-07-09 23:34:52 +020043static int statx_syscall_supported(void)
44{
45 return errno == EOPNOTSUPP ? 0 : -1;
46}
47
Jens Axboe41d442b2019-12-14 22:44:40 -070048static int test_statx(struct io_uring *ring, const char *path)
49{
50 struct io_uring_cqe *cqe;
51 struct io_uring_sqe *sqe;
Tobias Klausercb7c6262020-07-09 23:34:52 +020052 struct statx x1, x2;
Jens Axboe41d442b2019-12-14 22:44:40 -070053 int ret;
54
55 sqe = io_uring_get_sqe(ring);
56 if (!sqe) {
57 fprintf(stderr, "get sqe failed\n");
58 goto err;
59 }
60 io_uring_prep_statx(sqe, -1, path, 0, STATX_ALL, &x1);
61
62 ret = io_uring_submit(ring);
63 if (ret <= 0) {
64 fprintf(stderr, "sqe submit failed: %d\n", ret);
65 goto err;
66 }
67
68 ret = io_uring_wait_cqe(ring, &cqe);
69 if (ret < 0) {
70 fprintf(stderr, "wait completion %d\n", ret);
71 goto err;
72 }
73 ret = cqe->res;
74 io_uring_cqe_seen(ring, cqe);
75 if (ret)
76 return ret;
Jens Axboe41d442b2019-12-14 22:44:40 -070077 ret = do_statx(-1, path, 0, STATX_ALL, &x2);
78 if (ret < 0)
Tobias Klausercb7c6262020-07-09 23:34:52 +020079 return statx_syscall_supported();
Jens Axboe41d442b2019-12-14 22:44:40 -070080 if (memcmp(&x1, &x2, sizeof(x1))) {
81 fprintf(stderr, "Miscompare between io_uring and statx\n");
82 goto err;
83 }
Jens Axboe41d442b2019-12-14 22:44:40 -070084 return 0;
85err:
86 return -1;
87}
88
Jens Axboe06b7fa52020-04-27 10:51:30 -060089static int test_statx_fd(struct io_uring *ring, const char *path)
90{
91 struct io_uring_cqe *cqe;
92 struct io_uring_sqe *sqe;
Tobias Klausercb7c6262020-07-09 23:34:52 +020093 struct statx x1, x2;
Jens Axboe06b7fa52020-04-27 10:51:30 -060094 int ret, fd;
95
96 fd = open(path, O_RDONLY);
97 if (fd < 0) {
98 perror("open");
99 return 1;
100 }
101
102 memset(&x1, 0, sizeof(x1));
103
104 sqe = io_uring_get_sqe(ring);
105 if (!sqe) {
106 fprintf(stderr, "get sqe failed\n");
107 goto err;
108 }
109 io_uring_prep_statx(sqe, fd, "", AT_EMPTY_PATH, STATX_ALL, &x1);
110
111 ret = io_uring_submit(ring);
112 if (ret <= 0) {
113 fprintf(stderr, "sqe submit failed: %d\n", ret);
114 goto err;
115 }
116
117 ret = io_uring_wait_cqe(ring, &cqe);
118 if (ret < 0) {
119 fprintf(stderr, "wait completion %d\n", ret);
120 goto err;
121 }
122 ret = cqe->res;
123 io_uring_cqe_seen(ring, cqe);
124 if (ret)
125 return ret;
Jens Axboe06b7fa52020-04-27 10:51:30 -0600126 memset(&x2, 0, sizeof(x2));
127 ret = do_statx(fd, "", AT_EMPTY_PATH, STATX_ALL, &x2);
128 if (ret < 0)
Tobias Klausercb7c6262020-07-09 23:34:52 +0200129 return statx_syscall_supported();
Jens Axboe06b7fa52020-04-27 10:51:30 -0600130 if (memcmp(&x1, &x2, sizeof(x1))) {
131 fprintf(stderr, "Miscompare between io_uring and statx\n");
132 goto err;
133 }
Jens Axboe06b7fa52020-04-27 10:51:30 -0600134 return 0;
135err:
136 return -1;
137}
138
Jens Axboe41d442b2019-12-14 22:44:40 -0700139int main(int argc, char *argv[])
140{
141 struct io_uring ring;
142 const char *fname;
143 int ret;
144
145 ret = io_uring_queue_init(8, &ring, 0);
146 if (ret) {
147 fprintf(stderr, "ring setup failed\n");
148 return 1;
149 }
150
151 if (argc > 1) {
152 fname = argv[1];
153 } else {
154 fname = "/tmp/.statx";
155 if (create_file(fname, 4096)) {
156 fprintf(stderr, "file create failed\n");
157 return 1;
158 }
159 }
160
161 ret = test_statx(&ring, fname);
162 if (ret) {
163 if (ret == -EINVAL) {
164 fprintf(stdout, "statx not supported, skipping\n");
165 goto done;
166 }
167 fprintf(stderr, "test_statx failed: %d\n", ret);
168 goto err;
169 }
Jens Axboe06b7fa52020-04-27 10:51:30 -0600170
171 ret = test_statx_fd(&ring, fname);
172 if (ret) {
173 fprintf(stderr, "test_statx_fd failed: %d\n", ret);
174 goto err;
175 }
Jens Axboe41d442b2019-12-14 22:44:40 -0700176done:
177 if (fname != argv[1])
178 unlink(fname);
179 return 0;
180err:
181 if (fname != argv[1])
182 unlink(fname);
183 return 1;
184}