blob: 93ec6feb09b65e120bbbb9d331cf4a18155d8522 [file] [log] [blame]
Dmitry V. Levin13c21732015-08-26 12:49:07 +00001/*
Dmitry V. Levin9ad44092016-01-06 11:27:15 +00002 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
Dmitry V. Levin13c21732015-08-26 12:49:07 +00003 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
Dmitry V. Levin0c8853c2016-01-02 13:28:43 +000028#include "tests.h"
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000029#include <assert.h>
30#include <errno.h>
Dmitry V. Levinc36270a2016-01-11 02:20:04 +000031#include <fcntl.h>
Dmitry V. Levin13c21732015-08-26 12:49:07 +000032#include <inttypes.h>
33#include <stdio.h>
Dmitry V. Levind1c663a2015-12-16 02:00:01 +000034#include <time.h>
Dmitry V. Levin13c21732015-08-26 12:49:07 +000035#include <unistd.h>
Dmitry V. Levin13c21732015-08-26 12:49:07 +000036#include <sys/syscall.h>
37
38#if defined __NR_io_setup \
39 && defined __NR_io_submit \
40 && defined __NR_io_getevents \
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000041 && defined __NR_io_cancel \
Dmitry V. Levin13c21732015-08-26 12:49:07 +000042 && defined __NR_io_destroy
43# include <linux/aio_abi.h>
44
Dmitry V. Levin9ad44092016-01-06 11:27:15 +000045# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000046
Dmitry V. Levin13c21732015-08-26 12:49:07 +000047int
48main(void)
49{
50 static char data0[4096];
51 static char data1[8192];
52
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000053 const struct iocb cb[] = {
Dmitry V. Levin13c21732015-08-26 12:49:07 +000054 {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000055 .aio_data = 0xfeedface11111111,
Dmitry V. Levin13c21732015-08-26 12:49:07 +000056 .aio_reqprio = 11,
57 .aio_buf = (unsigned long) data0,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000058 .aio_offset = 0xdeface1facefeed,
Dmitry V. Levin13c21732015-08-26 12:49:07 +000059 .aio_nbytes = sizeof(data0)
60 },
61 {
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000062 .aio_data = 0xfeedface22222222,
Dmitry V. Levin13c21732015-08-26 12:49:07 +000063 .aio_reqprio = 22,
64 .aio_buf = (unsigned long) data1,
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000065 .aio_offset = 0xdeface2cafef00d,
Dmitry V. Levin13c21732015-08-26 12:49:07 +000066 .aio_nbytes = sizeof(data1)
67 }
68 };
Dmitry V. Levinf56046e2015-08-26 17:48:40 +000069 const struct iovec iov0[] = {
70 {
71 .iov_base = data0,
72 .iov_len = sizeof(data0) / 4
73 },
74 {
75 .iov_base = data0 + sizeof(data0) / 4,
76 .iov_len = sizeof(data0) / 4 * 3
77 },
78 };
79 const struct iovec iov1[] = {
80 {
81 .iov_base = data1,
82 .iov_len = sizeof(data1) / 4
83 },
84 {
85 .iov_base = data1 + sizeof(data1) / 4,
86 .iov_len = sizeof(data1) / 4 * 3
87 },
88 };
89 const struct iocb cbv[] = {
90 {
91 .aio_data = 0xfeed11111111face,
92 .aio_lio_opcode = 7,
93 .aio_reqprio = 111,
94 .aio_buf = (unsigned long) &iov0,
95 .aio_offset = 0xdeface1facefeed,
96 .aio_nbytes = ARRAY_SIZE(iov0)
97 },
98 {
99 .aio_data = 0xfeed22222222face,
100 .aio_lio_opcode = 7,
101 .aio_reqprio = 222,
102 .aio_buf = (unsigned long) &iov1,
103 .aio_offset = 0xdeface2cafef00d,
104 .aio_nbytes = ARRAY_SIZE(iov1)
105 }
106 };
107 struct iocb cbc = {
108 .aio_data = 0xdeadbeefbadc0ded,
109 .aio_reqprio = 99,
110 .aio_fildes = -42
111 };
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000112
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000113 const long cbs[ARRAY_SIZE(cb) + 2] = {
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000114 (long) &cb[0], (long) &cb[1],
115 0xdeadbeef, 0xbadc0ded
116 };
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000117 const long cbvs[ARRAY_SIZE(cb) + 2] = {
118 (long) &cbv[0], (long) &cbv[1],
119 0xdeadbeef, 0xbadc0ded
120 };
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000121
122 unsigned long ctx = 0;
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000123 const unsigned int nr = ARRAY_SIZE(cb);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000124 const unsigned long lnr = (unsigned long) (0xdeadbeef00000000ULL | nr);
125
126 struct io_event ev[nr];
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000127 const struct timespec ts = { .tv_nsec = 123456789 };
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000128
129 (void) close(0);
130 if (open("/dev/zero", O_RDONLY))
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000131 perror_msg_and_skip("open: %s", "/dev/zero");
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000132
133 if (syscall(__NR_io_setup, lnr, &ctx))
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000134 perror_msg_and_skip("io_setup");
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000135 printf("io_setup(%u, [%lu]) = 0\n", nr, ctx);
136
137 if (syscall(__NR_io_submit, ctx, nr, cbs) != (long) nr)
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000138 perror_msg_and_skip("io_submit");
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000139 printf("io_submit(%lu, %u, ["
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000140 "{data=%#llx, pread, reqprio=11, fildes=0, "
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000141 "buf=%p, nbytes=%u, offset=%lld}, "
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000142 "{data=%#llx, pread, reqprio=22, fildes=0, "
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000143 "buf=%p, nbytes=%u, offset=%lld}"
144 "]) = %u\n",
145 ctx, nr,
146 (unsigned long long) cb[0].aio_data, data0,
147 (unsigned int) sizeof(data0), (long long) cb[0].aio_offset,
148 (unsigned long long) cb[1].aio_data, data1,
149 (unsigned int) sizeof(data1), (long long) cb[1].aio_offset,
150 nr);
151
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000152 assert(syscall(__NR_io_getevents, ctx, nr, nr + 1, ev, &ts) == (long) nr);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000153 printf("io_getevents(%lu, %u, %u, ["
154 "{data=%#llx, obj=%p, res=%u, res2=0}, "
155 "{data=%#llx, obj=%p, res=%u, res2=0}"
156 "], {0, 123456789}) = %u\n",
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000157 ctx, nr, nr + 1,
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000158 (unsigned long long) cb[0].aio_data, &cb[0],
159 (unsigned int) sizeof(data0),
160 (unsigned long long) cb[1].aio_data, &cb[1],
161 (unsigned int) sizeof(data1),
162 nr);
163
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000164 assert(syscall(__NR_io_cancel, ctx, &cbc, ev) == -1 && EINVAL == errno);
165 printf("io_cancel(%lu, {data=%#llx, pread, reqprio=99, fildes=-42}, %p) "
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000166 "= -1 EINVAL (%m)\n",
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000167 ctx, (unsigned long long) cbc.aio_data, ev);
168
169 if (syscall(__NR_io_submit, ctx, nr, cbvs) != (long) nr)
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000170 perror_msg_and_skip("io_submit");
Dmitry V. Levinf56046e2015-08-26 17:48:40 +0000171 printf("io_submit(%lu, %u, ["
172 "{data=%#llx, preadv, reqprio=%hd, fildes=0, "
173 "iovec=[{%p, %u}, {%p, %u}], offset=%lld}, "
174 "{data=%#llx, preadv, reqprio=%hd, fildes=0, "
175 "iovec=[{%p, %u}, {%p, %u}], offset=%lld}"
176 "]) = %u\n",
177 ctx, nr,
178 (unsigned long long) cbv[0].aio_data, cbv[0].aio_reqprio,
179 iov0[0].iov_base, (unsigned int) iov0[0].iov_len,
180 iov0[1].iov_base, (unsigned int) iov0[1].iov_len,
181 (long long) cbv[0].aio_offset,
182 (unsigned long long) cbv[1].aio_data, cbv[1].aio_reqprio,
183 iov1[0].iov_base, (unsigned int) iov1[0].iov_len,
184 iov1[1].iov_base, (unsigned int) iov1[1].iov_len,
185 (long long) cbv[1].aio_offset,
186 nr);
187
188 assert(syscall(__NR_io_destroy, ctx) == 0);
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000189 printf("io_destroy(%lu) = 0\n", ctx);
190
191 puts("+++ exited with 0 +++");
192 return 0;
193}
194
195#else
196
Dmitry V. Levin9ad44092016-01-06 11:27:15 +0000197SKIP_MAIN_UNDEFINED("__NR_io_*")
Dmitry V. Levin13c21732015-08-26 12:49:07 +0000198
199#endif