blob: a397593f7c11db36896373aa32ab496f6b4272ee [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
18#if defined(__x86_64)
19static int do_statx(int dfd, const char *path, int flags, unsigned mask,
20 struct statx *statxbuf)
21{
22 return syscall(332, dfd, path, flags, mask, statxbuf);
23}
24#endif
25
26static int create_file(const char *file, size_t size)
27{
28 ssize_t ret;
29 char *buf;
30 int fd;
31
32 buf = malloc(size);
33 memset(buf, 0xaa, size);
34
35 fd = open(file, O_WRONLY | O_CREAT, 0644);
36 if (fd < 0) {
37 perror("open file");
38 return 1;
39 }
40 ret = write(fd, buf, size);
41 close(fd);
42 return ret != size;
43}
44
45static int test_statx(struct io_uring *ring, const char *path)
46{
47 struct io_uring_cqe *cqe;
48 struct io_uring_sqe *sqe;
49 struct statx x1;
50#if defined(__x86_64)
51 struct statx x2;
52#endif
53 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;
77#if defined(__x86_64)
78 ret = do_statx(-1, path, 0, STATX_ALL, &x2);
79 if (ret < 0)
80 return -1;
81 if (memcmp(&x1, &x2, sizeof(x1))) {
82 fprintf(stderr, "Miscompare between io_uring and statx\n");
83 goto err;
84 }
85#endif
86 return 0;
87err:
88 return -1;
89}
90
Jens Axboe06b7fa52020-04-27 10:51:30 -060091static int test_statx_fd(struct io_uring *ring, const char *path)
92{
93 struct io_uring_cqe *cqe;
94 struct io_uring_sqe *sqe;
95 struct statx x1;
96#if defined(__x86_64)
97 struct statx x2;
98#endif
99 int ret, fd;
100
101 fd = open(path, O_RDONLY);
102 if (fd < 0) {
103 perror("open");
104 return 1;
105 }
106
107 memset(&x1, 0, sizeof(x1));
108
109 sqe = io_uring_get_sqe(ring);
110 if (!sqe) {
111 fprintf(stderr, "get sqe failed\n");
112 goto err;
113 }
114 io_uring_prep_statx(sqe, fd, "", AT_EMPTY_PATH, STATX_ALL, &x1);
115
116 ret = io_uring_submit(ring);
117 if (ret <= 0) {
118 fprintf(stderr, "sqe submit failed: %d\n", ret);
119 goto err;
120 }
121
122 ret = io_uring_wait_cqe(ring, &cqe);
123 if (ret < 0) {
124 fprintf(stderr, "wait completion %d\n", ret);
125 goto err;
126 }
127 ret = cqe->res;
128 io_uring_cqe_seen(ring, cqe);
129 if (ret)
130 return ret;
131#if defined(__x86_64)
132 memset(&x2, 0, sizeof(x2));
133 ret = do_statx(fd, "", AT_EMPTY_PATH, STATX_ALL, &x2);
134 if (ret < 0)
135 return -1;
136 if (memcmp(&x1, &x2, sizeof(x1))) {
137 fprintf(stderr, "Miscompare between io_uring and statx\n");
138 goto err;
139 }
140#endif
141 return 0;
142err:
143 return -1;
144}
145
Jens Axboe41d442b2019-12-14 22:44:40 -0700146int main(int argc, char *argv[])
147{
148 struct io_uring ring;
149 const char *fname;
150 int ret;
151
152 ret = io_uring_queue_init(8, &ring, 0);
153 if (ret) {
154 fprintf(stderr, "ring setup failed\n");
155 return 1;
156 }
157
158 if (argc > 1) {
159 fname = argv[1];
160 } else {
161 fname = "/tmp/.statx";
162 if (create_file(fname, 4096)) {
163 fprintf(stderr, "file create failed\n");
164 return 1;
165 }
166 }
167
168 ret = test_statx(&ring, fname);
169 if (ret) {
170 if (ret == -EINVAL) {
171 fprintf(stdout, "statx not supported, skipping\n");
172 goto done;
173 }
174 fprintf(stderr, "test_statx failed: %d\n", ret);
175 goto err;
176 }
Jens Axboe06b7fa52020-04-27 10:51:30 -0600177
178 ret = test_statx_fd(&ring, fname);
179 if (ret) {
180 fprintf(stderr, "test_statx_fd failed: %d\n", ret);
181 goto err;
182 }
Jens Axboe41d442b2019-12-14 22:44:40 -0700183done:
184 if (fname != argv[1])
185 unlink(fname);
186 return 0;
187err:
188 if (fname != argv[1])
189 unlink(fname);
190 return 1;
191}