blob: 014eb35fd13b424dd03fc1b7b03f159815106c28 [file] [log] [blame]
Jeff Dike75e55842005-09-03 15:57:45 -07001/*
Jeff Dikeba180fd2007-10-16 01:27:00 -07002 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
Jeff Dike75e55842005-09-03 15:57:45 -07003 * Licensed under the GPL
4 */
5
Jeff Dike75e55842005-09-03 15:57:45 -07006#include <unistd.h>
Jeff Dikeba180fd2007-10-16 01:27:00 -07007#include <sched.h>
Jeff Dike75e55842005-09-03 15:57:45 -07008#include <signal.h>
9#include <errno.h>
Jeff Dikeba180fd2007-10-16 01:27:00 -070010#include <sys/time.h>
11#include <asm/unistd.h>
Al Viro37185b32012-10-08 03:27:32 +010012#include <aio.h>
13#include <init.h>
14#include <kern_util.h>
15#include <os.h>
Jeff Dike75e55842005-09-03 15:57:45 -070016
Jeff Dike91acb212005-10-10 23:10:32 -040017struct aio_thread_req {
Jeff Diked50084a2006-01-06 00:18:50 -080018 enum aio_type type;
19 int io_fd;
20 unsigned long long offset;
21 char *buf;
22 int len;
23 struct aio_context *aio;
Jeff Dike91acb212005-10-10 23:10:32 -040024};
25
Jeff Dike75e55842005-09-03 15:57:45 -070026#if defined(HAVE_AIO_ABI)
27#include <linux/aio_abi.h>
28
Jeff Dikeba180fd2007-10-16 01:27:00 -070029/*
30 * If we have the headers, we are going to build with AIO enabled.
Jeff Dike75e55842005-09-03 15:57:45 -070031 * If we don't have aio in libc, we define the necessary stubs here.
32 */
33
34#if !defined(HAVE_AIO_LIBC)
35
36static long io_setup(int n, aio_context_t *ctxp)
37{
Jeff Diked50084a2006-01-06 00:18:50 -080038 return syscall(__NR_io_setup, n, ctxp);
Jeff Dike75e55842005-09-03 15:57:45 -070039}
40
41static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
42{
Jeff Diked50084a2006-01-06 00:18:50 -080043 return syscall(__NR_io_submit, ctx, nr, iocbpp);
Jeff Dike75e55842005-09-03 15:57:45 -070044}
45
46static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
Jeff Diked50084a2006-01-06 00:18:50 -080047 struct io_event *events, struct timespec *timeout)
Jeff Dike75e55842005-09-03 15:57:45 -070048{
Jeff Diked50084a2006-01-06 00:18:50 -080049 return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
Jeff Dike75e55842005-09-03 15:57:45 -070050}
51
52#endif
53
Jeff Dikeba180fd2007-10-16 01:27:00 -070054/*
55 * The AIO_MMAP cases force the mmapped page into memory here
Jeff Dike75e55842005-09-03 15:57:45 -070056 * rather than in whatever place first touches the data. I used
57 * to do this by touching the page, but that's delicate because
58 * gcc is prone to optimizing that away. So, what's done here
59 * is we read from the descriptor from which the page was
60 * mapped. The caller is required to pass an offset which is
61 * inside the page that was mapped. Thus, when the read
62 * returns, we know that the page is in the page cache, and
63 * that it now backs the mmapped area.
64 */
65
Jeff Dike91acb212005-10-10 23:10:32 -040066static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
Jeff Diked50084a2006-01-06 00:18:50 -080067 int len, unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -070068{
Jeff Dikeda3e30e2007-07-23 18:43:47 -070069 struct iocb *iocbp = & ((struct iocb) {
70 .aio_data = (unsigned long) aio,
71 .aio_fildes = fd,
72 .aio_buf = (unsigned long) buf,
73 .aio_nbytes = len,
74 .aio_offset = offset
75 });
Jeff Diked50084a2006-01-06 00:18:50 -080076 char c;
Jeff Dike75e55842005-09-03 15:57:45 -070077
Jeff Dikeda3e30e2007-07-23 18:43:47 -070078 switch (type) {
Jeff Diked50084a2006-01-06 00:18:50 -080079 case AIO_READ:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070080 iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
Jeff Diked50084a2006-01-06 00:18:50 -080081 break;
82 case AIO_WRITE:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070083 iocbp->aio_lio_opcode = IOCB_CMD_PWRITE;
Jeff Diked50084a2006-01-06 00:18:50 -080084 break;
85 case AIO_MMAP:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070086 iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
87 iocbp->aio_buf = (unsigned long) &c;
88 iocbp->aio_nbytes = sizeof(c);
Jeff Diked50084a2006-01-06 00:18:50 -080089 break;
90 default:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070091 printk(UM_KERN_ERR "Bogus op in do_aio - %d\n", type);
92 return -EINVAL;
Jeff Diked50084a2006-01-06 00:18:50 -080093 }
Jeff Dike09ace812005-09-03 15:57:46 -070094
Jeff Dikeda3e30e2007-07-23 18:43:47 -070095 return (io_submit(ctx, 1, &iocbp) > 0) ? 0 : -errno;
Jeff Dike75e55842005-09-03 15:57:45 -070096}
97
Jeff Dike9683da92007-02-10 01:44:27 -080098/* Initialized in an initcall and unchanged thereafter */
Jeff Dike75e55842005-09-03 15:57:45 -070099static aio_context_t ctx = 0;
100
101static int aio_thread(void *arg)
102{
Jeff Diked50084a2006-01-06 00:18:50 -0800103 struct aio_thread_reply reply;
104 struct io_event event;
105 int err, n, reply_fd;
Jeff Dike75e55842005-09-03 15:57:45 -0700106
Richard Weinberger91d44ff2013-08-18 13:30:08 +0200107 os_fix_helper_signals();
Jeff Dikeba180fd2007-10-16 01:27:00 -0700108 while (1) {
Jeff Diked50084a2006-01-06 00:18:50 -0800109 n = io_getevents(ctx, 1, 1, &event, NULL);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700110 if (n < 0) {
111 if (errno == EINTR)
Jeff Diked50084a2006-01-06 00:18:50 -0800112 continue;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700113 printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
Jeff Diked50084a2006-01-06 00:18:50 -0800114 "errno = %d\n", errno);
115 }
116 else {
117 reply = ((struct aio_thread_reply)
118 { .data = (void *) (long) event.data,
119 .err = event.res });
Jeff Dike91acb212005-10-10 23:10:32 -0400120 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
Jeff Dikea61f3342007-05-06 14:51:35 -0700121 err = write(reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700122 if (err != sizeof(reply))
123 printk(UM_KERN_ERR "aio_thread - write failed, "
124 "fd = %d, err = %d\n", reply_fd, errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800125 }
126 }
127 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700128}
129
130#endif
131
Jeff Dike91acb212005-10-10 23:10:32 -0400132static int do_not_aio(struct aio_thread_req *req)
Jeff Dike75e55842005-09-03 15:57:45 -0700133{
Jeff Diked50084a2006-01-06 00:18:50 -0800134 char c;
Jeff Dikeef0470c2007-05-06 14:51:33 -0700135 unsigned long long actual;
Jeff Dikea61f3342007-05-06 14:51:35 -0700136 int n;
Jeff Dike75e55842005-09-03 15:57:45 -0700137
Jeff Dikeef0470c2007-05-06 14:51:33 -0700138 actual = lseek64(req->io_fd, req->offset, SEEK_SET);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700139 if (actual != req->offset)
Jeff Dikeef0470c2007-05-06 14:51:33 -0700140 return -errno;
141
Jeff Dike5134d8f2008-02-08 04:22:08 -0800142 switch (req->type) {
Jeff Diked50084a2006-01-06 00:18:50 -0800143 case AIO_READ:
Jeff Dikea61f3342007-05-06 14:51:35 -0700144 n = read(req->io_fd, req->buf, req->len);
Jeff Diked50084a2006-01-06 00:18:50 -0800145 break;
146 case AIO_WRITE:
Jeff Dikea61f3342007-05-06 14:51:35 -0700147 n = write(req->io_fd, req->buf, req->len);
Jeff Diked50084a2006-01-06 00:18:50 -0800148 break;
149 case AIO_MMAP:
Jeff Dikea61f3342007-05-06 14:51:35 -0700150 n = read(req->io_fd, &c, sizeof(c));
Jeff Diked50084a2006-01-06 00:18:50 -0800151 break;
152 default:
Jeff Dikeba180fd2007-10-16 01:27:00 -0700153 printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
154 req->type);
Jeff Dikea61f3342007-05-06 14:51:35 -0700155 return -EINVAL;
Jeff Diked50084a2006-01-06 00:18:50 -0800156 }
Jeff Dike75e55842005-09-03 15:57:45 -0700157
Jeff Dikeba180fd2007-10-16 01:27:00 -0700158 if (n < 0)
Jeff Dikea61f3342007-05-06 14:51:35 -0700159 return -errno;
160 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700161}
162
Jeff Dike9683da92007-02-10 01:44:27 -0800163/* These are initialized in initcalls and not changed */
164static int aio_req_fd_r = -1;
165static int aio_req_fd_w = -1;
166static int aio_pid = -1;
Jeff Dikec4399012007-07-15 23:38:56 -0700167static unsigned long aio_stack;
Jeff Dike9683da92007-02-10 01:44:27 -0800168
Jeff Dike75e55842005-09-03 15:57:45 -0700169static int not_aio_thread(void *arg)
170{
Jeff Diked50084a2006-01-06 00:18:50 -0800171 struct aio_thread_req req;
172 struct aio_thread_reply reply;
173 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700174
Richard Weinberger91d44ff2013-08-18 13:30:08 +0200175 os_fix_helper_signals();
Jeff Dikeba180fd2007-10-16 01:27:00 -0700176 while (1) {
Jeff Dikea61f3342007-05-06 14:51:35 -0700177 err = read(aio_req_fd_r, &req, sizeof(req));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700178 if (err != sizeof(req)) {
179 if (err < 0)
180 printk(UM_KERN_ERR "not_aio_thread - "
181 "read failed, fd = %d, err = %d\n",
182 aio_req_fd_r,
Jeff Dikea61f3342007-05-06 14:51:35 -0700183 errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800184 else {
Jeff Dikeba180fd2007-10-16 01:27:00 -0700185 printk(UM_KERN_ERR "not_aio_thread - short "
186 "read, fd = %d, length = %d\n",
187 aio_req_fd_r, err);
Jeff Diked50084a2006-01-06 00:18:50 -0800188 }
189 continue;
190 }
191 err = do_not_aio(&req);
192 reply = ((struct aio_thread_reply) { .data = req.aio,
Jeff Dikeef0470c2007-05-06 14:51:33 -0700193 .err = err });
Jeff Dikea61f3342007-05-06 14:51:35 -0700194 err = write(req.aio->reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700195 if (err != sizeof(reply))
196 printk(UM_KERN_ERR "not_aio_thread - write failed, "
197 "fd = %d, err = %d\n", req.aio->reply_fd, errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800198 }
Jeff Dike1b57e9c2006-01-06 00:18:49 -0800199
200 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700201}
202
Jeff Dike75e55842005-09-03 15:57:45 -0700203static int init_aio_24(void)
204{
Jeff Diked50084a2006-01-06 00:18:50 -0800205 int fds[2], err;
Jeff Dike75e55842005-09-03 15:57:45 -0700206
Jeff Diked50084a2006-01-06 00:18:50 -0800207 err = os_pipe(fds, 1, 1);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700208 if (err)
Jeff Diked50084a2006-01-06 00:18:50 -0800209 goto out;
Jeff Dike75e55842005-09-03 15:57:45 -0700210
Jeff Diked50084a2006-01-06 00:18:50 -0800211 aio_req_fd_w = fds[0];
212 aio_req_fd_r = fds[1];
Jeff Dike8603ec82007-05-06 14:51:44 -0700213
214 err = os_set_fd_block(aio_req_fd_w, 0);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700215 if (err)
Jeff Dike8603ec82007-05-06 14:51:44 -0700216 goto out_close_pipe;
217
Jeff Diked50084a2006-01-06 00:18:50 -0800218 err = run_helper_thread(not_aio_thread, NULL,
Stanislaw Gruszka4dbed852007-12-17 16:19:46 -0800219 CLONE_FILES | CLONE_VM, &aio_stack);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700220 if (err < 0)
Jeff Diked50084a2006-01-06 00:18:50 -0800221 goto out_close_pipe;
Jeff Dike75e55842005-09-03 15:57:45 -0700222
Jeff Diked50084a2006-01-06 00:18:50 -0800223 aio_pid = err;
224 goto out;
Jeff Dike75e55842005-09-03 15:57:45 -0700225
Jeff Diked50084a2006-01-06 00:18:50 -0800226out_close_pipe:
Jeff Dike512b6fb2007-10-16 01:27:11 -0700227 close(fds[0]);
228 close(fds[1]);
Jeff Diked50084a2006-01-06 00:18:50 -0800229 aio_req_fd_w = -1;
230 aio_req_fd_r = -1;
231out:
Jeff Dike75e55842005-09-03 15:57:45 -0700232#ifndef HAVE_AIO_ABI
Jeff Dikeba180fd2007-10-16 01:27:00 -0700233 printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
234 "build\n");
Jeff Dike75e55842005-09-03 15:57:45 -0700235#endif
Jeff Dikeba180fd2007-10-16 01:27:00 -0700236 printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
237 "I/O thread\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800238 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700239}
240
241#ifdef HAVE_AIO_ABI
242#define DEFAULT_24_AIO 0
243static int init_aio_26(void)
244{
Jeff Diked50084a2006-01-06 00:18:50 -0800245 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700246
Jeff Dikeba180fd2007-10-16 01:27:00 -0700247 if (io_setup(256, &ctx)) {
Jeff Dikeb4fd3102005-09-16 19:27:49 -0700248 err = -errno;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700249 printk(UM_KERN_ERR "aio_thread failed to initialize context, "
250 "err = %d\n", errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800251 return err;
252 }
Jeff Dike75e55842005-09-03 15:57:45 -0700253
Jeff Diked50084a2006-01-06 00:18:50 -0800254 err = run_helper_thread(aio_thread, NULL,
Stanislaw Gruszka4dbed852007-12-17 16:19:46 -0800255 CLONE_FILES | CLONE_VM, &aio_stack);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700256 if (err < 0)
Jeff Diked50084a2006-01-06 00:18:50 -0800257 return err;
Jeff Dike75e55842005-09-03 15:57:45 -0700258
Jeff Diked50084a2006-01-06 00:18:50 -0800259 aio_pid = err;
Jeff Dike75e55842005-09-03 15:57:45 -0700260
Jeff Dikeba180fd2007-10-16 01:27:00 -0700261 printk(UM_KERN_INFO "Using 2.6 host AIO\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800262 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700263}
264
Jeff Dike91acb212005-10-10 23:10:32 -0400265static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
266 unsigned long long offset, struct aio_context *aio)
267{
Jeff Diked50084a2006-01-06 00:18:50 -0800268 struct aio_thread_reply reply;
269 int err;
Jeff Dike91acb212005-10-10 23:10:32 -0400270
Jeff Diked50084a2006-01-06 00:18:50 -0800271 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700272 if (err) {
Jeff Diked50084a2006-01-06 00:18:50 -0800273 reply = ((struct aio_thread_reply) { .data = aio,
274 .err = err });
Jeff Dikea61f3342007-05-06 14:51:35 -0700275 err = write(aio->reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700276 if (err != sizeof(reply)) {
Jeff Dikea61f3342007-05-06 14:51:35 -0700277 err = -errno;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700278 printk(UM_KERN_ERR "submit_aio_26 - write failed, "
Jeff Diked50084a2006-01-06 00:18:50 -0800279 "fd = %d, err = %d\n", aio->reply_fd, -err);
Jeff Dikea61f3342007-05-06 14:51:35 -0700280 }
Jeff Diked50084a2006-01-06 00:18:50 -0800281 else err = 0;
282 }
Jeff Dike91acb212005-10-10 23:10:32 -0400283
Jeff Diked50084a2006-01-06 00:18:50 -0800284 return err;
Jeff Dike91acb212005-10-10 23:10:32 -0400285}
286
Jeff Dike75e55842005-09-03 15:57:45 -0700287#else
288#define DEFAULT_24_AIO 1
Jeff Dike91acb212005-10-10 23:10:32 -0400289static int init_aio_26(void)
Jeff Dike75e55842005-09-03 15:57:45 -0700290{
Jeff Diked50084a2006-01-06 00:18:50 -0800291 return -ENOSYS;
Jeff Dike75e55842005-09-03 15:57:45 -0700292}
293
Jeff Dike91acb212005-10-10 23:10:32 -0400294static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
295 unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -0700296{
Jeff Diked50084a2006-01-06 00:18:50 -0800297 return -ENOSYS;
Jeff Dike75e55842005-09-03 15:57:45 -0700298}
299#endif
300
Jeff Dike9683da92007-02-10 01:44:27 -0800301/* Initialized in an initcall and unchanged thereafter */
Jeff Dike75e55842005-09-03 15:57:45 -0700302static int aio_24 = DEFAULT_24_AIO;
303
304static int __init set_aio_24(char *name, int *add)
305{
Jeff Diked50084a2006-01-06 00:18:50 -0800306 aio_24 = 1;
307 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700308}
309
310__uml_setup("aio=2.4", set_aio_24,
311"aio=2.4\n"
312" This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n"
313" available. 2.4 AIO is a single thread that handles one request at a\n"
314" time, synchronously. 2.6 AIO is a thread which uses the 2.6 AIO \n"
315" interface to handle an arbitrary number of pending requests. 2.6 AIO \n"
316" is not available in tt mode, on 2.4 hosts, or when UML is built with\n"
317" /usr/include/linux/aio_abi.h not available. Many distributions don't\n"
318" include aio_abi.h, so you will need to copy it from a kernel tree to\n"
319" your /usr/include/linux in order to build an AIO-capable UML\n\n"
320);
321
322static int init_aio(void)
323{
Jeff Diked50084a2006-01-06 00:18:50 -0800324 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700325
Jeff Dikeba180fd2007-10-16 01:27:00 -0700326 if (!aio_24) {
Jeff Diked50084a2006-01-06 00:18:50 -0800327 err = init_aio_26();
Jeff Dikeba180fd2007-10-16 01:27:00 -0700328 if (err && (errno == ENOSYS)) {
329 printk(UM_KERN_INFO "2.6 AIO not supported on the "
330 "host - reverting to 2.4 AIO\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800331 aio_24 = 1;
332 }
333 else return err;
334 }
Jeff Dike75e55842005-09-03 15:57:45 -0700335
Jeff Dikeba180fd2007-10-16 01:27:00 -0700336 if (aio_24)
Jeff Diked50084a2006-01-06 00:18:50 -0800337 return init_aio_24();
Jeff Dike75e55842005-09-03 15:57:45 -0700338
Jeff Diked50084a2006-01-06 00:18:50 -0800339 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700340}
341
Jeff Dikeba180fd2007-10-16 01:27:00 -0700342/*
343 * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
Jeff Dike75e55842005-09-03 15:57:45 -0700344 * needs to be called when the kernel is running because it calls run_helper,
345 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic
346 * kernel does not run __exitcalls on shutdown, and can't because many of them
347 * break when called outside of module unloading.
348 */
349__initcall(init_aio);
350
351static void exit_aio(void)
352{
Jeff Dikec4399012007-07-15 23:38:56 -0700353 if (aio_pid != -1) {
Jeff Diked50084a2006-01-06 00:18:50 -0800354 os_kill_process(aio_pid, 1);
Jeff Dikec4399012007-07-15 23:38:56 -0700355 free_stack(aio_stack, 0);
356 }
Jeff Dike75e55842005-09-03 15:57:45 -0700357}
358
359__uml_exitcall(exit_aio);
360
Jeff Dike91acb212005-10-10 23:10:32 -0400361static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
362 unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -0700363{
Jeff Diked50084a2006-01-06 00:18:50 -0800364 struct aio_thread_req req = { .type = type,
365 .io_fd = io_fd,
366 .offset = offset,
367 .buf = buf,
368 .len = len,
369 .aio = aio,
370 };
371 int err;
Jeff Dike91acb212005-10-10 23:10:32 -0400372
Jeff Dikea61f3342007-05-06 14:51:35 -0700373 err = write(aio_req_fd_w, &req, sizeof(req));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700374 if (err == sizeof(req))
Jeff Diked50084a2006-01-06 00:18:50 -0800375 err = 0;
Jeff Dikea61f3342007-05-06 14:51:35 -0700376 else err = -errno;
Jeff Dike91acb212005-10-10 23:10:32 -0400377
Jeff Diked50084a2006-01-06 00:18:50 -0800378 return err;
Jeff Dike91acb212005-10-10 23:10:32 -0400379}
380
381int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
Jeff Diked50084a2006-01-06 00:18:50 -0800382 unsigned long long offset, int reply_fd,
383 struct aio_context *aio)
Jeff Dike91acb212005-10-10 23:10:32 -0400384{
Jeff Diked50084a2006-01-06 00:18:50 -0800385 aio->reply_fd = reply_fd;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700386 if (aio_24)
Jeff Diked50084a2006-01-06 00:18:50 -0800387 return submit_aio_24(type, io_fd, buf, len, offset, aio);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700388 else
Jeff Diked50084a2006-01-06 00:18:50 -0800389 return submit_aio_26(type, io_fd, buf, len, offset, aio);
Jeff Dike75e55842005-09-03 15:57:45 -0700390}