blob: 3a6bc2af09615378886ebcc6a15f2f439cbb4407 [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
Jeff Diked50084a2006-01-06 00:18:50 -0800107 signal(SIGWINCH, SIG_IGN);
Jeff Dike75e55842005-09-03 15:57:45 -0700108
Jeff Dikeba180fd2007-10-16 01:27:00 -0700109 while (1) {
Jeff Diked50084a2006-01-06 00:18:50 -0800110 n = io_getevents(ctx, 1, 1, &event, NULL);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700111 if (n < 0) {
112 if (errno == EINTR)
Jeff Diked50084a2006-01-06 00:18:50 -0800113 continue;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700114 printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
Jeff Diked50084a2006-01-06 00:18:50 -0800115 "errno = %d\n", errno);
116 }
117 else {
118 reply = ((struct aio_thread_reply)
119 { .data = (void *) (long) event.data,
120 .err = event.res });
Jeff Dike91acb212005-10-10 23:10:32 -0400121 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
Jeff Dikea61f3342007-05-06 14:51:35 -0700122 err = write(reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700123 if (err != sizeof(reply))
124 printk(UM_KERN_ERR "aio_thread - write failed, "
125 "fd = %d, err = %d\n", reply_fd, errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800126 }
127 }
128 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700129}
130
131#endif
132
Jeff Dike91acb212005-10-10 23:10:32 -0400133static int do_not_aio(struct aio_thread_req *req)
Jeff Dike75e55842005-09-03 15:57:45 -0700134{
Jeff Diked50084a2006-01-06 00:18:50 -0800135 char c;
Jeff Dikeef0470c2007-05-06 14:51:33 -0700136 unsigned long long actual;
Jeff Dikea61f3342007-05-06 14:51:35 -0700137 int n;
Jeff Dike75e55842005-09-03 15:57:45 -0700138
Jeff Dikeef0470c2007-05-06 14:51:33 -0700139 actual = lseek64(req->io_fd, req->offset, SEEK_SET);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700140 if (actual != req->offset)
Jeff Dikeef0470c2007-05-06 14:51:33 -0700141 return -errno;
142
Jeff Dike5134d8f2008-02-08 04:22:08 -0800143 switch (req->type) {
Jeff Diked50084a2006-01-06 00:18:50 -0800144 case AIO_READ:
Jeff Dikea61f3342007-05-06 14:51:35 -0700145 n = read(req->io_fd, req->buf, req->len);
Jeff Diked50084a2006-01-06 00:18:50 -0800146 break;
147 case AIO_WRITE:
Jeff Dikea61f3342007-05-06 14:51:35 -0700148 n = write(req->io_fd, req->buf, req->len);
Jeff Diked50084a2006-01-06 00:18:50 -0800149 break;
150 case AIO_MMAP:
Jeff Dikea61f3342007-05-06 14:51:35 -0700151 n = read(req->io_fd, &c, sizeof(c));
Jeff Diked50084a2006-01-06 00:18:50 -0800152 break;
153 default:
Jeff Dikeba180fd2007-10-16 01:27:00 -0700154 printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
155 req->type);
Jeff Dikea61f3342007-05-06 14:51:35 -0700156 return -EINVAL;
Jeff Diked50084a2006-01-06 00:18:50 -0800157 }
Jeff Dike75e55842005-09-03 15:57:45 -0700158
Jeff Dikeba180fd2007-10-16 01:27:00 -0700159 if (n < 0)
Jeff Dikea61f3342007-05-06 14:51:35 -0700160 return -errno;
161 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700162}
163
Jeff Dike9683da92007-02-10 01:44:27 -0800164/* These are initialized in initcalls and not changed */
165static int aio_req_fd_r = -1;
166static int aio_req_fd_w = -1;
167static int aio_pid = -1;
Jeff Dikec4399012007-07-15 23:38:56 -0700168static unsigned long aio_stack;
Jeff Dike9683da92007-02-10 01:44:27 -0800169
Jeff Dike75e55842005-09-03 15:57:45 -0700170static int not_aio_thread(void *arg)
171{
Jeff Diked50084a2006-01-06 00:18:50 -0800172 struct aio_thread_req req;
173 struct aio_thread_reply reply;
174 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700175
Jeff Diked50084a2006-01-06 00:18:50 -0800176 signal(SIGWINCH, SIG_IGN);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700177 while (1) {
Jeff Dikea61f3342007-05-06 14:51:35 -0700178 err = read(aio_req_fd_r, &req, sizeof(req));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700179 if (err != sizeof(req)) {
180 if (err < 0)
181 printk(UM_KERN_ERR "not_aio_thread - "
182 "read failed, fd = %d, err = %d\n",
183 aio_req_fd_r,
Jeff Dikea61f3342007-05-06 14:51:35 -0700184 errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800185 else {
Jeff Dikeba180fd2007-10-16 01:27:00 -0700186 printk(UM_KERN_ERR "not_aio_thread - short "
187 "read, fd = %d, length = %d\n",
188 aio_req_fd_r, err);
Jeff Diked50084a2006-01-06 00:18:50 -0800189 }
190 continue;
191 }
192 err = do_not_aio(&req);
193 reply = ((struct aio_thread_reply) { .data = req.aio,
Jeff Dikeef0470c2007-05-06 14:51:33 -0700194 .err = err });
Jeff Dikea61f3342007-05-06 14:51:35 -0700195 err = write(req.aio->reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700196 if (err != sizeof(reply))
197 printk(UM_KERN_ERR "not_aio_thread - write failed, "
198 "fd = %d, err = %d\n", req.aio->reply_fd, errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800199 }
Jeff Dike1b57e9c2006-01-06 00:18:49 -0800200
201 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700202}
203
Jeff Dike75e55842005-09-03 15:57:45 -0700204static int init_aio_24(void)
205{
Jeff Diked50084a2006-01-06 00:18:50 -0800206 int fds[2], err;
Jeff Dike75e55842005-09-03 15:57:45 -0700207
Jeff Diked50084a2006-01-06 00:18:50 -0800208 err = os_pipe(fds, 1, 1);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700209 if (err)
Jeff Diked50084a2006-01-06 00:18:50 -0800210 goto out;
Jeff Dike75e55842005-09-03 15:57:45 -0700211
Jeff Diked50084a2006-01-06 00:18:50 -0800212 aio_req_fd_w = fds[0];
213 aio_req_fd_r = fds[1];
Jeff Dike8603ec82007-05-06 14:51:44 -0700214
215 err = os_set_fd_block(aio_req_fd_w, 0);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700216 if (err)
Jeff Dike8603ec82007-05-06 14:51:44 -0700217 goto out_close_pipe;
218
Jeff Diked50084a2006-01-06 00:18:50 -0800219 err = run_helper_thread(not_aio_thread, NULL,
Stanislaw Gruszka4dbed852007-12-17 16:19:46 -0800220 CLONE_FILES | CLONE_VM, &aio_stack);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700221 if (err < 0)
Jeff Diked50084a2006-01-06 00:18:50 -0800222 goto out_close_pipe;
Jeff Dike75e55842005-09-03 15:57:45 -0700223
Jeff Diked50084a2006-01-06 00:18:50 -0800224 aio_pid = err;
225 goto out;
Jeff Dike75e55842005-09-03 15:57:45 -0700226
Jeff Diked50084a2006-01-06 00:18:50 -0800227out_close_pipe:
Jeff Dike512b6fb2007-10-16 01:27:11 -0700228 close(fds[0]);
229 close(fds[1]);
Jeff Diked50084a2006-01-06 00:18:50 -0800230 aio_req_fd_w = -1;
231 aio_req_fd_r = -1;
232out:
Jeff Dike75e55842005-09-03 15:57:45 -0700233#ifndef HAVE_AIO_ABI
Jeff Dikeba180fd2007-10-16 01:27:00 -0700234 printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
235 "build\n");
Jeff Dike75e55842005-09-03 15:57:45 -0700236#endif
Jeff Dikeba180fd2007-10-16 01:27:00 -0700237 printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
238 "I/O thread\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800239 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700240}
241
242#ifdef HAVE_AIO_ABI
243#define DEFAULT_24_AIO 0
244static int init_aio_26(void)
245{
Jeff Diked50084a2006-01-06 00:18:50 -0800246 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700247
Jeff Dikeba180fd2007-10-16 01:27:00 -0700248 if (io_setup(256, &ctx)) {
Jeff Dikeb4fd3102005-09-16 19:27:49 -0700249 err = -errno;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700250 printk(UM_KERN_ERR "aio_thread failed to initialize context, "
251 "err = %d\n", errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800252 return err;
253 }
Jeff Dike75e55842005-09-03 15:57:45 -0700254
Jeff Diked50084a2006-01-06 00:18:50 -0800255 err = run_helper_thread(aio_thread, NULL,
Stanislaw Gruszka4dbed852007-12-17 16:19:46 -0800256 CLONE_FILES | CLONE_VM, &aio_stack);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700257 if (err < 0)
Jeff Diked50084a2006-01-06 00:18:50 -0800258 return err;
Jeff Dike75e55842005-09-03 15:57:45 -0700259
Jeff Diked50084a2006-01-06 00:18:50 -0800260 aio_pid = err;
Jeff Dike75e55842005-09-03 15:57:45 -0700261
Jeff Dikeba180fd2007-10-16 01:27:00 -0700262 printk(UM_KERN_INFO "Using 2.6 host AIO\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800263 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700264}
265
Jeff Dike91acb212005-10-10 23:10:32 -0400266static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
267 unsigned long long offset, struct aio_context *aio)
268{
Jeff Diked50084a2006-01-06 00:18:50 -0800269 struct aio_thread_reply reply;
270 int err;
Jeff Dike91acb212005-10-10 23:10:32 -0400271
Jeff Diked50084a2006-01-06 00:18:50 -0800272 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700273 if (err) {
Jeff Diked50084a2006-01-06 00:18:50 -0800274 reply = ((struct aio_thread_reply) { .data = aio,
275 .err = err });
Jeff Dikea61f3342007-05-06 14:51:35 -0700276 err = write(aio->reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700277 if (err != sizeof(reply)) {
Jeff Dikea61f3342007-05-06 14:51:35 -0700278 err = -errno;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700279 printk(UM_KERN_ERR "submit_aio_26 - write failed, "
Jeff Diked50084a2006-01-06 00:18:50 -0800280 "fd = %d, err = %d\n", aio->reply_fd, -err);
Jeff Dikea61f3342007-05-06 14:51:35 -0700281 }
Jeff Diked50084a2006-01-06 00:18:50 -0800282 else err = 0;
283 }
Jeff Dike91acb212005-10-10 23:10:32 -0400284
Jeff Diked50084a2006-01-06 00:18:50 -0800285 return err;
Jeff Dike91acb212005-10-10 23:10:32 -0400286}
287
Jeff Dike75e55842005-09-03 15:57:45 -0700288#else
289#define DEFAULT_24_AIO 1
Jeff Dike91acb212005-10-10 23:10:32 -0400290static int init_aio_26(void)
Jeff Dike75e55842005-09-03 15:57:45 -0700291{
Jeff Diked50084a2006-01-06 00:18:50 -0800292 return -ENOSYS;
Jeff Dike75e55842005-09-03 15:57:45 -0700293}
294
Jeff Dike91acb212005-10-10 23:10:32 -0400295static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
296 unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -0700297{
Jeff Diked50084a2006-01-06 00:18:50 -0800298 return -ENOSYS;
Jeff Dike75e55842005-09-03 15:57:45 -0700299}
300#endif
301
Jeff Dike9683da92007-02-10 01:44:27 -0800302/* Initialized in an initcall and unchanged thereafter */
Jeff Dike75e55842005-09-03 15:57:45 -0700303static int aio_24 = DEFAULT_24_AIO;
304
305static int __init set_aio_24(char *name, int *add)
306{
Jeff Diked50084a2006-01-06 00:18:50 -0800307 aio_24 = 1;
308 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700309}
310
311__uml_setup("aio=2.4", set_aio_24,
312"aio=2.4\n"
313" This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n"
314" available. 2.4 AIO is a single thread that handles one request at a\n"
315" time, synchronously. 2.6 AIO is a thread which uses the 2.6 AIO \n"
316" interface to handle an arbitrary number of pending requests. 2.6 AIO \n"
317" is not available in tt mode, on 2.4 hosts, or when UML is built with\n"
318" /usr/include/linux/aio_abi.h not available. Many distributions don't\n"
319" include aio_abi.h, so you will need to copy it from a kernel tree to\n"
320" your /usr/include/linux in order to build an AIO-capable UML\n\n"
321);
322
323static int init_aio(void)
324{
Jeff Diked50084a2006-01-06 00:18:50 -0800325 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700326
Jeff Dikeba180fd2007-10-16 01:27:00 -0700327 if (!aio_24) {
Jeff Diked50084a2006-01-06 00:18:50 -0800328 err = init_aio_26();
Jeff Dikeba180fd2007-10-16 01:27:00 -0700329 if (err && (errno == ENOSYS)) {
330 printk(UM_KERN_INFO "2.6 AIO not supported on the "
331 "host - reverting to 2.4 AIO\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800332 aio_24 = 1;
333 }
334 else return err;
335 }
Jeff Dike75e55842005-09-03 15:57:45 -0700336
Jeff Dikeba180fd2007-10-16 01:27:00 -0700337 if (aio_24)
Jeff Diked50084a2006-01-06 00:18:50 -0800338 return init_aio_24();
Jeff Dike75e55842005-09-03 15:57:45 -0700339
Jeff Diked50084a2006-01-06 00:18:50 -0800340 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700341}
342
Jeff Dikeba180fd2007-10-16 01:27:00 -0700343/*
344 * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
Jeff Dike75e55842005-09-03 15:57:45 -0700345 * needs to be called when the kernel is running because it calls run_helper,
346 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic
347 * kernel does not run __exitcalls on shutdown, and can't because many of them
348 * break when called outside of module unloading.
349 */
350__initcall(init_aio);
351
352static void exit_aio(void)
353{
Jeff Dikec4399012007-07-15 23:38:56 -0700354 if (aio_pid != -1) {
Jeff Diked50084a2006-01-06 00:18:50 -0800355 os_kill_process(aio_pid, 1);
Jeff Dikec4399012007-07-15 23:38:56 -0700356 free_stack(aio_stack, 0);
357 }
Jeff Dike75e55842005-09-03 15:57:45 -0700358}
359
360__uml_exitcall(exit_aio);
361
Jeff Dike91acb212005-10-10 23:10:32 -0400362static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
363 unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -0700364{
Jeff Diked50084a2006-01-06 00:18:50 -0800365 struct aio_thread_req req = { .type = type,
366 .io_fd = io_fd,
367 .offset = offset,
368 .buf = buf,
369 .len = len,
370 .aio = aio,
371 };
372 int err;
Jeff Dike91acb212005-10-10 23:10:32 -0400373
Jeff Dikea61f3342007-05-06 14:51:35 -0700374 err = write(aio_req_fd_w, &req, sizeof(req));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700375 if (err == sizeof(req))
Jeff Diked50084a2006-01-06 00:18:50 -0800376 err = 0;
Jeff Dikea61f3342007-05-06 14:51:35 -0700377 else err = -errno;
Jeff Dike91acb212005-10-10 23:10:32 -0400378
Jeff Diked50084a2006-01-06 00:18:50 -0800379 return err;
Jeff Dike91acb212005-10-10 23:10:32 -0400380}
381
382int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
Jeff Diked50084a2006-01-06 00:18:50 -0800383 unsigned long long offset, int reply_fd,
384 struct aio_context *aio)
Jeff Dike91acb212005-10-10 23:10:32 -0400385{
Jeff Diked50084a2006-01-06 00:18:50 -0800386 aio->reply_fd = reply_fd;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700387 if (aio_24)
Jeff Diked50084a2006-01-06 00:18:50 -0800388 return submit_aio_24(type, io_fd, buf, len, offset, aio);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700389 else
Jeff Diked50084a2006-01-06 00:18:50 -0800390 return submit_aio_26(type, io_fd, buf, len, offset, aio);
Jeff Dike75e55842005-09-03 15:57:45 -0700391}