1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Description: test io_uring mkdirat handling
4 */
5 #include <fcntl.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
12 #include "liburing.h"
13
do_mkdirat(struct io_uring * ring,const char * fn)14 static int do_mkdirat(struct io_uring *ring, const char *fn)
15 {
16 int ret;
17 struct io_uring_sqe *sqe;
18 struct io_uring_cqe *cqe;
19
20 sqe = io_uring_get_sqe(ring);
21 if (!sqe) {
22 fprintf(stderr, "sqe get failed\n");
23 goto err;
24 }
25 io_uring_prep_mkdirat(sqe, AT_FDCWD, fn, 0700);
26
27 ret = io_uring_submit(ring);
28 if (ret != 1) {
29 fprintf(stderr, "submit failed: %d\n", ret);
30 goto err;
31 }
32
33 ret = io_uring_wait_cqes(ring, &cqe, 1, 0, 0);
34 if (ret) {
35 fprintf(stderr, "wait_cqe failed: %d\n", ret);
36 goto err;
37 }
38 ret = cqe->res;
39 io_uring_cqe_seen(ring, cqe);
40 return ret;
41 err:
42 return 1;
43 }
44
stat_file(const char * fn)45 static int stat_file(const char *fn)
46 {
47 struct stat sb;
48
49 if (!stat(fn, &sb))
50 return 0;
51
52 return errno;
53 }
54
main(int argc,char * argv[])55 int main(int argc, char *argv[])
56 {
57 static const char fn[] = "io_uring-mkdirat-test";
58 int ret;
59 struct io_uring ring;
60
61 if (argc > 1)
62 return 0;
63
64 ret = io_uring_queue_init(8, &ring, 0);
65 if (ret) {
66 fprintf(stderr, "queue init failed: %d\n", ret);
67 return ret;
68 }
69
70 ret = do_mkdirat(&ring, fn);
71 if (ret < 0) {
72 if (ret == -EBADF || ret == -EINVAL) {
73 fprintf(stdout, "mkdirat not supported, skipping\n");
74 goto out;
75 }
76 fprintf(stderr, "mkdirat: %s\n", strerror(-ret));
77 goto err;
78 } else if (ret) {
79 goto err;
80 }
81
82 if (stat_file(fn)) {
83 perror("stat");
84 goto err;
85 }
86
87 ret = do_mkdirat(&ring, fn);
88 if (ret != -EEXIST) {
89 fprintf(stderr, "do_mkdirat already exists failed: %d\n", ret);
90 goto err1;
91 }
92
93 ret = do_mkdirat(&ring, "surely/this/wont/exist");
94 if (ret != -ENOENT) {
95 fprintf(stderr, "do_mkdirat no parent failed: %d\n", ret);
96 goto err1;
97 }
98
99 out:
100 unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
101 io_uring_queue_exit(&ring);
102 return 0;
103 err1:
104 unlinkat(AT_FDCWD, fn, AT_REMOVEDIR);
105 err:
106 io_uring_queue_exit(&ring);
107 return 1;
108 }
109