Deleted Added
full compact
vfs_aio.c (87590) vfs_aio.c (88633)
1/*
2 * Copyright (c) 1997 John S. Dyson. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. John S. Dyson's name may not be used to endorse or promote products
10 * derived from this software without specific prior written permission.
11 *
12 * DISCLAIMER: This code isn't warranted to do anything useful. Anything
13 * bad that happens because of using this software isn't the responsibility
14 * of the author. This software is distributed AS-IS.
15 *
1/*
2 * Copyright (c) 1997 John S. Dyson. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. John S. Dyson's name may not be used to endorse or promote products
10 * derived from this software without specific prior written permission.
11 *
12 * DISCLAIMER: This code isn't warranted to do anything useful. Anything
13 * bad that happens because of using this software isn't the responsibility
14 * of the author. This software is distributed AS-IS.
15 *
16 * $FreeBSD: head/sys/kern/vfs_aio.c 87590 2001-12-10 03:34:06Z alc $
16 * $FreeBSD: head/sys/kern/vfs_aio.c 88633 2001-12-29 07:13:47Z alfred $
17 */
18
19/*
20 * This file contains support for the POSIX 1003.1B AIO/LIO facility.
21 */
22
23#include <sys/param.h>
24#include <sys/systm.h>

--- 8 unchanged lines hidden (view full) ---

33#include <sys/lock.h>
34#include <sys/mutex.h>
35#include <sys/unistd.h>
36#include <sys/proc.h>
37#include <sys/resourcevar.h>
38#include <sys/signalvar.h>
39#include <sys/protosw.h>
40#include <sys/socketvar.h>
17 */
18
19/*
20 * This file contains support for the POSIX 1003.1B AIO/LIO facility.
21 */
22
23#include <sys/param.h>
24#include <sys/systm.h>

--- 8 unchanged lines hidden (view full) ---

33#include <sys/lock.h>
34#include <sys/mutex.h>
35#include <sys/unistd.h>
36#include <sys/proc.h>
37#include <sys/resourcevar.h>
38#include <sys/signalvar.h>
39#include <sys/protosw.h>
40#include <sys/socketvar.h>
41#include <sys/syscall.h>
42#include <sys/sysent.h>
41#include <sys/sysctl.h>
42#include <sys/vnode.h>
43#include <sys/conf.h>
44#include <sys/event.h>
45
46#include <vm/vm.h>
47#include <vm/vm_extern.h>
48#include <vm/pmap.h>
49#include <vm/vm_map.h>
50#include <vm/vm_zone.h>
51#include <sys/aio.h>
52
53#include <machine/limits.h>
54
55#include "opt_vfs_aio.h"
56
43#include <sys/sysctl.h>
44#include <sys/vnode.h>
45#include <sys/conf.h>
46#include <sys/event.h>
47
48#include <vm/vm.h>
49#include <vm/vm_extern.h>
50#include <vm/pmap.h>
51#include <vm/vm_map.h>
52#include <vm/vm_zone.h>
53#include <sys/aio.h>
54
55#include <machine/limits.h>
56
57#include "opt_vfs_aio.h"
58
57#ifdef VFS_AIO
58
59static long jobrefid;
60
61#define JOBST_NULL 0x0
62#define JOBST_JOBQPROC 0x1
63#define JOBST_JOBQGLOBAL 0x2
64#define JOBST_JOBRUNNING 0x3
65#define JOBST_JOBFINISHED 0x4
66#define JOBST_JOBQBUF 0x5

--- 35 unchanged lines hidden (view full) ---

102static int num_aio_procs = 0;
103static int target_aio_procs = TARGET_AIO_PROCS;
104static int max_queue_count = MAX_AIO_QUEUE;
105static int num_queue_count = 0;
106static int num_buf_aio = 0;
107static int num_aio_resv_start = 0;
108static int aiod_timeout;
109static int aiod_lifetime;
59static long jobrefid;
60
61#define JOBST_NULL 0x0
62#define JOBST_JOBQPROC 0x1
63#define JOBST_JOBQGLOBAL 0x2
64#define JOBST_JOBRUNNING 0x3
65#define JOBST_JOBFINISHED 0x4
66#define JOBST_JOBQBUF 0x5

--- 35 unchanged lines hidden (view full) ---

102static int num_aio_procs = 0;
103static int target_aio_procs = TARGET_AIO_PROCS;
104static int max_queue_count = MAX_AIO_QUEUE;
105static int num_queue_count = 0;
106static int num_buf_aio = 0;
107static int num_aio_resv_start = 0;
108static int aiod_timeout;
109static int aiod_lifetime;
110static int unloadable = 0;
110
111static int max_aio_per_proc = MAX_AIO_PER_PROC;
112static int max_aio_queue_per_proc = MAX_AIO_QUEUE_PER_PROC;
113static int max_buf_aio = MAX_BUF_AIO;
114
115SYSCTL_NODE(_vfs, OID_AUTO, aio, CTLFLAG_RW, 0, "AIO mgmt");
116
117SYSCTL_INT(_vfs_aio, OID_AUTO, max_aio_per_proc,

--- 24 unchanged lines hidden (view full) ---

142 CTLFLAG_RD, &num_buf_aio, 0, "");
143
144SYSCTL_INT(_vfs_aio, OID_AUTO, aiod_lifetime,
145 CTLFLAG_RW, &aiod_lifetime, 0, "");
146
147SYSCTL_INT(_vfs_aio, OID_AUTO, aiod_timeout,
148 CTLFLAG_RW, &aiod_timeout, 0, "");
149
111
112static int max_aio_per_proc = MAX_AIO_PER_PROC;
113static int max_aio_queue_per_proc = MAX_AIO_QUEUE_PER_PROC;
114static int max_buf_aio = MAX_BUF_AIO;
115
116SYSCTL_NODE(_vfs, OID_AUTO, aio, CTLFLAG_RW, 0, "AIO mgmt");
117
118SYSCTL_INT(_vfs_aio, OID_AUTO, max_aio_per_proc,

--- 24 unchanged lines hidden (view full) ---

143 CTLFLAG_RD, &num_buf_aio, 0, "");
144
145SYSCTL_INT(_vfs_aio, OID_AUTO, aiod_lifetime,
146 CTLFLAG_RW, &aiod_lifetime, 0, "");
147
148SYSCTL_INT(_vfs_aio, OID_AUTO, aiod_timeout,
149 CTLFLAG_RW, &aiod_timeout, 0, "");
150
151SYSCTL_INT(_vfs_aio, OID_AUTO, unloadable, CTLFLAG_RW, &unloadable, 0,
152 "Allow unload of aio (not recommended)");
153
150/*
151 * AIO process info
152 */
153#define AIOP_FREE 0x1 /* proc on free queue */
154#define AIOP_SCHED 0x2 /* proc explicitly scheduled */
155
156struct aiothreadlist {
157 int aiothreadflags; /* AIO proc flags */

--- 43 unchanged lines hidden (view full) ---

201#define KAIO_RUNDOWN 0x1 /* process is being run down */
202#define KAIO_WAKEUP 0x2 /* wakeup process when there is a significant event */
203
204static TAILQ_HEAD(,aiothreadlist) aio_freeproc, aio_activeproc;
205static TAILQ_HEAD(,aiocblist) aio_jobs; /* Async job list */
206static TAILQ_HEAD(,aiocblist) aio_bufjobs; /* Phys I/O job list */
207
208static void aio_init_aioinfo(struct proc *p);
154/*
155 * AIO process info
156 */
157#define AIOP_FREE 0x1 /* proc on free queue */
158#define AIOP_SCHED 0x2 /* proc explicitly scheduled */
159
160struct aiothreadlist {
161 int aiothreadflags; /* AIO proc flags */

--- 43 unchanged lines hidden (view full) ---

205#define KAIO_RUNDOWN 0x1 /* process is being run down */
206#define KAIO_WAKEUP 0x2 /* wakeup process when there is a significant event */
207
208static TAILQ_HEAD(,aiothreadlist) aio_freeproc, aio_activeproc;
209static TAILQ_HEAD(,aiocblist) aio_jobs; /* Async job list */
210static TAILQ_HEAD(,aiocblist) aio_bufjobs; /* Phys I/O job list */
211
212static void aio_init_aioinfo(struct proc *p);
209static void aio_onceonly(void *);
213static void aio_onceonly(void);
210static int aio_free_entry(struct aiocblist *aiocbe);
211static void aio_process(struct aiocblist *aiocbe);
212static int aio_newproc(void);
213static int aio_aqueue(struct thread *td, struct aiocb *job, int type);
214static void aio_physwakeup(struct buf *bp);
214static int aio_free_entry(struct aiocblist *aiocbe);
215static void aio_process(struct aiocblist *aiocbe);
216static int aio_newproc(void);
217static int aio_aqueue(struct thread *td, struct aiocb *job, int type);
218static void aio_physwakeup(struct buf *bp);
219static void aio_proc_rundown(struct proc *p);
215static int aio_fphysio(struct proc *p, struct aiocblist *aiocbe);
216static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
217static void aio_daemon(void *uproc);
220static int aio_fphysio(struct proc *p, struct aiocblist *aiocbe);
221static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
222static void aio_daemon(void *uproc);
223static int aio_unload(void);
218static void process_signal(void *aioj);
224static void process_signal(void *aioj);
225static int filt_aioattach(struct knote *kn);
226static void filt_aiodetach(struct knote *kn);
227static int filt_aio(struct knote *kn, long hint);
219
228
220SYSINIT(aio, SI_SUB_VFS, SI_ORDER_ANY, aio_onceonly, NULL);
221
222static vm_zone_t kaio_zone = 0, aiop_zone = 0, aiocb_zone = 0, aiol_zone = 0;
223static vm_zone_t aiolio_zone = 0;
224
229static vm_zone_t kaio_zone = 0, aiop_zone = 0, aiocb_zone = 0, aiol_zone = 0;
230static vm_zone_t aiolio_zone = 0;
231
232static struct filterops aio_filtops =
233 { 0, filt_aioattach, filt_aiodetach, filt_aio };
234
235static int
236aio_modload(struct module *module, int cmd, void *arg)
237{
238 int error = 0;
239
240 switch (cmd) {
241 case MOD_LOAD:
242 aio_onceonly();
243 break;
244 case MOD_UNLOAD:
245 error = aio_unload();
246 break;
247 case MOD_SHUTDOWN:
248 break;
249 default:
250 error = EINVAL;
251 break;
252 }
253 return (error);
254}
255
256static moduledata_t aio_mod = {
257 "aio",
258 &aio_modload,
259 NULL
260};
261
262SYSCALL_MODULE_HELPER(aio_return);
263SYSCALL_MODULE_HELPER(aio_suspend);
264SYSCALL_MODULE_HELPER(aio_cancel);
265SYSCALL_MODULE_HELPER(aio_error);
266SYSCALL_MODULE_HELPER(aio_read);
267SYSCALL_MODULE_HELPER(aio_write);
268SYSCALL_MODULE_HELPER(aio_waitcomplete);
269SYSCALL_MODULE_HELPER(lio_listio);
270
271DECLARE_MODULE(aio, aio_mod,
272 SI_SUB_VFS, SI_ORDER_ANY);
273MODULE_VERSION(aio, 1);
274
225/*
226 * Startup initialization
227 */
228static void
275/*
276 * Startup initialization
277 */
278static void
229aio_onceonly(void *na)
279aio_onceonly(void)
230{
280{
281
282 /* XXX: should probably just use so->callback */
283 aio_swake = &aio_swake_cb;
284 at_exit(aio_proc_rundown);
285 at_exec(aio_proc_rundown);
286 kqueue_add_filteropts(EVFILT_AIO, &aio_filtops);
231 TAILQ_INIT(&aio_freeproc);
232 TAILQ_INIT(&aio_activeproc);
233 TAILQ_INIT(&aio_jobs);
234 TAILQ_INIT(&aio_bufjobs);
235 kaio_zone = zinit("AIO", sizeof (struct kaioinfo), 0, 0, 1);
236 aiop_zone = zinit("AIOP", sizeof (struct aiothreadlist), 0, 0, 1);
237 aiocb_zone = zinit("AIOCB", sizeof (struct aiocblist), 0, 0, 1);
238 aiol_zone = zinit("AIOL", AIO_LISTIO_MAX * sizeof (int), 0, 0, 1);
239 aiolio_zone = zinit("AIOLIO", AIO_LISTIO_MAX * sizeof (struct
240 aio_liojob), 0, 0, 1);
241 aiod_timeout = AIOD_TIMEOUT_DEFAULT;
242 aiod_lifetime = AIOD_LIFETIME_DEFAULT;
243 jobrefid = 1;
244}
245
287 TAILQ_INIT(&aio_freeproc);
288 TAILQ_INIT(&aio_activeproc);
289 TAILQ_INIT(&aio_jobs);
290 TAILQ_INIT(&aio_bufjobs);
291 kaio_zone = zinit("AIO", sizeof (struct kaioinfo), 0, 0, 1);
292 aiop_zone = zinit("AIOP", sizeof (struct aiothreadlist), 0, 0, 1);
293 aiocb_zone = zinit("AIOCB", sizeof (struct aiocblist), 0, 0, 1);
294 aiol_zone = zinit("AIOL", AIO_LISTIO_MAX * sizeof (int), 0, 0, 1);
295 aiolio_zone = zinit("AIOLIO", AIO_LISTIO_MAX * sizeof (struct
296 aio_liojob), 0, 0, 1);
297 aiod_timeout = AIOD_TIMEOUT_DEFAULT;
298 aiod_lifetime = AIOD_LIFETIME_DEFAULT;
299 jobrefid = 1;
300}
301
302static int
303aio_unload(void)
304{
305
306 /*
307 * XXX: no unloads by default, it's too dangerous.
308 * perhaps we could do it if locked out callers and then
309 * did an aio_proc_rundown() on each process.
310 */
311 if (!unloadable)
312 return (EOPNOTSUPP);
313
314 aio_swake = NULL;
315 rm_at_exit(aio_proc_rundown);
316 rm_at_exec(aio_proc_rundown);
317 kqueue_del_filteropts(EVFILT_AIO);
318 return (0);
319}
320
246/*
247 * Init the per-process aioinfo structure. The aioinfo limits are set
248 * per-process for user limit (resource) management.
249 */
250static void
251aio_init_aioinfo(struct proc *p)
252{
253 struct kaioinfo *ki;

--- 125 unchanged lines hidden (view full) ---

379 TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list);
380 zfree(aiolio_zone, lj);
381 }
382 aiocbe->jobstate = JOBST_NULL;
383 untimeout(process_signal, aiocbe, aiocbe->timeouthandle);
384 zfree(aiocb_zone, aiocbe);
385 return 0;
386}
321/*
322 * Init the per-process aioinfo structure. The aioinfo limits are set
323 * per-process for user limit (resource) management.
324 */
325static void
326aio_init_aioinfo(struct proc *p)
327{
328 struct kaioinfo *ki;

--- 125 unchanged lines hidden (view full) ---

454 TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list);
455 zfree(aiolio_zone, lj);
456 }
457 aiocbe->jobstate = JOBST_NULL;
458 untimeout(process_signal, aiocbe, aiocbe->timeouthandle);
459 zfree(aiocb_zone, aiocbe);
460 return 0;
461}
387#endif /* VFS_AIO */
388
389/*
390 * Rundown the jobs for a given process.
391 */
462
463/*
464 * Rundown the jobs for a given process.
465 */
392void
466static void
393aio_proc_rundown(struct proc *p)
394{
467aio_proc_rundown(struct proc *p)
468{
395#ifndef VFS_AIO
396 return;
397#else
398 int s;
399 struct kaioinfo *ki;
400 struct aio_liojob *lj, *ljn;
401 struct aiocblist *aiocbe, *aiocbn;
402 struct file *fp;
403 struct filedesc *fdp;
404 struct socket *so;
405

--- 108 unchanged lines hidden (view full) ---

514 lj->lioj_queue_count,
515 lj->lioj_queue_finished_count);
516#endif
517 }
518 }
519
520 zfree(kaio_zone, ki);
521 p->p_aioinfo = NULL;
469 int s;
470 struct kaioinfo *ki;
471 struct aio_liojob *lj, *ljn;
472 struct aiocblist *aiocbe, *aiocbn;
473 struct file *fp;
474 struct filedesc *fdp;
475 struct socket *so;
476

--- 108 unchanged lines hidden (view full) ---

585 lj->lioj_queue_count,
586 lj->lioj_queue_finished_count);
587#endif
588 }
589 }
590
591 zfree(kaio_zone, ki);
592 p->p_aioinfo = NULL;
522#endif /* VFS_AIO */
523}
524
593}
594
525#ifdef VFS_AIO
526/*
527 * Select a job to run (called by an AIO daemon).
528 */
529static struct aiocblist *
530aio_selectjob(struct aiothreadlist *aiop)
531{
532 int s;
533 struct aiocblist *aiocbe;

--- 611 unchanged lines hidden (view full) ---

1145
1146 /* Check for an error. */
1147 if (bp->b_ioflags & BIO_ERROR)
1148 error = bp->b_error;
1149
1150 relpbuf(bp, NULL);
1151 return (error);
1152}
595/*
596 * Select a job to run (called by an AIO daemon).
597 */
598static struct aiocblist *
599aio_selectjob(struct aiothreadlist *aiop)
600{
601 int s;
602 struct aiocblist *aiocbe;

--- 611 unchanged lines hidden (view full) ---

1214
1215 /* Check for an error. */
1216 if (bp->b_ioflags & BIO_ERROR)
1217 error = bp->b_error;
1218
1219 relpbuf(bp, NULL);
1220 return (error);
1221}
1153#endif /* VFS_AIO */
1154
1155/*
1156 * Wake up aio requests that may be serviceable now.
1157 */
1158void
1222
1223/*
1224 * Wake up aio requests that may be serviceable now.
1225 */
1226void
1159aio_swake(struct socket *so, struct sockbuf *sb)
1227aio_swake_cb(struct socket *so, struct sockbuf *sb)
1160{
1228{
1161#ifndef VFS_AIO
1162 return;
1163#else
1164 struct aiocblist *cb,*cbn;
1165 struct proc *p;
1166 struct kaioinfo *ki = NULL;
1167 int opcode, wakecount = 0;
1168 struct aiothreadlist *aiop;
1169
1170 if (sb == &so->so_snd) {
1171 opcode = LIO_WRITE;

--- 21 unchanged lines hidden (view full) ---

1193 while (wakecount--) {
1194 if ((aiop = TAILQ_FIRST(&aio_freeproc)) != 0) {
1195 TAILQ_REMOVE(&aio_freeproc, aiop, list);
1196 TAILQ_INSERT_TAIL(&aio_activeproc, aiop, list);
1197 aiop->aiothreadflags &= ~AIOP_FREE;
1198 wakeup(aiop->aiothread);
1199 }
1200 }
1229 struct aiocblist *cb,*cbn;
1230 struct proc *p;
1231 struct kaioinfo *ki = NULL;
1232 int opcode, wakecount = 0;
1233 struct aiothreadlist *aiop;
1234
1235 if (sb == &so->so_snd) {
1236 opcode = LIO_WRITE;

--- 21 unchanged lines hidden (view full) ---

1258 while (wakecount--) {
1259 if ((aiop = TAILQ_FIRST(&aio_freeproc)) != 0) {
1260 TAILQ_REMOVE(&aio_freeproc, aiop, list);
1261 TAILQ_INSERT_TAIL(&aio_activeproc, aiop, list);
1262 aiop->aiothreadflags &= ~AIOP_FREE;
1263 wakeup(aiop->aiothread);
1264 }
1265 }
1201#endif /* VFS_AIO */
1202}
1203
1266}
1267
1204#ifdef VFS_AIO
1205/*
1206 * Queue a new AIO request. Choosing either the threaded or direct physio VCHR
1207 * technique is done in this code.
1208 */
1209static int
1210_aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int type)
1211{
1212 struct proc *p = td->td_proc;

--- 256 unchanged lines hidden (view full) ---

1469 return EAGAIN;
1470
1471 ki = p->p_aioinfo;
1472 if (ki->kaio_queue_count >= ki->kaio_qallowed_count)
1473 return EAGAIN;
1474
1475 return _aio_aqueue(td, job, NULL, type);
1476}
1268/*
1269 * Queue a new AIO request. Choosing either the threaded or direct physio VCHR
1270 * technique is done in this code.
1271 */
1272static int
1273_aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int type)
1274{
1275 struct proc *p = td->td_proc;

--- 256 unchanged lines hidden (view full) ---

1532 return EAGAIN;
1533
1534 ki = p->p_aioinfo;
1535 if (ki->kaio_queue_count >= ki->kaio_qallowed_count)
1536 return EAGAIN;
1537
1538 return _aio_aqueue(td, job, NULL, type);
1539}
1477#endif /* VFS_AIO */
1478
1479/*
1480 * Support the aio_return system call, as a side-effect, kernel resources are
1481 * released.
1482 */
1483int
1484aio_return(struct thread *td, struct aio_return_args *uap)
1485{
1540
1541/*
1542 * Support the aio_return system call, as a side-effect, kernel resources are
1543 * released.
1544 */
1545int
1546aio_return(struct thread *td, struct aio_return_args *uap)
1547{
1486#ifndef VFS_AIO
1487 return ENOSYS;
1488#else
1489 struct proc *p = td->td_proc;
1490 int s;
1491 int jobref;
1492 struct aiocblist *cb, *ncb;
1493 struct aiocb *ujob;
1494 struct kaioinfo *ki;
1495
1496 ki = p->p_aioinfo;

--- 45 unchanged lines hidden (view full) ---

1542 td->td_retval[0] = EFAULT;
1543 aio_free_entry(cb);
1544 return 0;
1545 }
1546 }
1547 splx(s);
1548
1549 return (EINVAL);
1548 struct proc *p = td->td_proc;
1549 int s;
1550 int jobref;
1551 struct aiocblist *cb, *ncb;
1552 struct aiocb *ujob;
1553 struct kaioinfo *ki;
1554
1555 ki = p->p_aioinfo;

--- 45 unchanged lines hidden (view full) ---

1601 td->td_retval[0] = EFAULT;
1602 aio_free_entry(cb);
1603 return 0;
1604 }
1605 }
1606 splx(s);
1607
1608 return (EINVAL);
1550#endif /* VFS_AIO */
1551}
1552
1553/*
1554 * Allow a process to wakeup when any of the I/O requests are completed.
1555 */
1556int
1557aio_suspend(struct thread *td, struct aio_suspend_args *uap)
1558{
1609}
1610
1611/*
1612 * Allow a process to wakeup when any of the I/O requests are completed.
1613 */
1614int
1615aio_suspend(struct thread *td, struct aio_suspend_args *uap)
1616{
1559#ifndef VFS_AIO
1560 return ENOSYS;
1561#else
1562 struct proc *p = td->td_proc;
1563 struct timeval atv;
1564 struct timespec ts;
1565 struct aiocb *const *cbptr, *cbp;
1566 struct kaioinfo *ki;
1567 struct aiocblist *cb;
1568 int i;
1569 int njoblist;

--- 89 unchanged lines hidden (view full) ---

1659 zfree(aiol_zone, ijoblist);
1660 zfree(aiol_zone, ujoblist);
1661 return EAGAIN;
1662 }
1663 }
1664
1665/* NOTREACHED */
1666 return EINVAL;
1617 struct proc *p = td->td_proc;
1618 struct timeval atv;
1619 struct timespec ts;
1620 struct aiocb *const *cbptr, *cbp;
1621 struct kaioinfo *ki;
1622 struct aiocblist *cb;
1623 int i;
1624 int njoblist;

--- 89 unchanged lines hidden (view full) ---

1714 zfree(aiol_zone, ijoblist);
1715 zfree(aiol_zone, ujoblist);
1716 return EAGAIN;
1717 }
1718 }
1719
1720/* NOTREACHED */
1721 return EINVAL;
1667#endif /* VFS_AIO */
1668}
1669
1670/*
1671 * aio_cancel cancels any non-physio aio operations not currently in
1672 * progress.
1673 */
1674int
1675aio_cancel(struct thread *td, struct aio_cancel_args *uap)
1676{
1722}
1723
1724/*
1725 * aio_cancel cancels any non-physio aio operations not currently in
1726 * progress.
1727 */
1728int
1729aio_cancel(struct thread *td, struct aio_cancel_args *uap)
1730{
1677#ifndef VFS_AIO
1678 return ENOSYS;
1679#else
1680 struct proc *p = td->td_proc;
1681 struct kaioinfo *ki;
1682 struct aiocblist *cbe, *cbn;
1683 struct file *fp;
1684 struct filedesc *fdp;
1685 struct socket *so;
1686 struct proc *po;
1687 int s,error;

--- 103 unchanged lines hidden (view full) ---

1791 if (cancelled) {
1792 td->td_retval[0] = AIO_CANCELED;
1793 return 0;
1794 }
1795
1796 td->td_retval[0] = AIO_ALLDONE;
1797
1798 return 0;
1731 struct proc *p = td->td_proc;
1732 struct kaioinfo *ki;
1733 struct aiocblist *cbe, *cbn;
1734 struct file *fp;
1735 struct filedesc *fdp;
1736 struct socket *so;
1737 struct proc *po;
1738 int s,error;

--- 103 unchanged lines hidden (view full) ---

1842 if (cancelled) {
1843 td->td_retval[0] = AIO_CANCELED;
1844 return 0;
1845 }
1846
1847 td->td_retval[0] = AIO_ALLDONE;
1848
1849 return 0;
1799#endif /* VFS_AIO */
1800}
1801
1802/*
1803 * aio_error is implemented in the kernel level for compatibility purposes only.
1804 * For a user mode async implementation, it would be best to do it in a userland
1805 * subroutine.
1806 */
1807int
1808aio_error(struct thread *td, struct aio_error_args *uap)
1809{
1850}
1851
1852/*
1853 * aio_error is implemented in the kernel level for compatibility purposes only.
1854 * For a user mode async implementation, it would be best to do it in a userland
1855 * subroutine.
1856 */
1857int
1858aio_error(struct thread *td, struct aio_error_args *uap)
1859{
1810#ifndef VFS_AIO
1811 return ENOSYS;
1812#else
1813 struct proc *p = td->td_proc;
1814 int s;
1815 struct aiocblist *cb;
1816 struct kaioinfo *ki;
1817 int jobref;
1818
1819 ki = p->p_aioinfo;
1820 if (ki == NULL)

--- 61 unchanged lines hidden (view full) ---

1882 /*
1883 * Hack for lio.
1884 */
1885 status = fuword(&uap->aiocbp->_aiocb_private.status);
1886 if (status == -1)
1887 return fuword(&uap->aiocbp->_aiocb_private.error);
1888#endif
1889 return EINVAL;
1860 struct proc *p = td->td_proc;
1861 int s;
1862 struct aiocblist *cb;
1863 struct kaioinfo *ki;
1864 int jobref;
1865
1866 ki = p->p_aioinfo;
1867 if (ki == NULL)

--- 61 unchanged lines hidden (view full) ---

1929 /*
1930 * Hack for lio.
1931 */
1932 status = fuword(&uap->aiocbp->_aiocb_private.status);
1933 if (status == -1)
1934 return fuword(&uap->aiocbp->_aiocb_private.error);
1935#endif
1936 return EINVAL;
1890#endif /* VFS_AIO */
1891}
1892
1893int
1894aio_read(struct thread *td, struct aio_read_args *uap)
1895{
1937}
1938
1939int
1940aio_read(struct thread *td, struct aio_read_args *uap)
1941{
1896#ifndef VFS_AIO
1897 return ENOSYS;
1898#else
1942
1899 return aio_aqueue(td, uap->aiocbp, LIO_READ);
1943 return aio_aqueue(td, uap->aiocbp, LIO_READ);
1900#endif /* VFS_AIO */
1901}
1902
1903int
1904aio_write(struct thread *td, struct aio_write_args *uap)
1905{
1944}
1945
1946int
1947aio_write(struct thread *td, struct aio_write_args *uap)
1948{
1906#ifndef VFS_AIO
1907 return ENOSYS;
1908#else
1949
1909 return aio_aqueue(td, uap->aiocbp, LIO_WRITE);
1950 return aio_aqueue(td, uap->aiocbp, LIO_WRITE);
1910#endif /* VFS_AIO */
1911}
1912
1913int
1914lio_listio(struct thread *td, struct lio_listio_args *uap)
1915{
1951}
1952
1953int
1954lio_listio(struct thread *td, struct lio_listio_args *uap)
1955{
1916#ifndef VFS_AIO
1917 return ENOSYS;
1918#else
1919 struct proc *p = td->td_proc;
1920 int nent, nentqueued;
1921 struct aiocb *iocb, * const *cbptr;
1922 struct aiocblist *cb;
1923 struct kaioinfo *ki;
1924 struct aio_liojob *lj;
1925 int error, runningcode;
1926 int nerror;

--- 148 unchanged lines hidden (view full) ---

2075 if (error == EINTR)
2076 return EINTR;
2077 else if (error == EWOULDBLOCK)
2078 return EAGAIN;
2079 }
2080 }
2081
2082 return runningcode;
1956 struct proc *p = td->td_proc;
1957 int nent, nentqueued;
1958 struct aiocb *iocb, * const *cbptr;
1959 struct aiocblist *cb;
1960 struct kaioinfo *ki;
1961 struct aio_liojob *lj;
1962 int error, runningcode;
1963 int nerror;

--- 148 unchanged lines hidden (view full) ---

2112 if (error == EINTR)
2113 return EINTR;
2114 else if (error == EWOULDBLOCK)
2115 return EAGAIN;
2116 }
2117 }
2118
2119 return runningcode;
2083#endif /* VFS_AIO */
2084}
2085
2120}
2121
2086#ifdef VFS_AIO
2087/*
2088 * This is a weird hack so that we can post a signal. It is safe to do so from
2089 * a timeout routine, but *not* from an interrupt routine.
2090 */
2091static void
2092process_signal(void *aioj)
2093{
2094 struct aiocblist *aiocbe = aioj;

--- 79 unchanged lines hidden (view full) ---

2174 }
2175 }
2176
2177 if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL)
2178 aiocbe->timeouthandle =
2179 timeout(process_signal, aiocbe, 0);
2180 }
2181}
2122/*
2123 * This is a weird hack so that we can post a signal. It is safe to do so from
2124 * a timeout routine, but *not* from an interrupt routine.
2125 */
2126static void
2127process_signal(void *aioj)
2128{
2129 struct aiocblist *aiocbe = aioj;

--- 79 unchanged lines hidden (view full) ---

2209 }
2210 }
2211
2212 if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL)
2213 aiocbe->timeouthandle =
2214 timeout(process_signal, aiocbe, 0);
2215 }
2216}
2182#endif /* VFS_AIO */
2183
2184int
2185aio_waitcomplete(struct thread *td, struct aio_waitcomplete_args *uap)
2186{
2217
2218int
2219aio_waitcomplete(struct thread *td, struct aio_waitcomplete_args *uap)
2220{
2187#ifndef VFS_AIO
2188 return ENOSYS;
2189#else
2190 struct proc *p = td->td_proc;
2191 struct timeval atv;
2192 struct timespec ts;
2193 struct aiocb **cbptr;
2194 struct kaioinfo *ki;
2195 struct aiocblist *cb = NULL;
2196 int error, s, timo;
2197

--- 55 unchanged lines hidden (view full) ---

2253 return EINTR;
2254 else if (error < 0)
2255 return error;
2256 else if (error == EINTR)
2257 return EINTR;
2258 else if (error == EWOULDBLOCK)
2259 return EAGAIN;
2260 }
2221 struct proc *p = td->td_proc;
2222 struct timeval atv;
2223 struct timespec ts;
2224 struct aiocb **cbptr;
2225 struct kaioinfo *ki;
2226 struct aiocblist *cb = NULL;
2227 int error, s, timo;
2228

--- 55 unchanged lines hidden (view full) ---

2284 return EINTR;
2285 else if (error < 0)
2286 return error;
2287 else if (error == EINTR)
2288 return EINTR;
2289 else if (error == EWOULDBLOCK)
2290 return EAGAIN;
2291 }
2261#endif /* VFS_AIO */
2262}
2263
2292}
2293
2264
2265#ifndef VFS_AIO
2266static int
2267filt_aioattach(struct knote *kn)
2268{
2294static int
2295filt_aioattach(struct knote *kn)
2296{
2269
2270 return (ENXIO);
2271}
2272
2273struct filterops aio_filtops =
2274 { 0, filt_aioattach, NULL, NULL };
2275
2276#else
2277static int
2278filt_aioattach(struct knote *kn)
2279{
2280 struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id;
2281
2282 /*
2283 * The aiocbe pointer must be validated before using it, so
2284 * registration is restricted to the kernel; the user cannot
2285 * set EV_FLAG1.
2286 */
2287 if ((kn->kn_flags & EV_FLAG1) == 0)

--- 21 unchanged lines hidden (view full) ---

2309
2310 kn->kn_data = aiocbe->uaiocb._aiocb_private.error;
2311 if (aiocbe->jobstate != JOBST_JOBFINISHED &&
2312 aiocbe->jobstate != JOBST_JOBBFINISHED)
2313 return (0);
2314 kn->kn_flags |= EV_EOF;
2315 return (1);
2316}
2297 struct aiocblist *aiocbe = (struct aiocblist *)kn->kn_id;
2298
2299 /*
2300 * The aiocbe pointer must be validated before using it, so
2301 * registration is restricted to the kernel; the user cannot
2302 * set EV_FLAG1.
2303 */
2304 if ((kn->kn_flags & EV_FLAG1) == 0)

--- 21 unchanged lines hidden (view full) ---

2326
2327 kn->kn_data = aiocbe->uaiocb._aiocb_private.error;
2328 if (aiocbe->jobstate != JOBST_JOBFINISHED &&
2329 aiocbe->jobstate != JOBST_JOBBFINISHED)
2330 return (0);
2331 kn->kn_flags |= EV_EOF;
2332 return (1);
2333}
2317
2318struct filterops aio_filtops =
2319 { 0, filt_aioattach, filt_aiodetach, filt_aio };
2320#endif /* VFS_AIO */