160727d8bSWarner Losh /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3c4e20cadSPedro F. Giffuni * 40f606585SJohn Dyson * Copyright (c) 1997 John S. Dyson. All rights reserved. 50f606585SJohn Dyson * 60f606585SJohn Dyson * Redistribution and use in source and binary forms, with or without 70f606585SJohn Dyson * modification, are permitted provided that the following conditions 80f606585SJohn Dyson * are met: 90f606585SJohn Dyson * 1. Redistributions of source code must retain the above copyright 100f606585SJohn Dyson * notice, this list of conditions and the following disclaimer. 110f606585SJohn Dyson * 2. John S. Dyson's name may not be used to endorse or promote products 120f606585SJohn Dyson * derived from this software without specific prior written permission. 130f606585SJohn Dyson * 140f606585SJohn Dyson * DISCLAIMER: This code isn't warranted to do anything useful. Anything 150f606585SJohn Dyson * bad that happens because of using this software isn't the responsibility 160f606585SJohn Dyson * of the author. This software is distributed AS-IS. 170f606585SJohn Dyson */ 180f606585SJohn Dyson 19f0231545SDmitrij Tejblum #ifndef _SYS_AIO_H_ 20f0231545SDmitrij Tejblum #define _SYS_AIO_H_ 21f0231545SDmitrij Tejblum 220f606585SJohn Dyson #include <sys/types.h> 238a6472b7SPeter Dufault #include <sys/signal.h> 24f3215338SJohn Baldwin #ifdef _KERNEL 25f3215338SJohn Baldwin #include <sys/queue.h> 26f3215338SJohn Baldwin #include <sys/event.h> 27f3215338SJohn Baldwin #include <sys/signalvar.h> 28022ca2fcSAlan Somers #include <sys/uio.h> 29f3215338SJohn Baldwin #endif 30f0231545SDmitrij Tejblum 310f606585SJohn Dyson /* 320f606585SJohn Dyson * Returned by aio_cancel: 330f606585SJohn Dyson */ 340f606585SJohn Dyson #define AIO_CANCELED 0x1 3578922e41SJohn Dyson #define AIO_NOTCANCELED 0x2 360f606585SJohn Dyson #define AIO_ALLDONE 0x3 370f606585SJohn Dyson 380f606585SJohn Dyson /* 390f606585SJohn Dyson * LIO opcodes 400f606585SJohn Dyson */ 410f606585SJohn Dyson #define LIO_NOP 0x0 420f606585SJohn Dyson #define LIO_WRITE 0x1 430f606585SJohn Dyson #define LIO_READ 0x2 44f30a1ae8SThomas Munro #if __BSD_VISIBLE 452247f489SAlan Somers #define LIO_VECTORED 0x4 462247f489SAlan Somers #define LIO_WRITEV (LIO_WRITE | LIO_VECTORED) 472247f489SAlan Somers #define LIO_READV (LIO_READ | LIO_VECTORED) 48f30a1ae8SThomas Munro #endif 49f30a1ae8SThomas Munro #if defined(_KERNEL) || defined(_WANT_ALL_LIO_OPCODES) 502247f489SAlan Somers #define LIO_SYNC 0x8 512247f489SAlan Somers #define LIO_DSYNC (0x10 | LIO_SYNC) 522247f489SAlan Somers #define LIO_MLOCK 0x20 5353fcc63cSDavid Xu #endif 54e4b7bbd6SKonstantin Belousov #if __BSD_VISIBLE 55e4b7bbd6SKonstantin Belousov #define LIO_FOFFSET 0x40 56e4b7bbd6SKonstantin Belousov #endif 570f606585SJohn Dyson 5806cb1c3fSKonstantin Belousov /* aio_read2/aio_write2 flags */ 5906cb1c3fSKonstantin Belousov #if __BSD_VISIBLE 6006cb1c3fSKonstantin Belousov #define AIO_OP2_FOFFSET 0x00000001 618dfc788bSKonstantin Belousov #define AIO_OP2_VECTORED 0x00000002 6206cb1c3fSKonstantin Belousov #endif 6306cb1c3fSKonstantin Belousov 640f606585SJohn Dyson /* 650f606585SJohn Dyson * LIO modes 660f606585SJohn Dyson */ 670f606585SJohn Dyson #define LIO_NOWAIT 0x0 680f606585SJohn Dyson #define LIO_WAIT 0x1 690f606585SJohn Dyson 700f606585SJohn Dyson /* 7121b8a7a6SAlan Somers * Maximum number of operations in a single lio_listio call 727a2ac24cSPeter Dufault */ 737a2ac24cSPeter Dufault #define AIO_LISTIO_MAX 16 747a2ac24cSPeter Dufault 75f3215338SJohn Baldwin #ifdef _KERNEL 76f3215338SJohn Baldwin 77f3215338SJohn Baldwin /* Default values of tunables for the AIO worker pool. */ 78f3215338SJohn Baldwin 79f3215338SJohn Baldwin #ifndef MAX_AIO_PROCS 80f3215338SJohn Baldwin #define MAX_AIO_PROCS 32 81f3215338SJohn Baldwin #endif 82f3215338SJohn Baldwin 83f3215338SJohn Baldwin #ifndef TARGET_AIO_PROCS 84f3215338SJohn Baldwin #define TARGET_AIO_PROCS 4 85f3215338SJohn Baldwin #endif 86f3215338SJohn Baldwin 87f3215338SJohn Baldwin #ifndef AIOD_LIFETIME_DEFAULT 88f3215338SJohn Baldwin #define AIOD_LIFETIME_DEFAULT (30 * hz) 89f3215338SJohn Baldwin #endif 90f3215338SJohn Baldwin 91f3215338SJohn Baldwin #endif 92f3215338SJohn Baldwin 937a2ac24cSPeter Dufault /* 940f606585SJohn Dyson * Private members for aiocb -- don't access 950f606585SJohn Dyson * directly. 960f606585SJohn Dyson */ 970f606585SJohn Dyson struct __aiocb_private { 9896b8882aSAlan Cox long status; 9996b8882aSAlan Cox long error; 100*4605a99bSAndrew Gallatin void *spare; 1010f606585SJohn Dyson }; 1020f606585SJohn Dyson 1030f606585SJohn Dyson /* 1040f606585SJohn Dyson * I/O control block 1050f606585SJohn Dyson */ 1060f606585SJohn Dyson typedef struct aiocb { 1070f606585SJohn Dyson int aio_fildes; /* File descriptor */ 1080f606585SJohn Dyson off_t aio_offset; /* File offset for I/O */ 10978922e41SJohn Dyson volatile void *aio_buf; /* I/O buffer in process space */ 1100f606585SJohn Dyson size_t aio_nbytes; /* Number of bytes for I/O */ 111c4592cbcSJohn Baldwin int __spare__[2]; 112c4592cbcSJohn Baldwin void *__spare2__; 1130f606585SJohn Dyson int aio_lio_opcode; /* LIO opcode */ 1140f606585SJohn Dyson int aio_reqprio; /* Request priority -- ignored */ 1150f606585SJohn Dyson struct __aiocb_private _aiocb_private; 1160972628aSDavid Xu struct sigevent aio_sigevent; /* Signal to deliver */ 1170f606585SJohn Dyson } aiocb_t; 1180f606585SJohn Dyson 119022ca2fcSAlan Somers #define aio_iov aio_buf /* I/O scatter/gather list */ 120022ca2fcSAlan Somers #define aio_iovcnt aio_nbytes /* Length of aio_iov */ 121022ca2fcSAlan Somers 122f3215338SJohn Baldwin #ifdef _KERNEL 123f3215338SJohn Baldwin 124f3215338SJohn Baldwin typedef void aio_cancel_fn_t(struct kaiocb *); 125f3215338SJohn Baldwin typedef void aio_handle_fn_t(struct kaiocb *); 126f3215338SJohn Baldwin 127f3215338SJohn Baldwin /* 128f3215338SJohn Baldwin * Kernel version of an I/O control block. 129f3215338SJohn Baldwin * 130f3215338SJohn Baldwin * Locking key: 131f3215338SJohn Baldwin * * - need not protected 132f3215338SJohn Baldwin * a - locked by kaioinfo lock 133f3215338SJohn Baldwin * b - locked by backend lock 134f3215338SJohn Baldwin * c - locked by aio_job_mtx 135f3215338SJohn Baldwin */ 136f3215338SJohn Baldwin struct kaiocb { 137f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) list; /* (b) backend-specific list of jobs */ 138f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) plist; /* (a) lists of pending / done jobs */ 139f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) allist; /* (a) list of all jobs in proc */ 140f3215338SJohn Baldwin int jobflags; /* (a) job flags */ 141e4b7bbd6SKonstantin Belousov int ioflags; /* (*) io flags */ 142b1012d80SJohn Baldwin int inblock; /* (*) input blocks */ 143b1012d80SJohn Baldwin int outblock; /* (*) output blocks */ 144b1012d80SJohn Baldwin int msgsnd; /* (*) messages sent */ 145b1012d80SJohn Baldwin int msgrcv; /* (*) messages received */ 146f3215338SJohn Baldwin struct proc *userproc; /* (*) user process */ 147f3215338SJohn Baldwin struct ucred *cred; /* (*) active credential when created */ 148f3215338SJohn Baldwin struct file *fd_file; /* (*) pointer to file structure */ 149f3215338SJohn Baldwin struct aioliojob *lio; /* (*) optional lio job */ 150f3215338SJohn Baldwin struct aiocb *ujob; /* (*) pointer in userspace of aiocb */ 151f3215338SJohn Baldwin struct knlist klist; /* (a) list of knotes */ 152f3215338SJohn Baldwin struct aiocb uaiocb; /* (*) copy of user I/O control block */ 153022ca2fcSAlan Somers struct uio uio; /* (*) storage for non-vectored uio */ 154022ca2fcSAlan Somers struct iovec iov[1]; /* (*) storage for non-vectored uio */ 155022ca2fcSAlan Somers struct uio *uiop; /* (*) Possibly malloced uio */ 156f3215338SJohn Baldwin ksiginfo_t ksi; /* (a) realtime signal info */ 157f3215338SJohn Baldwin uint64_t seqno; /* (*) job number */ 158f3215338SJohn Baldwin aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */ 159f3215338SJohn Baldwin aio_handle_fn_t *handle_fn; /* (c) backend handle function */ 160fe0bdd1dSJohn Baldwin union { /* Backend-specific data fields */ 161022ca2fcSAlan Somers struct { /* BIO backend */ 16298844e99SJohn Baldwin volatile u_int nbio; /* Number of remaining bios */ 163022ca2fcSAlan Somers int error; /* Worst error of all bios */ 164022ca2fcSAlan Somers long nbytes; /* Bytes completed so far */ 165022ca2fcSAlan Somers }; 166fe0bdd1dSJohn Baldwin struct { /* fsync() requests */ 167fe0bdd1dSJohn Baldwin int pending; /* (a) number of pending I/O */ 168fe0bdd1dSJohn Baldwin }; 16901206038SAlan Somers struct { /* socket backend */ 170fe0bdd1dSJohn Baldwin void *backend1; 171fe0bdd1dSJohn Baldwin long backend3; 172fe0bdd1dSJohn Baldwin int backend4; 173fe0bdd1dSJohn Baldwin }; 174fe0bdd1dSJohn Baldwin }; 175f3215338SJohn Baldwin }; 176f3215338SJohn Baldwin 177f3215338SJohn Baldwin struct socket; 178f3215338SJohn Baldwin struct sockbuf; 179f3215338SJohn Baldwin 180f3215338SJohn Baldwin /* 181f3215338SJohn Baldwin * AIO backends should permit cancellation of queued requests waiting to 182f3215338SJohn Baldwin * be serviced by installing a cancel routine while the request is 183f3215338SJohn Baldwin * queued. The cancellation routine should dequeue the request if 184f3215338SJohn Baldwin * necessary and cancel it. Care must be used to handle races between 185f3215338SJohn Baldwin * queueing and dequeueing requests and cancellation. 186f3215338SJohn Baldwin * 187f3215338SJohn Baldwin * When queueing a request somewhere such that it can be cancelled, the 188f3215338SJohn Baldwin * caller should: 189f3215338SJohn Baldwin * 190f3215338SJohn Baldwin * 1) Acquire lock that protects the associated queue. 191f3215338SJohn Baldwin * 2) Call aio_set_cancel_function() to install the cancel routine. 192f3215338SJohn Baldwin * 3) If that fails, the request has a pending cancel and should be 193f3215338SJohn Baldwin * cancelled via aio_cancel(). 194f3215338SJohn Baldwin * 4) Queue the request. 195f3215338SJohn Baldwin * 196f3215338SJohn Baldwin * When dequeueing a request to service it or hand it off to somewhere else, 197f3215338SJohn Baldwin * the caller should: 198f3215338SJohn Baldwin * 199f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 200f3215338SJohn Baldwin * 2) Dequeue the request. 201f3215338SJohn Baldwin * 3) Call aio_clear_cancel_function() to clear the cancel routine. 202f3215338SJohn Baldwin * 4) If that fails, the cancel routine is about to be called. The 203f3215338SJohn Baldwin * caller should ignore the request. 204f3215338SJohn Baldwin * 205f3215338SJohn Baldwin * The cancel routine should: 206f3215338SJohn Baldwin * 207f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 208f3215338SJohn Baldwin * 2) Call aio_cancel_cleared() to determine if the request is already 209f3215338SJohn Baldwin * dequeued due to a race with dequeueing thread. 210f3215338SJohn Baldwin * 3) If that fails, dequeue the request. 211f3215338SJohn Baldwin * 4) Cancel the request via aio_cancel(). 212f3215338SJohn Baldwin */ 213f3215338SJohn Baldwin 214f3215338SJohn Baldwin bool aio_cancel_cleared(struct kaiocb *job); 215f3215338SJohn Baldwin void aio_cancel(struct kaiocb *job); 216f3215338SJohn Baldwin bool aio_clear_cancel_function(struct kaiocb *job); 217f3215338SJohn Baldwin void aio_complete(struct kaiocb *job, long status, int error); 218f3215338SJohn Baldwin void aio_schedule(struct kaiocb *job, aio_handle_fn_t *func); 219f3215338SJohn Baldwin bool aio_set_cancel_function(struct kaiocb *job, aio_cancel_fn_t *func); 220f3215338SJohn Baldwin void aio_switch_vmspace(struct kaiocb *job); 221f3215338SJohn Baldwin 222f3215338SJohn Baldwin #else /* !_KERNEL */ 223f0231545SDmitrij Tejblum 22434d3ac59SDavid Schultz struct timespec; 22534d3ac59SDavid Schultz 226f0231545SDmitrij Tejblum __BEGIN_DECLS 2270f606585SJohn Dyson /* 2280f606585SJohn Dyson * Asynchronously read from a file 2290f606585SJohn Dyson */ 230f0231545SDmitrij Tejblum int aio_read(struct aiocb *); 231022ca2fcSAlan Somers #if __BSD_VISIBLE 232022ca2fcSAlan Somers int aio_readv(struct aiocb *); 233022ca2fcSAlan Somers #endif 2340f606585SJohn Dyson 2350f606585SJohn Dyson /* 2360f606585SJohn Dyson * Asynchronously write to file 2370f606585SJohn Dyson */ 238f0231545SDmitrij Tejblum int aio_write(struct aiocb *); 239022ca2fcSAlan Somers #if __BSD_VISIBLE 240022ca2fcSAlan Somers int aio_writev(struct aiocb *); 241022ca2fcSAlan Somers #endif 2420f606585SJohn Dyson 2430f606585SJohn Dyson /* 2440f606585SJohn Dyson * List I/O Asynchronously/synchronously read/write to/from file 2450f606585SJohn Dyson * "lio_mode" specifies whether or not the I/O is synchronous. 2460f606585SJohn Dyson * "acb_list" is an array of "nacb_listent" I/O control blocks. 2470f606585SJohn Dyson * when all I/Os are complete, the optional signal "sig" is sent. 2480f606585SJohn Dyson */ 249049342a9SEd Schouten int lio_listio(int, struct aiocb *__restrict const *__restrict, int, 250049342a9SEd Schouten struct sigevent *); 2510f606585SJohn Dyson 2520f606585SJohn Dyson /* 2530f606585SJohn Dyson * Get completion status 2540f606585SJohn Dyson * returns EINPROGRESS until I/O is complete. 2550f606585SJohn Dyson * this routine does not block. 2560f606585SJohn Dyson */ 257f0231545SDmitrij Tejblum int aio_error(const struct aiocb *); 2580f606585SJohn Dyson 2590f606585SJohn Dyson /* 2600f606585SJohn Dyson * Finish up I/O, releasing I/O resources and returns the value 2610f606585SJohn Dyson * that would have been associated with a synchronous I/O request. 2620f606585SJohn Dyson * This routine must be called once and only once for each 2630f606585SJohn Dyson * I/O control block who has had I/O associated with it. 2640f606585SJohn Dyson */ 265f0231545SDmitrij Tejblum ssize_t aio_return(struct aiocb *); 2660f606585SJohn Dyson 2670f606585SJohn Dyson /* 2684270aed7SAlan Cox * Cancel I/O 2690f606585SJohn Dyson */ 270f0231545SDmitrij Tejblum int aio_cancel(int, struct aiocb *); 2710f606585SJohn Dyson 2720f606585SJohn Dyson /* 2730f606585SJohn Dyson * Suspend until all specified I/O or timeout is complete. 2740f606585SJohn Dyson */ 275f0231545SDmitrij Tejblum int aio_suspend(const struct aiocb * const[], int, const struct timespec *); 2760f606585SJohn Dyson 2776160e12cSGleb Smirnoff /* 2786160e12cSGleb Smirnoff * Asynchronous mlock 2796160e12cSGleb Smirnoff */ 2806160e12cSGleb Smirnoff int aio_mlock(struct aiocb *); 2816160e12cSGleb Smirnoff 282b8db1c9fSJohn Baldwin #if __BSD_VISIBLE 283bb430bc7SJohn Baldwin ssize_t aio_waitcomplete(struct aiocb **, struct timespec *); 28406cb1c3fSKonstantin Belousov int aio_read2(struct aiocb *, int); 28506cb1c3fSKonstantin Belousov int aio_write2(struct aiocb *, int); 28634d3ac59SDavid Schultz #endif 287bfbbc4aaSJason Evans 28853fcc63cSDavid Xu int aio_fsync(int op, struct aiocb *aiocbp); 289f0231545SDmitrij Tejblum __END_DECLS 29071af8fbaSJohn Dyson 291f3215338SJohn Baldwin #endif /* !_KERNEL */ 2925aaef07cSJohn Dyson 293f3215338SJohn Baldwin #endif /* !_SYS_AIO_H_ */ 294