blob: 57e3d46c989cf0ba4ec4546d6e613e969537be3e [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>
Jeff Dike75e55842005-09-03 15:57:45 -070012#include "aio.h"
13#include "init.h"
Jeff Dikeda3e30e2007-07-23 18:43:47 -070014#include "kern_constants.h"
Jeff Dikeedea1382008-02-04 22:30:46 -080015#include "kern_util.h"
Jeff Dikeba180fd2007-10-16 01:27:00 -070016#include "os.h"
17#include "user.h"
Jeff Dike75e55842005-09-03 15:57:45 -070018
Jeff Dike91acb212005-10-10 23:10:32 -040019struct aio_thread_req {
Jeff Diked50084a2006-01-06 00:18:50 -080020 enum aio_type type;
21 int io_fd;
22 unsigned long long offset;
23 char *buf;
24 int len;
25 struct aio_context *aio;
Jeff Dike91acb212005-10-10 23:10:32 -040026};
27
Jeff Dike75e55842005-09-03 15:57:45 -070028#if defined(HAVE_AIO_ABI)
29#include <linux/aio_abi.h>
30
Jeff Dikeba180fd2007-10-16 01:27:00 -070031/*
32 * If we have the headers, we are going to build with AIO enabled.
Jeff Dike75e55842005-09-03 15:57:45 -070033 * If we don't have aio in libc, we define the necessary stubs here.
34 */
35
36#if !defined(HAVE_AIO_LIBC)
37
38static long io_setup(int n, aio_context_t *ctxp)
39{
Jeff Diked50084a2006-01-06 00:18:50 -080040 return syscall(__NR_io_setup, n, ctxp);
Jeff Dike75e55842005-09-03 15:57:45 -070041}
42
43static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
44{
Jeff Diked50084a2006-01-06 00:18:50 -080045 return syscall(__NR_io_submit, ctx, nr, iocbpp);
Jeff Dike75e55842005-09-03 15:57:45 -070046}
47
48static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
Jeff Diked50084a2006-01-06 00:18:50 -080049 struct io_event *events, struct timespec *timeout)
Jeff Dike75e55842005-09-03 15:57:45 -070050{
Jeff Diked50084a2006-01-06 00:18:50 -080051 return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
Jeff Dike75e55842005-09-03 15:57:45 -070052}
53
54#endif
55
Jeff Dikeba180fd2007-10-16 01:27:00 -070056/*
57 * The AIO_MMAP cases force the mmapped page into memory here
Jeff Dike75e55842005-09-03 15:57:45 -070058 * rather than in whatever place first touches the data. I used
59 * to do this by touching the page, but that's delicate because
60 * gcc is prone to optimizing that away. So, what's done here
61 * is we read from the descriptor from which the page was
62 * mapped. The caller is required to pass an offset which is
63 * inside the page that was mapped. Thus, when the read
64 * returns, we know that the page is in the page cache, and
65 * that it now backs the mmapped area.
66 */
67
Jeff Dike91acb212005-10-10 23:10:32 -040068static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
Jeff Diked50084a2006-01-06 00:18:50 -080069 int len, unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -070070{
Jeff Dikeda3e30e2007-07-23 18:43:47 -070071 struct iocb *iocbp = & ((struct iocb) {
72 .aio_data = (unsigned long) aio,
73 .aio_fildes = fd,
74 .aio_buf = (unsigned long) buf,
75 .aio_nbytes = len,
76 .aio_offset = offset
77 });
Jeff Diked50084a2006-01-06 00:18:50 -080078 char c;
Jeff Dike75e55842005-09-03 15:57:45 -070079
Jeff Dikeda3e30e2007-07-23 18:43:47 -070080 switch (type) {
Jeff Diked50084a2006-01-06 00:18:50 -080081 case AIO_READ:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070082 iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
Jeff Diked50084a2006-01-06 00:18:50 -080083 break;
84 case AIO_WRITE:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070085 iocbp->aio_lio_opcode = IOCB_CMD_PWRITE;
Jeff Diked50084a2006-01-06 00:18:50 -080086 break;
87 case AIO_MMAP:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070088 iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
89 iocbp->aio_buf = (unsigned long) &c;
90 iocbp->aio_nbytes = sizeof(c);
Jeff Diked50084a2006-01-06 00:18:50 -080091 break;
92 default:
Jeff Dikeda3e30e2007-07-23 18:43:47 -070093 printk(UM_KERN_ERR "Bogus op in do_aio - %d\n", type);
94 return -EINVAL;
Jeff Diked50084a2006-01-06 00:18:50 -080095 }
Jeff Dike09ace812005-09-03 15:57:46 -070096
Jeff Dikeda3e30e2007-07-23 18:43:47 -070097 return (io_submit(ctx, 1, &iocbp) > 0) ? 0 : -errno;
Jeff Dike75e55842005-09-03 15:57:45 -070098}
99
Jeff Dike9683da92007-02-10 01:44:27 -0800100/* Initialized in an initcall and unchanged thereafter */
Jeff Dike75e55842005-09-03 15:57:45 -0700101static aio_context_t ctx = 0;
102
103static int aio_thread(void *arg)
104{
Jeff Diked50084a2006-01-06 00:18:50 -0800105 struct aio_thread_reply reply;
106 struct io_event event;
107 int err, n, reply_fd;
Jeff Dike75e55842005-09-03 15:57:45 -0700108
Jeff Diked50084a2006-01-06 00:18:50 -0800109 signal(SIGWINCH, SIG_IGN);
Jeff Dike75e55842005-09-03 15:57:45 -0700110
Jeff Dikeba180fd2007-10-16 01:27:00 -0700111 while (1) {
Jeff Diked50084a2006-01-06 00:18:50 -0800112 n = io_getevents(ctx, 1, 1, &event, NULL);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700113 if (n < 0) {
114 if (errno == EINTR)
Jeff Diked50084a2006-01-06 00:18:50 -0800115 continue;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700116 printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
Jeff Diked50084a2006-01-06 00:18:50 -0800117 "errno = %d\n", errno);
118 }
119 else {
120 reply = ((struct aio_thread_reply)
121 { .data = (void *) (long) event.data,
122 .err = event.res });
Jeff Dike91acb212005-10-10 23:10:32 -0400123 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
Jeff Dikea61f3342007-05-06 14:51:35 -0700124 err = write(reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700125 if (err != sizeof(reply))
126 printk(UM_KERN_ERR "aio_thread - write failed, "
127 "fd = %d, err = %d\n", reply_fd, errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800128 }
129 }
130 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700131}
132
133#endif
134
Jeff Dike91acb212005-10-10 23:10:32 -0400135static int do_not_aio(struct aio_thread_req *req)
Jeff Dike75e55842005-09-03 15:57:45 -0700136{
Jeff Diked50084a2006-01-06 00:18:50 -0800137 char c;
Jeff Dikeef0470c2007-05-06 14:51:33 -0700138 unsigned long long actual;
Jeff Dikea61f3342007-05-06 14:51:35 -0700139 int n;
Jeff Dike75e55842005-09-03 15:57:45 -0700140
Jeff Dikeef0470c2007-05-06 14:51:33 -0700141 actual = lseek64(req->io_fd, req->offset, SEEK_SET);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700142 if (actual != req->offset)
Jeff Dikeef0470c2007-05-06 14:51:33 -0700143 return -errno;
144
Jeff Dike5134d8f2008-02-08 04:22:08 -0800145 switch (req->type) {
Jeff Diked50084a2006-01-06 00:18:50 -0800146 case AIO_READ:
Jeff Dikea61f3342007-05-06 14:51:35 -0700147 n = read(req->io_fd, req->buf, req->len);
Jeff Diked50084a2006-01-06 00:18:50 -0800148 break;
149 case AIO_WRITE:
Jeff Dikea61f3342007-05-06 14:51:35 -0700150 n = write(req->io_fd, req->buf, req->len);
Jeff Diked50084a2006-01-06 00:18:50 -0800151 break;
152 case AIO_MMAP:
Jeff Dikea61f3342007-05-06 14:51:35 -0700153 n = read(req->io_fd, &c, sizeof(c));
Jeff Diked50084a2006-01-06 00:18:50 -0800154 break;
155 default:
Jeff Dikeba180fd2007-10-16 01:27:00 -0700156 printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
157 req->type);
Jeff Dikea61f3342007-05-06 14:51:35 -0700158 return -EINVAL;
Jeff Diked50084a2006-01-06 00:18:50 -0800159 }
Jeff Dike75e55842005-09-03 15:57:45 -0700160
Jeff Dikeba180fd2007-10-16 01:27:00 -0700161 if (n < 0)
Jeff Dikea61f3342007-05-06 14:51:35 -0700162 return -errno;
163 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700164}
165
Jeff Dike9683da92007-02-10 01:44:27 -0800166/* These are initialized in initcalls and not changed */
167static int aio_req_fd_r = -1;
168static int aio_req_fd_w = -1;
169static int aio_pid = -1;
Jeff Dikec4399012007-07-15 23:38:56 -0700170static unsigned long aio_stack;
Jeff Dike9683da92007-02-10 01:44:27 -0800171
Jeff Dike75e55842005-09-03 15:57:45 -0700172static int not_aio_thread(void *arg)
173{
Jeff Diked50084a2006-01-06 00:18:50 -0800174 struct aio_thread_req req;
175 struct aio_thread_reply reply;
176 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700177
Jeff Diked50084a2006-01-06 00:18:50 -0800178 signal(SIGWINCH, SIG_IGN);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700179 while (1) {
Jeff Dikea61f3342007-05-06 14:51:35 -0700180 err = read(aio_req_fd_r, &req, sizeof(req));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700181 if (err != sizeof(req)) {
182 if (err < 0)
183 printk(UM_KERN_ERR "not_aio_thread - "
184 "read failed, fd = %d, err = %d\n",
185 aio_req_fd_r,
Jeff Dikea61f3342007-05-06 14:51:35 -0700186 errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800187 else {
Jeff Dikeba180fd2007-10-16 01:27:00 -0700188 printk(UM_KERN_ERR "not_aio_thread - short "
189 "read, fd = %d, length = %d\n",
190 aio_req_fd_r, err);
Jeff Diked50084a2006-01-06 00:18:50 -0800191 }
192 continue;
193 }
194 err = do_not_aio(&req);
195 reply = ((struct aio_thread_reply) { .data = req.aio,
Jeff Dikeef0470c2007-05-06 14:51:33 -0700196 .err = err });
Jeff Dikea61f3342007-05-06 14:51:35 -0700197 err = write(req.aio->reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700198 if (err != sizeof(reply))
199 printk(UM_KERN_ERR "not_aio_thread - write failed, "
200 "fd = %d, err = %d\n", req.aio->reply_fd, errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800201 }
Jeff Dike1b57e9c2006-01-06 00:18:49 -0800202
203 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700204}
205
Jeff Dike75e55842005-09-03 15:57:45 -0700206static int init_aio_24(void)
207{
Jeff Diked50084a2006-01-06 00:18:50 -0800208 int fds[2], err;
Jeff Dike75e55842005-09-03 15:57:45 -0700209
Jeff Diked50084a2006-01-06 00:18:50 -0800210 err = os_pipe(fds, 1, 1);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700211 if (err)
Jeff Diked50084a2006-01-06 00:18:50 -0800212 goto out;
Jeff Dike75e55842005-09-03 15:57:45 -0700213
Jeff Diked50084a2006-01-06 00:18:50 -0800214 aio_req_fd_w = fds[0];
215 aio_req_fd_r = fds[1];
Jeff Dike8603ec82007-05-06 14:51:44 -0700216
217 err = os_set_fd_block(aio_req_fd_w, 0);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700218 if (err)
Jeff Dike8603ec82007-05-06 14:51:44 -0700219 goto out_close_pipe;
220
Jeff Diked50084a2006-01-06 00:18:50 -0800221 err = run_helper_thread(not_aio_thread, NULL,
Stanislaw Gruszka4dbed852007-12-17 16:19:46 -0800222 CLONE_FILES | CLONE_VM, &aio_stack);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700223 if (err < 0)
Jeff Diked50084a2006-01-06 00:18:50 -0800224 goto out_close_pipe;
Jeff Dike75e55842005-09-03 15:57:45 -0700225
Jeff Diked50084a2006-01-06 00:18:50 -0800226 aio_pid = err;
227 goto out;
Jeff Dike75e55842005-09-03 15:57:45 -0700228
Jeff Diked50084a2006-01-06 00:18:50 -0800229out_close_pipe:
Jeff Dike512b6fb2007-10-16 01:27:11 -0700230 close(fds[0]);
231 close(fds[1]);
Jeff Diked50084a2006-01-06 00:18:50 -0800232 aio_req_fd_w = -1;
233 aio_req_fd_r = -1;
234out:
Jeff Dike75e55842005-09-03 15:57:45 -0700235#ifndef HAVE_AIO_ABI
Jeff Dikeba180fd2007-10-16 01:27:00 -0700236 printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
237 "build\n");
Jeff Dike75e55842005-09-03 15:57:45 -0700238#endif
Jeff Dikeba180fd2007-10-16 01:27:00 -0700239 printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
240 "I/O thread\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800241 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700242}
243
244#ifdef HAVE_AIO_ABI
245#define DEFAULT_24_AIO 0
246static int init_aio_26(void)
247{
Jeff Diked50084a2006-01-06 00:18:50 -0800248 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700249
Jeff Dikeba180fd2007-10-16 01:27:00 -0700250 if (io_setup(256, &ctx)) {
Jeff Dikeb4fd3102005-09-16 19:27:49 -0700251 err = -errno;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700252 printk(UM_KERN_ERR "aio_thread failed to initialize context, "
253 "err = %d\n", errno);
Jeff Diked50084a2006-01-06 00:18:50 -0800254 return err;
255 }
Jeff Dike75e55842005-09-03 15:57:45 -0700256
Jeff Diked50084a2006-01-06 00:18:50 -0800257 err = run_helper_thread(aio_thread, NULL,
Stanislaw Gruszka4dbed852007-12-17 16:19:46 -0800258 CLONE_FILES | CLONE_VM, &aio_stack);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700259 if (err < 0)
Jeff Diked50084a2006-01-06 00:18:50 -0800260 return err;
Jeff Dike75e55842005-09-03 15:57:45 -0700261
Jeff Diked50084a2006-01-06 00:18:50 -0800262 aio_pid = err;
Jeff Dike75e55842005-09-03 15:57:45 -0700263
Jeff Dikeba180fd2007-10-16 01:27:00 -0700264 printk(UM_KERN_INFO "Using 2.6 host AIO\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800265 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700266}
267
Jeff Dike91acb212005-10-10 23:10:32 -0400268static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
269 unsigned long long offset, struct aio_context *aio)
270{
Jeff Diked50084a2006-01-06 00:18:50 -0800271 struct aio_thread_reply reply;
272 int err;
Jeff Dike91acb212005-10-10 23:10:32 -0400273
Jeff Diked50084a2006-01-06 00:18:50 -0800274 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700275 if (err) {
Jeff Diked50084a2006-01-06 00:18:50 -0800276 reply = ((struct aio_thread_reply) { .data = aio,
277 .err = err });
Jeff Dikea61f3342007-05-06 14:51:35 -0700278 err = write(aio->reply_fd, &reply, sizeof(reply));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700279 if (err != sizeof(reply)) {
Jeff Dikea61f3342007-05-06 14:51:35 -0700280 err = -errno;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700281 printk(UM_KERN_ERR "submit_aio_26 - write failed, "
Jeff Diked50084a2006-01-06 00:18:50 -0800282 "fd = %d, err = %d\n", aio->reply_fd, -err);
Jeff Dikea61f3342007-05-06 14:51:35 -0700283 }
Jeff Diked50084a2006-01-06 00:18:50 -0800284 else err = 0;
285 }
Jeff Dike91acb212005-10-10 23:10:32 -0400286
Jeff Diked50084a2006-01-06 00:18:50 -0800287 return err;
Jeff Dike91acb212005-10-10 23:10:32 -0400288}
289
Jeff Dike75e55842005-09-03 15:57:45 -0700290#else
291#define DEFAULT_24_AIO 1
Jeff Dike91acb212005-10-10 23:10:32 -0400292static int init_aio_26(void)
Jeff Dike75e55842005-09-03 15:57:45 -0700293{
Jeff Diked50084a2006-01-06 00:18:50 -0800294 return -ENOSYS;
Jeff Dike75e55842005-09-03 15:57:45 -0700295}
296
Jeff Dike91acb212005-10-10 23:10:32 -0400297static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
298 unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -0700299{
Jeff Diked50084a2006-01-06 00:18:50 -0800300 return -ENOSYS;
Jeff Dike75e55842005-09-03 15:57:45 -0700301}
302#endif
303
Jeff Dike9683da92007-02-10 01:44:27 -0800304/* Initialized in an initcall and unchanged thereafter */
Jeff Dike75e55842005-09-03 15:57:45 -0700305static int aio_24 = DEFAULT_24_AIO;
306
307static int __init set_aio_24(char *name, int *add)
308{
Jeff Diked50084a2006-01-06 00:18:50 -0800309 aio_24 = 1;
310 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700311}
312
313__uml_setup("aio=2.4", set_aio_24,
314"aio=2.4\n"
315" This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n"
316" available. 2.4 AIO is a single thread that handles one request at a\n"
317" time, synchronously. 2.6 AIO is a thread which uses the 2.6 AIO \n"
318" interface to handle an arbitrary number of pending requests. 2.6 AIO \n"
319" is not available in tt mode, on 2.4 hosts, or when UML is built with\n"
320" /usr/include/linux/aio_abi.h not available. Many distributions don't\n"
321" include aio_abi.h, so you will need to copy it from a kernel tree to\n"
322" your /usr/include/linux in order to build an AIO-capable UML\n\n"
323);
324
325static int init_aio(void)
326{
Jeff Diked50084a2006-01-06 00:18:50 -0800327 int err;
Jeff Dike75e55842005-09-03 15:57:45 -0700328
Jeff Dikeba180fd2007-10-16 01:27:00 -0700329 if (!aio_24) {
Jeff Diked50084a2006-01-06 00:18:50 -0800330 err = init_aio_26();
Jeff Dikeba180fd2007-10-16 01:27:00 -0700331 if (err && (errno == ENOSYS)) {
332 printk(UM_KERN_INFO "2.6 AIO not supported on the "
333 "host - reverting to 2.4 AIO\n");
Jeff Diked50084a2006-01-06 00:18:50 -0800334 aio_24 = 1;
335 }
336 else return err;
337 }
Jeff Dike75e55842005-09-03 15:57:45 -0700338
Jeff Dikeba180fd2007-10-16 01:27:00 -0700339 if (aio_24)
Jeff Diked50084a2006-01-06 00:18:50 -0800340 return init_aio_24();
Jeff Dike75e55842005-09-03 15:57:45 -0700341
Jeff Diked50084a2006-01-06 00:18:50 -0800342 return 0;
Jeff Dike75e55842005-09-03 15:57:45 -0700343}
344
Jeff Dikeba180fd2007-10-16 01:27:00 -0700345/*
346 * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
Jeff Dike75e55842005-09-03 15:57:45 -0700347 * needs to be called when the kernel is running because it calls run_helper,
348 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic
349 * kernel does not run __exitcalls on shutdown, and can't because many of them
350 * break when called outside of module unloading.
351 */
352__initcall(init_aio);
353
354static void exit_aio(void)
355{
Jeff Dikec4399012007-07-15 23:38:56 -0700356 if (aio_pid != -1) {
Jeff Diked50084a2006-01-06 00:18:50 -0800357 os_kill_process(aio_pid, 1);
Jeff Dikec4399012007-07-15 23:38:56 -0700358 free_stack(aio_stack, 0);
359 }
Jeff Dike75e55842005-09-03 15:57:45 -0700360}
361
362__uml_exitcall(exit_aio);
363
Jeff Dike91acb212005-10-10 23:10:32 -0400364static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
365 unsigned long long offset, struct aio_context *aio)
Jeff Dike75e55842005-09-03 15:57:45 -0700366{
Jeff Diked50084a2006-01-06 00:18:50 -0800367 struct aio_thread_req req = { .type = type,
368 .io_fd = io_fd,
369 .offset = offset,
370 .buf = buf,
371 .len = len,
372 .aio = aio,
373 };
374 int err;
Jeff Dike91acb212005-10-10 23:10:32 -0400375
Jeff Dikea61f3342007-05-06 14:51:35 -0700376 err = write(aio_req_fd_w, &req, sizeof(req));
Jeff Dikeba180fd2007-10-16 01:27:00 -0700377 if (err == sizeof(req))
Jeff Diked50084a2006-01-06 00:18:50 -0800378 err = 0;
Jeff Dikea61f3342007-05-06 14:51:35 -0700379 else err = -errno;
Jeff Dike91acb212005-10-10 23:10:32 -0400380
Jeff Diked50084a2006-01-06 00:18:50 -0800381 return err;
Jeff Dike91acb212005-10-10 23:10:32 -0400382}
383
384int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
Jeff Diked50084a2006-01-06 00:18:50 -0800385 unsigned long long offset, int reply_fd,
386 struct aio_context *aio)
Jeff Dike91acb212005-10-10 23:10:32 -0400387{
Jeff Diked50084a2006-01-06 00:18:50 -0800388 aio->reply_fd = reply_fd;
Jeff Dikeba180fd2007-10-16 01:27:00 -0700389 if (aio_24)
Jeff Diked50084a2006-01-06 00:18:50 -0800390 return submit_aio_24(type, io_fd, buf, len, offset, aio);
Jeff Dikeba180fd2007-10-16 01:27:00 -0700391 else
Jeff Diked50084a2006-01-06 00:18:50 -0800392 return submit_aio_26(type, io_fd, buf, len, offset, aio);
Jeff Dike75e55842005-09-03 15:57:45 -0700393}