diff options
Diffstat (limited to 'arch/um/os-Linux/aio.c')
-rw-r--r-- | arch/um/os-Linux/aio.c | 467 |
1 files changed, 234 insertions, 233 deletions
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index ffa759addd3..f897140cc4a 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c | |||
@@ -16,12 +16,12 @@ | |||
16 | #include "mode.h" | 16 | #include "mode.h" |
17 | 17 | ||
18 | struct aio_thread_req { | 18 | struct aio_thread_req { |
19 | enum aio_type type; | 19 | enum aio_type type; |
20 | int io_fd; | 20 | int io_fd; |
21 | unsigned long long offset; | 21 | unsigned long long offset; |
22 | char *buf; | 22 | char *buf; |
23 | int len; | 23 | int len; |
24 | struct aio_context *aio; | 24 | struct aio_context *aio; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static int aio_req_fd_r = -1; | 27 | static int aio_req_fd_r = -1; |
@@ -38,18 +38,18 @@ static int aio_req_fd_w = -1; | |||
38 | 38 | ||
39 | static long io_setup(int n, aio_context_t *ctxp) | 39 | static long io_setup(int n, aio_context_t *ctxp) |
40 | { | 40 | { |
41 | return syscall(__NR_io_setup, n, ctxp); | 41 | return syscall(__NR_io_setup, n, ctxp); |
42 | } | 42 | } |
43 | 43 | ||
44 | static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) | 44 | static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) |
45 | { | 45 | { |
46 | return syscall(__NR_io_submit, ctx, nr, iocbpp); | 46 | return syscall(__NR_io_submit, ctx, nr, iocbpp); |
47 | } | 47 | } |
48 | 48 | ||
49 | static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, | 49 | static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, |
50 | struct io_event *events, struct timespec *timeout) | 50 | struct io_event *events, struct timespec *timeout) |
51 | { | 51 | { |
52 | return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout); | 52 | return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout); |
53 | } | 53 | } |
54 | 54 | ||
55 | #endif | 55 | #endif |
@@ -66,243 +66,245 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, | |||
66 | */ | 66 | */ |
67 | 67 | ||
68 | static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, | 68 | static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, |
69 | int len, unsigned long long offset, struct aio_context *aio) | 69 | int len, unsigned long long offset, struct aio_context *aio) |
70 | { | 70 | { |
71 | struct iocb iocb, *iocbp = &iocb; | 71 | struct iocb iocb, *iocbp = &iocb; |
72 | char c; | 72 | char c; |
73 | int err; | 73 | int err; |
74 | 74 | ||
75 | iocb = ((struct iocb) { .aio_data = (unsigned long) aio, | 75 | iocb = ((struct iocb) { .aio_data = (unsigned long) aio, |
76 | .aio_reqprio = 0, | 76 | .aio_reqprio = 0, |
77 | .aio_fildes = fd, | 77 | .aio_fildes = fd, |
78 | .aio_buf = (unsigned long) buf, | 78 | .aio_buf = (unsigned long) buf, |
79 | .aio_nbytes = len, | 79 | .aio_nbytes = len, |
80 | .aio_offset = offset, | 80 | .aio_offset = offset, |
81 | .aio_reserved1 = 0, | 81 | .aio_reserved1 = 0, |
82 | .aio_reserved2 = 0, | 82 | .aio_reserved2 = 0, |
83 | .aio_reserved3 = 0 }); | 83 | .aio_reserved3 = 0 }); |
84 | 84 | ||
85 | switch(type){ | 85 | switch(type){ |
86 | case AIO_READ: | 86 | case AIO_READ: |
87 | iocb.aio_lio_opcode = IOCB_CMD_PREAD; | 87 | iocb.aio_lio_opcode = IOCB_CMD_PREAD; |
88 | err = io_submit(ctx, 1, &iocbp); | 88 | err = io_submit(ctx, 1, &iocbp); |
89 | break; | 89 | break; |
90 | case AIO_WRITE: | 90 | case AIO_WRITE: |
91 | iocb.aio_lio_opcode = IOCB_CMD_PWRITE; | 91 | iocb.aio_lio_opcode = IOCB_CMD_PWRITE; |
92 | err = io_submit(ctx, 1, &iocbp); | 92 | err = io_submit(ctx, 1, &iocbp); |
93 | break; | 93 | break; |
94 | case AIO_MMAP: | 94 | case AIO_MMAP: |
95 | iocb.aio_lio_opcode = IOCB_CMD_PREAD; | 95 | iocb.aio_lio_opcode = IOCB_CMD_PREAD; |
96 | iocb.aio_buf = (unsigned long) &c; | 96 | iocb.aio_buf = (unsigned long) &c; |
97 | iocb.aio_nbytes = sizeof(c); | 97 | iocb.aio_nbytes = sizeof(c); |
98 | err = io_submit(ctx, 1, &iocbp); | 98 | err = io_submit(ctx, 1, &iocbp); |
99 | break; | 99 | break; |
100 | default: | 100 | default: |
101 | printk("Bogus op in do_aio - %d\n", type); | 101 | printk("Bogus op in do_aio - %d\n", type); |
102 | err = -EINVAL; | 102 | err = -EINVAL; |
103 | break; | 103 | break; |
104 | } | 104 | } |
105 | 105 | ||
106 | if(err > 0) | 106 | if(err > 0) |
107 | err = 0; | 107 | err = 0; |
108 | else | 108 | else |
109 | err = -errno; | 109 | err = -errno; |
110 | 110 | ||
111 | return err; | 111 | return err; |
112 | } | 112 | } |
113 | 113 | ||
114 | static aio_context_t ctx = 0; | 114 | static aio_context_t ctx = 0; |
115 | 115 | ||
116 | static int aio_thread(void *arg) | 116 | static int aio_thread(void *arg) |
117 | { | 117 | { |
118 | struct aio_thread_reply reply; | 118 | struct aio_thread_reply reply; |
119 | struct io_event event; | 119 | struct io_event event; |
120 | int err, n, reply_fd; | 120 | int err, n, reply_fd; |
121 | 121 | ||
122 | signal(SIGWINCH, SIG_IGN); | 122 | signal(SIGWINCH, SIG_IGN); |
123 | 123 | ||
124 | while(1){ | 124 | while(1){ |
125 | n = io_getevents(ctx, 1, 1, &event, NULL); | 125 | n = io_getevents(ctx, 1, 1, &event, NULL); |
126 | if(n < 0){ | 126 | if(n < 0){ |
127 | if(errno == EINTR) | 127 | if(errno == EINTR) |
128 | continue; | 128 | continue; |
129 | printk("aio_thread - io_getevents failed, " | 129 | printk("aio_thread - io_getevents failed, " |
130 | "errno = %d\n", errno); | 130 | "errno = %d\n", errno); |
131 | } | 131 | } |
132 | else { | 132 | else { |
133 | reply = ((struct aio_thread_reply) | 133 | reply = ((struct aio_thread_reply) |
134 | { .data = (void *) (long) event.data, | 134 | { .data = (void *) (long) event.data, |
135 | .err = event.res }); | 135 | .err = event.res }); |
136 | reply_fd = ((struct aio_context *) reply.data)->reply_fd; | 136 | reply_fd = ((struct aio_context *) reply.data)->reply_fd; |
137 | err = os_write_file(reply_fd, &reply, sizeof(reply)); | 137 | err = os_write_file(reply_fd, &reply, sizeof(reply)); |
138 | if(err != sizeof(reply)) | 138 | if(err != sizeof(reply)) |
139 | printk("aio_thread - write failed, fd = %d, " | 139 | printk("aio_thread - write failed, fd = %d, " |
140 | "err = %d\n", aio_req_fd_r, -err); | 140 | "err = %d\n", aio_req_fd_r, -err); |
141 | } | 141 | } |
142 | } | 142 | } |
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | #endif | 146 | #endif |
147 | 147 | ||
148 | static int do_not_aio(struct aio_thread_req *req) | 148 | static int do_not_aio(struct aio_thread_req *req) |
149 | { | 149 | { |
150 | char c; | 150 | char c; |
151 | int err; | 151 | int err; |
152 | 152 | ||
153 | switch(req->type){ | 153 | switch(req->type){ |
154 | case AIO_READ: | 154 | case AIO_READ: |
155 | err = os_seek_file(req->io_fd, req->offset); | 155 | err = os_seek_file(req->io_fd, req->offset); |
156 | if(err) | 156 | if(err) |
157 | goto out; | 157 | goto out; |
158 | 158 | ||
159 | err = os_read_file(req->io_fd, req->buf, req->len); | 159 | err = os_read_file(req->io_fd, req->buf, req->len); |
160 | break; | 160 | break; |
161 | case AIO_WRITE: | 161 | case AIO_WRITE: |
162 | err = os_seek_file(req->io_fd, req->offset); | 162 | err = os_seek_file(req->io_fd, req->offset); |
163 | if(err) | 163 | if(err) |
164 | goto out; | 164 | goto out; |
165 | 165 | ||
166 | err = os_write_file(req->io_fd, req->buf, req->len); | 166 | err = os_write_file(req->io_fd, req->buf, req->len); |
167 | break; | 167 | break; |
168 | case AIO_MMAP: | 168 | case AIO_MMAP: |
169 | err = os_seek_file(req->io_fd, req->offset); | 169 | err = os_seek_file(req->io_fd, req->offset); |
170 | if(err) | 170 | if(err) |
171 | goto out; | 171 | goto out; |
172 | 172 | ||
173 | err = os_read_file(req->io_fd, &c, sizeof(c)); | 173 | err = os_read_file(req->io_fd, &c, sizeof(c)); |
174 | break; | 174 | break; |
175 | default: | 175 | default: |
176 | printk("do_not_aio - bad request type : %d\n", req->type); | 176 | printk("do_not_aio - bad request type : %d\n", req->type); |
177 | err = -EINVAL; | 177 | err = -EINVAL; |
178 | break; | 178 | break; |
179 | } | 179 | } |
180 | 180 | ||
181 | out: | 181 | out: |
182 | return err; | 182 | return err; |
183 | } | 183 | } |
184 | 184 | ||
185 | static int not_aio_thread(void *arg) | 185 | static int not_aio_thread(void *arg) |
186 | { | 186 | { |
187 | struct aio_thread_req req; | 187 | struct aio_thread_req req; |
188 | struct aio_thread_reply reply; | 188 | struct aio_thread_reply reply; |
189 | int err; | 189 | int err; |
190 | 190 | ||
191 | signal(SIGWINCH, SIG_IGN); | 191 | signal(SIGWINCH, SIG_IGN); |
192 | while(1){ | 192 | while(1){ |
193 | err = os_read_file(aio_req_fd_r, &req, sizeof(req)); | 193 | err = os_read_file(aio_req_fd_r, &req, sizeof(req)); |
194 | if(err != sizeof(req)){ | 194 | if(err != sizeof(req)){ |
195 | if(err < 0) | 195 | if(err < 0) |
196 | printk("not_aio_thread - read failed, " | 196 | printk("not_aio_thread - read failed, " |
197 | "fd = %d, err = %d\n", aio_req_fd_r, | 197 | "fd = %d, err = %d\n", aio_req_fd_r, |
198 | -err); | 198 | -err); |
199 | else { | 199 | else { |
200 | printk("not_aio_thread - short read, fd = %d, " | 200 | printk("not_aio_thread - short read, fd = %d, " |
201 | "length = %d\n", aio_req_fd_r, err); | 201 | "length = %d\n", aio_req_fd_r, err); |
202 | } | 202 | } |
203 | continue; | 203 | continue; |
204 | } | 204 | } |
205 | err = do_not_aio(&req); | 205 | err = do_not_aio(&req); |
206 | reply = ((struct aio_thread_reply) { .data = req.aio, | 206 | reply = ((struct aio_thread_reply) { .data = req.aio, |
207 | .err = err }); | 207 | .err = err }); |
208 | err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); | 208 | err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); |
209 | if(err != sizeof(reply)) | 209 | if(err != sizeof(reply)) |
210 | printk("not_aio_thread - write failed, fd = %d, " | 210 | printk("not_aio_thread - write failed, fd = %d, " |
211 | "err = %d\n", aio_req_fd_r, -err); | 211 | "err = %d\n", aio_req_fd_r, -err); |
212 | } | 212 | } |
213 | |||
214 | return 0; | ||
213 | } | 215 | } |
214 | 216 | ||
215 | static int aio_pid = -1; | 217 | static int aio_pid = -1; |
216 | 218 | ||
217 | static int init_aio_24(void) | 219 | static int init_aio_24(void) |
218 | { | 220 | { |
219 | unsigned long stack; | 221 | unsigned long stack; |
220 | int fds[2], err; | 222 | int fds[2], err; |
221 | 223 | ||
222 | err = os_pipe(fds, 1, 1); | 224 | err = os_pipe(fds, 1, 1); |
223 | if(err) | 225 | if(err) |
224 | goto out; | 226 | goto out; |
225 | 227 | ||
226 | aio_req_fd_w = fds[0]; | 228 | aio_req_fd_w = fds[0]; |
227 | aio_req_fd_r = fds[1]; | 229 | aio_req_fd_r = fds[1]; |
228 | err = run_helper_thread(not_aio_thread, NULL, | 230 | err = run_helper_thread(not_aio_thread, NULL, |
229 | CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); | 231 | CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); |
230 | if(err < 0) | 232 | if(err < 0) |
231 | goto out_close_pipe; | 233 | goto out_close_pipe; |
232 | 234 | ||
233 | aio_pid = err; | 235 | aio_pid = err; |
234 | goto out; | 236 | goto out; |
235 | 237 | ||
236 | out_close_pipe: | 238 | out_close_pipe: |
237 | os_close_file(fds[0]); | 239 | os_close_file(fds[0]); |
238 | os_close_file(fds[1]); | 240 | os_close_file(fds[1]); |
239 | aio_req_fd_w = -1; | 241 | aio_req_fd_w = -1; |
240 | aio_req_fd_r = -1; | 242 | aio_req_fd_r = -1; |
241 | out: | 243 | out: |
242 | #ifndef HAVE_AIO_ABI | 244 | #ifndef HAVE_AIO_ABI |
243 | printk("/usr/include/linux/aio_abi.h not present during build\n"); | 245 | printk("/usr/include/linux/aio_abi.h not present during build\n"); |
244 | #endif | 246 | #endif |
245 | printk("2.6 host AIO support not used - falling back to I/O " | 247 | printk("2.6 host AIO support not used - falling back to I/O " |
246 | "thread\n"); | 248 | "thread\n"); |
247 | return 0; | 249 | return 0; |
248 | } | 250 | } |
249 | 251 | ||
250 | #ifdef HAVE_AIO_ABI | 252 | #ifdef HAVE_AIO_ABI |
251 | #define DEFAULT_24_AIO 0 | 253 | #define DEFAULT_24_AIO 0 |
252 | static int init_aio_26(void) | 254 | static int init_aio_26(void) |
253 | { | 255 | { |
254 | unsigned long stack; | 256 | unsigned long stack; |
255 | int err; | 257 | int err; |
256 | 258 | ||
257 | if(io_setup(256, &ctx)){ | 259 | if(io_setup(256, &ctx)){ |
258 | err = -errno; | 260 | err = -errno; |
259 | printk("aio_thread failed to initialize context, err = %d\n", | 261 | printk("aio_thread failed to initialize context, err = %d\n", |
260 | errno); | 262 | errno); |
261 | return err; | 263 | return err; |
262 | } | 264 | } |
263 | 265 | ||
264 | err = run_helper_thread(aio_thread, NULL, | 266 | err = run_helper_thread(aio_thread, NULL, |
265 | CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); | 267 | CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); |
266 | if(err < 0) | 268 | if(err < 0) |
267 | return err; | 269 | return err; |
268 | 270 | ||
269 | aio_pid = err; | 271 | aio_pid = err; |
270 | 272 | ||
271 | printk("Using 2.6 host AIO\n"); | 273 | printk("Using 2.6 host AIO\n"); |
272 | return 0; | 274 | return 0; |
273 | } | 275 | } |
274 | 276 | ||
275 | static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, | 277 | static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, |
276 | unsigned long long offset, struct aio_context *aio) | 278 | unsigned long long offset, struct aio_context *aio) |
277 | { | 279 | { |
278 | struct aio_thread_reply reply; | 280 | struct aio_thread_reply reply; |
279 | int err; | 281 | int err; |
280 | 282 | ||
281 | err = do_aio(ctx, type, io_fd, buf, len, offset, aio); | 283 | err = do_aio(ctx, type, io_fd, buf, len, offset, aio); |
282 | if(err){ | 284 | if(err){ |
283 | reply = ((struct aio_thread_reply) { .data = aio, | 285 | reply = ((struct aio_thread_reply) { .data = aio, |
284 | .err = err }); | 286 | .err = err }); |
285 | err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); | 287 | err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); |
286 | if(err != sizeof(reply)) | 288 | if(err != sizeof(reply)) |
287 | printk("submit_aio_26 - write failed, " | 289 | printk("submit_aio_26 - write failed, " |
288 | "fd = %d, err = %d\n", aio->reply_fd, -err); | 290 | "fd = %d, err = %d\n", aio->reply_fd, -err); |
289 | else err = 0; | 291 | else err = 0; |
290 | } | 292 | } |
291 | 293 | ||
292 | return err; | 294 | return err; |
293 | } | 295 | } |
294 | 296 | ||
295 | #else | 297 | #else |
296 | #define DEFAULT_24_AIO 1 | 298 | #define DEFAULT_24_AIO 1 |
297 | static int init_aio_26(void) | 299 | static int init_aio_26(void) |
298 | { | 300 | { |
299 | return -ENOSYS; | 301 | return -ENOSYS; |
300 | } | 302 | } |
301 | 303 | ||
302 | static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, | 304 | static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, |
303 | unsigned long long offset, struct aio_context *aio) | 305 | unsigned long long offset, struct aio_context *aio) |
304 | { | 306 | { |
305 | return -ENOSYS; | 307 | return -ENOSYS; |
306 | } | 308 | } |
307 | #endif | 309 | #endif |
308 | 310 | ||
@@ -310,8 +312,8 @@ static int aio_24 = DEFAULT_24_AIO; | |||
310 | 312 | ||
311 | static int __init set_aio_24(char *name, int *add) | 313 | static int __init set_aio_24(char *name, int *add) |
312 | { | 314 | { |
313 | aio_24 = 1; | 315 | aio_24 = 1; |
314 | return 0; | 316 | return 0; |
315 | } | 317 | } |
316 | 318 | ||
317 | __uml_setup("aio=2.4", set_aio_24, | 319 | __uml_setup("aio=2.4", set_aio_24, |
@@ -328,28 +330,27 @@ __uml_setup("aio=2.4", set_aio_24, | |||
328 | 330 | ||
329 | static int init_aio(void) | 331 | static int init_aio(void) |
330 | { | 332 | { |
331 | int err; | 333 | int err; |
332 | 334 | ||
333 | CHOOSE_MODE(({ | 335 | CHOOSE_MODE(({ if(!aio_24){ |
334 | if(!aio_24){ | 336 | printk("Disabling 2.6 AIO in tt mode\n"); |
335 | printk("Disabling 2.6 AIO in tt mode\n"); | 337 | aio_24 = 1; |
336 | aio_24 = 1; | 338 | } }), (void) 0); |
337 | } }), (void) 0); | 339 | |
338 | 340 | if(!aio_24){ | |
339 | if(!aio_24){ | 341 | err = init_aio_26(); |
340 | err = init_aio_26(); | 342 | if(err && (errno == ENOSYS)){ |
341 | if(err && (errno == ENOSYS)){ | 343 | printk("2.6 AIO not supported on the host - " |
342 | printk("2.6 AIO not supported on the host - " | 344 | "reverting to 2.4 AIO\n"); |
343 | "reverting to 2.4 AIO\n"); | 345 | aio_24 = 1; |
344 | aio_24 = 1; | 346 | } |
345 | } | 347 | else return err; |
346 | else return err; | 348 | } |
347 | } | 349 | |
348 | 350 | if(aio_24) | |
349 | if(aio_24) | 351 | return init_aio_24(); |
350 | return init_aio_24(); | 352 | |
351 | 353 | return 0; | |
352 | return 0; | ||
353 | } | 354 | } |
354 | 355 | ||
355 | /* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio | 356 | /* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio |
@@ -362,8 +363,8 @@ __initcall(init_aio); | |||
362 | 363 | ||
363 | static void exit_aio(void) | 364 | static void exit_aio(void) |
364 | { | 365 | { |
365 | if(aio_pid != -1) | 366 | if(aio_pid != -1) |
366 | os_kill_process(aio_pid, 1); | 367 | os_kill_process(aio_pid, 1); |
367 | } | 368 | } |
368 | 369 | ||
369 | __uml_exitcall(exit_aio); | 370 | __uml_exitcall(exit_aio); |
@@ -371,30 +372,30 @@ __uml_exitcall(exit_aio); | |||
371 | static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, | 372 | static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, |
372 | unsigned long long offset, struct aio_context *aio) | 373 | unsigned long long offset, struct aio_context *aio) |
373 | { | 374 | { |
374 | struct aio_thread_req req = { .type = type, | 375 | struct aio_thread_req req = { .type = type, |
375 | .io_fd = io_fd, | 376 | .io_fd = io_fd, |
376 | .offset = offset, | 377 | .offset = offset, |
377 | .buf = buf, | 378 | .buf = buf, |
378 | .len = len, | 379 | .len = len, |
379 | .aio = aio, | 380 | .aio = aio, |
380 | }; | 381 | }; |
381 | int err; | 382 | int err; |
382 | 383 | ||
383 | err = os_write_file(aio_req_fd_w, &req, sizeof(req)); | 384 | err = os_write_file(aio_req_fd_w, &req, sizeof(req)); |
384 | if(err == sizeof(req)) | 385 | if(err == sizeof(req)) |
385 | err = 0; | 386 | err = 0; |
386 | 387 | ||
387 | return err; | 388 | return err; |
388 | } | 389 | } |
389 | 390 | ||
390 | int submit_aio(enum aio_type type, int io_fd, char *buf, int len, | 391 | int submit_aio(enum aio_type type, int io_fd, char *buf, int len, |
391 | unsigned long long offset, int reply_fd, | 392 | unsigned long long offset, int reply_fd, |
392 | struct aio_context *aio) | 393 | struct aio_context *aio) |
393 | { | 394 | { |
394 | aio->reply_fd = reply_fd; | 395 | aio->reply_fd = reply_fd; |
395 | if(aio_24) | 396 | if(aio_24) |
396 | return submit_aio_24(type, io_fd, buf, len, offset, aio); | 397 | return submit_aio_24(type, io_fd, buf, len, offset, aio); |
397 | else { | 398 | else { |
398 | return submit_aio_26(type, io_fd, buf, len, offset, aio); | 399 | return submit_aio_26(type, io_fd, buf, len, offset, aio); |
399 | } | 400 | } |
400 | } | 401 | } |