160727d8bSWarner Losh /*- 20f606585SJohn Dyson * Copyright (c) 1997 John S. Dyson. All rights reserved. 30f606585SJohn Dyson * 40f606585SJohn Dyson * Redistribution and use in source and binary forms, with or without 50f606585SJohn Dyson * modification, are permitted provided that the following conditions 60f606585SJohn Dyson * are met: 70f606585SJohn Dyson * 1. Redistributions of source code must retain the above copyright 80f606585SJohn Dyson * notice, this list of conditions and the following disclaimer. 90f606585SJohn Dyson * 2. John S. Dyson's name may not be used to endorse or promote products 100f606585SJohn Dyson * derived from this software without specific prior written permission. 110f606585SJohn Dyson * 120f606585SJohn Dyson * DISCLAIMER: This code isn't warranted to do anything useful. Anything 130f606585SJohn Dyson * bad that happens because of using this software isn't the responsibility 140f606585SJohn Dyson * of the author. This software is distributed AS-IS. 150f606585SJohn Dyson * 16c3aac50fSPeter Wemm * $FreeBSD$ 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> 28f3215338SJohn Baldwin #endif 29f0231545SDmitrij Tejblum 300f606585SJohn Dyson /* 310f606585SJohn Dyson * Returned by aio_cancel: 320f606585SJohn Dyson */ 330f606585SJohn Dyson #define AIO_CANCELED 0x1 3478922e41SJohn Dyson #define AIO_NOTCANCELED 0x2 350f606585SJohn Dyson #define AIO_ALLDONE 0x3 360f606585SJohn Dyson 370f606585SJohn Dyson /* 380f606585SJohn Dyson * LIO opcodes 390f606585SJohn Dyson */ 400f606585SJohn Dyson #define LIO_NOP 0x0 410f606585SJohn Dyson #define LIO_WRITE 0x1 420f606585SJohn Dyson #define LIO_READ 0x2 4353fcc63cSDavid Xu #ifdef _KERNEL 4453fcc63cSDavid Xu #define LIO_SYNC 0x3 456160e12cSGleb Smirnoff #define LIO_MLOCK 0x4 4653fcc63cSDavid Xu #endif 470f606585SJohn Dyson 480f606585SJohn Dyson /* 490f606585SJohn Dyson * LIO modes 500f606585SJohn Dyson */ 510f606585SJohn Dyson #define LIO_NOWAIT 0x0 520f606585SJohn Dyson #define LIO_WAIT 0x1 530f606585SJohn Dyson 540f606585SJohn Dyson /* 557a2ac24cSPeter Dufault * Maximum number of allowed LIO operations 567a2ac24cSPeter Dufault */ 577a2ac24cSPeter Dufault #define AIO_LISTIO_MAX 16 587a2ac24cSPeter Dufault 59f3215338SJohn Baldwin #ifdef _KERNEL 60f3215338SJohn Baldwin 61f3215338SJohn Baldwin /* Default values of tunables for the AIO worker pool. */ 62f3215338SJohn Baldwin 63f3215338SJohn Baldwin #ifndef MAX_AIO_PROCS 64f3215338SJohn Baldwin #define MAX_AIO_PROCS 32 65f3215338SJohn Baldwin #endif 66f3215338SJohn Baldwin 67f3215338SJohn Baldwin #ifndef TARGET_AIO_PROCS 68f3215338SJohn Baldwin #define TARGET_AIO_PROCS 4 69f3215338SJohn Baldwin #endif 70f3215338SJohn Baldwin 71f3215338SJohn Baldwin #ifndef AIOD_LIFETIME_DEFAULT 72f3215338SJohn Baldwin #define AIOD_LIFETIME_DEFAULT (30 * hz) 73f3215338SJohn Baldwin #endif 74f3215338SJohn Baldwin 75f3215338SJohn Baldwin #endif 76f3215338SJohn Baldwin 777a2ac24cSPeter Dufault /* 780f606585SJohn Dyson * Private members for aiocb -- don't access 790f606585SJohn Dyson * directly. 800f606585SJohn Dyson */ 810f606585SJohn Dyson struct __aiocb_private { 8296b8882aSAlan Cox long status; 8396b8882aSAlan Cox long error; 840f606585SJohn Dyson void *kernelinfo; 850f606585SJohn Dyson }; 860f606585SJohn Dyson 870f606585SJohn Dyson /* 880f606585SJohn Dyson * I/O control block 890f606585SJohn Dyson */ 900f606585SJohn Dyson typedef struct aiocb { 910f606585SJohn Dyson int aio_fildes; /* File descriptor */ 920f606585SJohn Dyson off_t aio_offset; /* File offset for I/O */ 9378922e41SJohn Dyson volatile void *aio_buf; /* I/O buffer in process space */ 940f606585SJohn Dyson size_t aio_nbytes; /* Number of bytes for I/O */ 95c4592cbcSJohn Baldwin int __spare__[2]; 96c4592cbcSJohn Baldwin void *__spare2__; 970f606585SJohn Dyson int aio_lio_opcode; /* LIO opcode */ 980f606585SJohn Dyson int aio_reqprio; /* Request priority -- ignored */ 990f606585SJohn Dyson struct __aiocb_private _aiocb_private; 1000972628aSDavid Xu struct sigevent aio_sigevent; /* Signal to deliver */ 1010f606585SJohn Dyson } aiocb_t; 1020f606585SJohn Dyson 103f3215338SJohn Baldwin #ifdef _KERNEL 104f3215338SJohn Baldwin 105f3215338SJohn Baldwin typedef void aio_cancel_fn_t(struct kaiocb *); 106f3215338SJohn Baldwin typedef void aio_handle_fn_t(struct kaiocb *); 107f3215338SJohn Baldwin 108f3215338SJohn Baldwin /* 109f3215338SJohn Baldwin * Kernel version of an I/O control block. 110f3215338SJohn Baldwin * 111f3215338SJohn Baldwin * Locking key: 112f3215338SJohn Baldwin * * - need not protected 113f3215338SJohn Baldwin * a - locked by kaioinfo lock 114f3215338SJohn Baldwin * b - locked by backend lock 115f3215338SJohn Baldwin * c - locked by aio_job_mtx 116f3215338SJohn Baldwin */ 117f3215338SJohn Baldwin struct kaiocb { 118f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) list; /* (b) backend-specific list of jobs */ 119f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) plist; /* (a) lists of pending / done jobs */ 120f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) allist; /* (a) list of all jobs in proc */ 121f3215338SJohn Baldwin int jobflags; /* (a) job flags */ 122b1012d80SJohn Baldwin int inblock; /* (*) input blocks */ 123b1012d80SJohn Baldwin int outblock; /* (*) output blocks */ 124b1012d80SJohn Baldwin int msgsnd; /* (*) messages sent */ 125b1012d80SJohn Baldwin int msgrcv; /* (*) messages received */ 126f3215338SJohn Baldwin struct proc *userproc; /* (*) user process */ 127f3215338SJohn Baldwin struct ucred *cred; /* (*) active credential when created */ 128f3215338SJohn Baldwin struct file *fd_file; /* (*) pointer to file structure */ 129f3215338SJohn Baldwin struct aioliojob *lio; /* (*) optional lio job */ 130f3215338SJohn Baldwin struct aiocb *ujob; /* (*) pointer in userspace of aiocb */ 131f3215338SJohn Baldwin struct knlist klist; /* (a) list of knotes */ 132f3215338SJohn Baldwin struct aiocb uaiocb; /* (*) copy of user I/O control block */ 133f3215338SJohn Baldwin ksiginfo_t ksi; /* (a) realtime signal info */ 134f3215338SJohn Baldwin uint64_t seqno; /* (*) job number */ 135f3215338SJohn Baldwin aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */ 136f3215338SJohn Baldwin aio_handle_fn_t *handle_fn; /* (c) backend handle function */ 137fe0bdd1dSJohn Baldwin union { /* Backend-specific data fields */ 138fe0bdd1dSJohn Baldwin struct { /* BIO backend */ 139fe0bdd1dSJohn Baldwin struct bio *bp; /* (*) BIO pointer */ 140fe0bdd1dSJohn Baldwin struct buf *pbuf; /* (*) buffer pointer */ 141fe0bdd1dSJohn Baldwin struct vm_page *pages[btoc(MAXPHYS)+1]; /* (*) */ 142fe0bdd1dSJohn Baldwin int npages; /* (*) number of pages */ 143fe0bdd1dSJohn Baldwin }; 144fe0bdd1dSJohn Baldwin struct { /* fsync() requests */ 145fe0bdd1dSJohn Baldwin int pending; /* (a) number of pending I/O */ 146fe0bdd1dSJohn Baldwin }; 147fe0bdd1dSJohn Baldwin struct { 148fe0bdd1dSJohn Baldwin void *backend1; 149fe0bdd1dSJohn Baldwin void *backend2; 150fe0bdd1dSJohn Baldwin long backend3; 151fe0bdd1dSJohn Baldwin int backend4; 152fe0bdd1dSJohn Baldwin }; 153fe0bdd1dSJohn Baldwin }; 154f3215338SJohn Baldwin }; 155f3215338SJohn Baldwin 156f3215338SJohn Baldwin struct socket; 157f3215338SJohn Baldwin struct sockbuf; 158f3215338SJohn Baldwin 159f3215338SJohn Baldwin /* 160f3215338SJohn Baldwin * AIO backends should permit cancellation of queued requests waiting to 161f3215338SJohn Baldwin * be serviced by installing a cancel routine while the request is 162f3215338SJohn Baldwin * queued. The cancellation routine should dequeue the request if 163f3215338SJohn Baldwin * necessary and cancel it. Care must be used to handle races between 164f3215338SJohn Baldwin * queueing and dequeueing requests and cancellation. 165f3215338SJohn Baldwin * 166f3215338SJohn Baldwin * When queueing a request somewhere such that it can be cancelled, the 167f3215338SJohn Baldwin * caller should: 168f3215338SJohn Baldwin * 169f3215338SJohn Baldwin * 1) Acquire lock that protects the associated queue. 170f3215338SJohn Baldwin * 2) Call aio_set_cancel_function() to install the cancel routine. 171f3215338SJohn Baldwin * 3) If that fails, the request has a pending cancel and should be 172f3215338SJohn Baldwin * cancelled via aio_cancel(). 173f3215338SJohn Baldwin * 4) Queue the request. 174f3215338SJohn Baldwin * 175f3215338SJohn Baldwin * When dequeueing a request to service it or hand it off to somewhere else, 176f3215338SJohn Baldwin * the caller should: 177f3215338SJohn Baldwin * 178f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 179f3215338SJohn Baldwin * 2) Dequeue the request. 180f3215338SJohn Baldwin * 3) Call aio_clear_cancel_function() to clear the cancel routine. 181f3215338SJohn Baldwin * 4) If that fails, the cancel routine is about to be called. The 182f3215338SJohn Baldwin * caller should ignore the request. 183f3215338SJohn Baldwin * 184f3215338SJohn Baldwin * The cancel routine should: 185f3215338SJohn Baldwin * 186f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 187f3215338SJohn Baldwin * 2) Call aio_cancel_cleared() to determine if the request is already 188f3215338SJohn Baldwin * dequeued due to a race with dequeueing thread. 189f3215338SJohn Baldwin * 3) If that fails, dequeue the request. 190f3215338SJohn Baldwin * 4) Cancel the request via aio_cancel(). 191f3215338SJohn Baldwin */ 192f3215338SJohn Baldwin 193f3215338SJohn Baldwin bool aio_cancel_cleared(struct kaiocb *job); 194f3215338SJohn Baldwin void aio_cancel(struct kaiocb *job); 195f3215338SJohn Baldwin bool aio_clear_cancel_function(struct kaiocb *job); 196f3215338SJohn Baldwin void aio_complete(struct kaiocb *job, long status, int error); 197f3215338SJohn Baldwin void aio_schedule(struct kaiocb *job, aio_handle_fn_t *func); 198f3215338SJohn Baldwin bool aio_set_cancel_function(struct kaiocb *job, aio_cancel_fn_t *func); 199f3215338SJohn Baldwin void aio_switch_vmspace(struct kaiocb *job); 200f3215338SJohn Baldwin 201f3215338SJohn Baldwin #else /* !_KERNEL */ 202f0231545SDmitrij Tejblum 20334d3ac59SDavid Schultz struct timespec; 20434d3ac59SDavid Schultz 205f0231545SDmitrij Tejblum __BEGIN_DECLS 2060f606585SJohn Dyson /* 2070f606585SJohn Dyson * Asynchronously read from a file 2080f606585SJohn Dyson */ 209f0231545SDmitrij Tejblum int aio_read(struct aiocb *); 2100f606585SJohn Dyson 2110f606585SJohn Dyson /* 2120f606585SJohn Dyson * Asynchronously write to file 2130f606585SJohn Dyson */ 214f0231545SDmitrij Tejblum int aio_write(struct aiocb *); 2150f606585SJohn Dyson 2160f606585SJohn Dyson /* 2170f606585SJohn Dyson * List I/O Asynchronously/synchronously read/write to/from file 2180f606585SJohn Dyson * "lio_mode" specifies whether or not the I/O is synchronous. 2190f606585SJohn Dyson * "acb_list" is an array of "nacb_listent" I/O control blocks. 2200f606585SJohn Dyson * when all I/Os are complete, the optional signal "sig" is sent. 2210f606585SJohn Dyson */ 222049342a9SEd Schouten int lio_listio(int, struct aiocb *__restrict const *__restrict, int, 223049342a9SEd Schouten struct sigevent *); 2240f606585SJohn Dyson 2250f606585SJohn Dyson /* 2260f606585SJohn Dyson * Get completion status 2270f606585SJohn Dyson * returns EINPROGRESS until I/O is complete. 2280f606585SJohn Dyson * this routine does not block. 2290f606585SJohn Dyson */ 230f0231545SDmitrij Tejblum int aio_error(const struct aiocb *); 2310f606585SJohn Dyson 2320f606585SJohn Dyson /* 2330f606585SJohn Dyson * Finish up I/O, releasing I/O resources and returns the value 2340f606585SJohn Dyson * that would have been associated with a synchronous I/O request. 2350f606585SJohn Dyson * This routine must be called once and only once for each 2360f606585SJohn Dyson * I/O control block who has had I/O associated with it. 2370f606585SJohn Dyson */ 238f0231545SDmitrij Tejblum ssize_t aio_return(struct aiocb *); 2390f606585SJohn Dyson 2400f606585SJohn Dyson /* 2414270aed7SAlan Cox * Cancel I/O 2420f606585SJohn Dyson */ 243f0231545SDmitrij Tejblum int aio_cancel(int, struct aiocb *); 2440f606585SJohn Dyson 2450f606585SJohn Dyson /* 2460f606585SJohn Dyson * Suspend until all specified I/O or timeout is complete. 2470f606585SJohn Dyson */ 248f0231545SDmitrij Tejblum int aio_suspend(const struct aiocb * const[], int, const struct timespec *); 2490f606585SJohn Dyson 2506160e12cSGleb Smirnoff /* 2516160e12cSGleb Smirnoff * Asynchronous mlock 2526160e12cSGleb Smirnoff */ 2536160e12cSGleb Smirnoff int aio_mlock(struct aiocb *); 2546160e12cSGleb Smirnoff 255*b8db1c9fSJohn Baldwin #if __BSD_VISIBLE 256bb430bc7SJohn Baldwin ssize_t aio_waitcomplete(struct aiocb **, struct timespec *); 25734d3ac59SDavid Schultz #endif 258bfbbc4aaSJason Evans 25953fcc63cSDavid Xu int aio_fsync(int op, struct aiocb *aiocbp); 260f0231545SDmitrij Tejblum __END_DECLS 26171af8fbaSJohn Dyson 262f3215338SJohn Baldwin #endif /* !_KERNEL */ 2635aaef07cSJohn Dyson 264f3215338SJohn Baldwin #endif /* !_SYS_AIO_H_ */ 265