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 */ 122f3215338SJohn Baldwin int inputcharge; /* (*) input blocks */ 123f3215338SJohn Baldwin int outputcharge; /* (*) output blocks */ 124f3215338SJohn Baldwin struct bio *bp; /* (*) BIO backend BIO pointer */ 125f3215338SJohn Baldwin struct buf *pbuf; /* (*) BIO backend buffer pointer */ 126f3215338SJohn Baldwin struct vm_page *pages[btoc(MAXPHYS)+1]; /* BIO backend pages */ 127f3215338SJohn Baldwin int npages; /* BIO backend number of pages */ 128f3215338SJohn Baldwin struct proc *userproc; /* (*) user process */ 129f3215338SJohn Baldwin struct ucred *cred; /* (*) active credential when created */ 130f3215338SJohn Baldwin struct file *fd_file; /* (*) pointer to file structure */ 131f3215338SJohn Baldwin struct aioliojob *lio; /* (*) optional lio job */ 132f3215338SJohn Baldwin struct aiocb *ujob; /* (*) pointer in userspace of aiocb */ 133f3215338SJohn Baldwin struct knlist klist; /* (a) list of knotes */ 134f3215338SJohn Baldwin struct aiocb uaiocb; /* (*) copy of user I/O control block */ 135f3215338SJohn Baldwin ksiginfo_t ksi; /* (a) realtime signal info */ 136f3215338SJohn Baldwin uint64_t seqno; /* (*) job number */ 137f3215338SJohn Baldwin int pending; /* (a) number of pending I/O, aio_fsync only */ 138f3215338SJohn Baldwin aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */ 139f3215338SJohn Baldwin aio_handle_fn_t *handle_fn; /* (c) backend handle function */ 140f3215338SJohn Baldwin }; 141f3215338SJohn Baldwin 142f3215338SJohn Baldwin struct socket; 143f3215338SJohn Baldwin struct sockbuf; 144f3215338SJohn Baldwin 145f3215338SJohn Baldwin /* 146f3215338SJohn Baldwin * AIO backends should permit cancellation of queued requests waiting to 147f3215338SJohn Baldwin * be serviced by installing a cancel routine while the request is 148f3215338SJohn Baldwin * queued. The cancellation routine should dequeue the request if 149f3215338SJohn Baldwin * necessary and cancel it. Care must be used to handle races between 150f3215338SJohn Baldwin * queueing and dequeueing requests and cancellation. 151f3215338SJohn Baldwin * 152f3215338SJohn Baldwin * When queueing a request somewhere such that it can be cancelled, the 153f3215338SJohn Baldwin * caller should: 154f3215338SJohn Baldwin * 155f3215338SJohn Baldwin * 1) Acquire lock that protects the associated queue. 156f3215338SJohn Baldwin * 2) Call aio_set_cancel_function() to install the cancel routine. 157f3215338SJohn Baldwin * 3) If that fails, the request has a pending cancel and should be 158f3215338SJohn Baldwin * cancelled via aio_cancel(). 159f3215338SJohn Baldwin * 4) Queue the request. 160f3215338SJohn Baldwin * 161f3215338SJohn Baldwin * When dequeueing a request to service it or hand it off to somewhere else, 162f3215338SJohn Baldwin * the caller should: 163f3215338SJohn Baldwin * 164f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 165f3215338SJohn Baldwin * 2) Dequeue the request. 166f3215338SJohn Baldwin * 3) Call aio_clear_cancel_function() to clear the cancel routine. 167f3215338SJohn Baldwin * 4) If that fails, the cancel routine is about to be called. The 168f3215338SJohn Baldwin * caller should ignore the request. 169f3215338SJohn Baldwin * 170f3215338SJohn Baldwin * The cancel routine should: 171f3215338SJohn Baldwin * 172f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 173f3215338SJohn Baldwin * 2) Call aio_cancel_cleared() to determine if the request is already 174f3215338SJohn Baldwin * dequeued due to a race with dequeueing thread. 175f3215338SJohn Baldwin * 3) If that fails, dequeue the request. 176f3215338SJohn Baldwin * 4) Cancel the request via aio_cancel(). 177f3215338SJohn Baldwin */ 178f3215338SJohn Baldwin 179f3215338SJohn Baldwin bool aio_cancel_cleared(struct kaiocb *job); 180f3215338SJohn Baldwin void aio_cancel(struct kaiocb *job); 181f3215338SJohn Baldwin bool aio_clear_cancel_function(struct kaiocb *job); 182f3215338SJohn Baldwin void aio_complete(struct kaiocb *job, long status, int error); 183f3215338SJohn Baldwin void aio_schedule(struct kaiocb *job, aio_handle_fn_t *func); 184f3215338SJohn Baldwin bool aio_set_cancel_function(struct kaiocb *job, aio_cancel_fn_t *func); 185f3215338SJohn Baldwin void aio_switch_vmspace(struct kaiocb *job); 186f3215338SJohn Baldwin 187f3215338SJohn Baldwin #else /* !_KERNEL */ 188f0231545SDmitrij Tejblum 18934d3ac59SDavid Schultz struct timespec; 19034d3ac59SDavid Schultz 191f0231545SDmitrij Tejblum __BEGIN_DECLS 1920f606585SJohn Dyson /* 1930f606585SJohn Dyson * Asynchronously read from a file 1940f606585SJohn Dyson */ 195f0231545SDmitrij Tejblum int aio_read(struct aiocb *); 1960f606585SJohn Dyson 1970f606585SJohn Dyson /* 1980f606585SJohn Dyson * Asynchronously write to file 1990f606585SJohn Dyson */ 200f0231545SDmitrij Tejblum int aio_write(struct aiocb *); 2010f606585SJohn Dyson 2020f606585SJohn Dyson /* 2030f606585SJohn Dyson * List I/O Asynchronously/synchronously read/write to/from file 2040f606585SJohn Dyson * "lio_mode" specifies whether or not the I/O is synchronous. 2050f606585SJohn Dyson * "acb_list" is an array of "nacb_listent" I/O control blocks. 2060f606585SJohn Dyson * when all I/Os are complete, the optional signal "sig" is sent. 2070f606585SJohn Dyson */ 208f0231545SDmitrij Tejblum int lio_listio(int, struct aiocb * const [], int, struct sigevent *); 2090f606585SJohn Dyson 2100f606585SJohn Dyson /* 2110f606585SJohn Dyson * Get completion status 2120f606585SJohn Dyson * returns EINPROGRESS until I/O is complete. 2130f606585SJohn Dyson * this routine does not block. 2140f606585SJohn Dyson */ 215f0231545SDmitrij Tejblum int aio_error(const struct aiocb *); 2160f606585SJohn Dyson 2170f606585SJohn Dyson /* 2180f606585SJohn Dyson * Finish up I/O, releasing I/O resources and returns the value 2190f606585SJohn Dyson * that would have been associated with a synchronous I/O request. 2200f606585SJohn Dyson * This routine must be called once and only once for each 2210f606585SJohn Dyson * I/O control block who has had I/O associated with it. 2220f606585SJohn Dyson */ 223f0231545SDmitrij Tejblum ssize_t aio_return(struct aiocb *); 2240f606585SJohn Dyson 2250f606585SJohn Dyson /* 2264270aed7SAlan Cox * Cancel I/O 2270f606585SJohn Dyson */ 228f0231545SDmitrij Tejblum int aio_cancel(int, struct aiocb *); 2290f606585SJohn Dyson 2300f606585SJohn Dyson /* 2310f606585SJohn Dyson * Suspend until all specified I/O or timeout is complete. 2320f606585SJohn Dyson */ 233f0231545SDmitrij Tejblum int aio_suspend(const struct aiocb * const[], int, const struct timespec *); 2340f606585SJohn Dyson 2356160e12cSGleb Smirnoff /* 2366160e12cSGleb Smirnoff * Asynchronous mlock 2376160e12cSGleb Smirnoff */ 2386160e12cSGleb Smirnoff int aio_mlock(struct aiocb *); 2396160e12cSGleb Smirnoff 24034d3ac59SDavid Schultz #ifdef __BSD_VISIBLE 241*bb430bc7SJohn Baldwin ssize_t aio_waitcomplete(struct aiocb **, struct timespec *); 24234d3ac59SDavid Schultz #endif 243bfbbc4aaSJason Evans 24453fcc63cSDavid Xu int aio_fsync(int op, struct aiocb *aiocbp); 245f0231545SDmitrij Tejblum __END_DECLS 24671af8fbaSJohn Dyson 247f3215338SJohn Baldwin #endif /* !_KERNEL */ 2485aaef07cSJohn Dyson 249f3215338SJohn Baldwin #endif /* !_SYS_AIO_H_ */ 250