160727d8bSWarner Losh /*- 2c4e20cadSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * 18c3aac50fSPeter Wemm * $FreeBSD$ 190f606585SJohn Dyson */ 200f606585SJohn Dyson 21f0231545SDmitrij Tejblum #ifndef _SYS_AIO_H_ 22f0231545SDmitrij Tejblum #define _SYS_AIO_H_ 23f0231545SDmitrij Tejblum 240f606585SJohn Dyson #include <sys/types.h> 258a6472b7SPeter Dufault #include <sys/signal.h> 26f3215338SJohn Baldwin #ifdef _KERNEL 27f3215338SJohn Baldwin #include <sys/queue.h> 28f3215338SJohn Baldwin #include <sys/event.h> 29f3215338SJohn Baldwin #include <sys/signalvar.h> 30022ca2fcSAlan Somers #include <sys/uio.h> 31f3215338SJohn Baldwin #endif 32f0231545SDmitrij Tejblum 330f606585SJohn Dyson /* 340f606585SJohn Dyson * Returned by aio_cancel: 350f606585SJohn Dyson */ 360f606585SJohn Dyson #define AIO_CANCELED 0x1 3778922e41SJohn Dyson #define AIO_NOTCANCELED 0x2 380f606585SJohn Dyson #define AIO_ALLDONE 0x3 390f606585SJohn Dyson 400f606585SJohn Dyson /* 410f606585SJohn Dyson * LIO opcodes 420f606585SJohn Dyson */ 430f606585SJohn Dyson #define LIO_NOP 0x0 440f606585SJohn Dyson #define LIO_WRITE 0x1 450f606585SJohn Dyson #define LIO_READ 0x2 46*f30a1ae8SThomas Munro #if __BSD_VISIBLE 472247f489SAlan Somers #define LIO_VECTORED 0x4 482247f489SAlan Somers #define LIO_WRITEV (LIO_WRITE | LIO_VECTORED) 492247f489SAlan Somers #define LIO_READV (LIO_READ | LIO_VECTORED) 50*f30a1ae8SThomas Munro #endif 51*f30a1ae8SThomas Munro #if defined(_KERNEL) || defined(_WANT_ALL_LIO_OPCODES) 522247f489SAlan Somers #define LIO_SYNC 0x8 532247f489SAlan Somers #define LIO_DSYNC (0x10 | LIO_SYNC) 542247f489SAlan Somers #define LIO_MLOCK 0x20 5553fcc63cSDavid Xu #endif 560f606585SJohn Dyson 570f606585SJohn Dyson /* 580f606585SJohn Dyson * LIO modes 590f606585SJohn Dyson */ 600f606585SJohn Dyson #define LIO_NOWAIT 0x0 610f606585SJohn Dyson #define LIO_WAIT 0x1 620f606585SJohn Dyson 630f606585SJohn Dyson /* 6421b8a7a6SAlan Somers * Maximum number of operations in a single lio_listio call 657a2ac24cSPeter Dufault */ 667a2ac24cSPeter Dufault #define AIO_LISTIO_MAX 16 677a2ac24cSPeter Dufault 68f3215338SJohn Baldwin #ifdef _KERNEL 69f3215338SJohn Baldwin 70f3215338SJohn Baldwin /* Default values of tunables for the AIO worker pool. */ 71f3215338SJohn Baldwin 72f3215338SJohn Baldwin #ifndef MAX_AIO_PROCS 73f3215338SJohn Baldwin #define MAX_AIO_PROCS 32 74f3215338SJohn Baldwin #endif 75f3215338SJohn Baldwin 76f3215338SJohn Baldwin #ifndef TARGET_AIO_PROCS 77f3215338SJohn Baldwin #define TARGET_AIO_PROCS 4 78f3215338SJohn Baldwin #endif 79f3215338SJohn Baldwin 80f3215338SJohn Baldwin #ifndef AIOD_LIFETIME_DEFAULT 81f3215338SJohn Baldwin #define AIOD_LIFETIME_DEFAULT (30 * hz) 82f3215338SJohn Baldwin #endif 83f3215338SJohn Baldwin 84f3215338SJohn Baldwin #endif 85f3215338SJohn Baldwin 867a2ac24cSPeter Dufault /* 870f606585SJohn Dyson * Private members for aiocb -- don't access 880f606585SJohn Dyson * directly. 890f606585SJohn Dyson */ 900f606585SJohn Dyson struct __aiocb_private { 9196b8882aSAlan Cox long status; 9296b8882aSAlan Cox long error; 930f606585SJohn Dyson void *kernelinfo; 940f606585SJohn Dyson }; 950f606585SJohn Dyson 960f606585SJohn Dyson /* 970f606585SJohn Dyson * I/O control block 980f606585SJohn Dyson */ 990f606585SJohn Dyson typedef struct aiocb { 1000f606585SJohn Dyson int aio_fildes; /* File descriptor */ 1010f606585SJohn Dyson off_t aio_offset; /* File offset for I/O */ 10278922e41SJohn Dyson volatile void *aio_buf; /* I/O buffer in process space */ 1030f606585SJohn Dyson size_t aio_nbytes; /* Number of bytes for I/O */ 104c4592cbcSJohn Baldwin int __spare__[2]; 105c4592cbcSJohn Baldwin void *__spare2__; 1060f606585SJohn Dyson int aio_lio_opcode; /* LIO opcode */ 1070f606585SJohn Dyson int aio_reqprio; /* Request priority -- ignored */ 1080f606585SJohn Dyson struct __aiocb_private _aiocb_private; 1090972628aSDavid Xu struct sigevent aio_sigevent; /* Signal to deliver */ 1100f606585SJohn Dyson } aiocb_t; 1110f606585SJohn Dyson 112022ca2fcSAlan Somers #define aio_iov aio_buf /* I/O scatter/gather list */ 113022ca2fcSAlan Somers #define aio_iovcnt aio_nbytes /* Length of aio_iov */ 114022ca2fcSAlan Somers 115f3215338SJohn Baldwin #ifdef _KERNEL 116f3215338SJohn Baldwin 117f3215338SJohn Baldwin typedef void aio_cancel_fn_t(struct kaiocb *); 118f3215338SJohn Baldwin typedef void aio_handle_fn_t(struct kaiocb *); 119f3215338SJohn Baldwin 120f3215338SJohn Baldwin /* 121f3215338SJohn Baldwin * Kernel version of an I/O control block. 122f3215338SJohn Baldwin * 123f3215338SJohn Baldwin * Locking key: 124f3215338SJohn Baldwin * * - need not protected 125f3215338SJohn Baldwin * a - locked by kaioinfo lock 126f3215338SJohn Baldwin * b - locked by backend lock 127f3215338SJohn Baldwin * c - locked by aio_job_mtx 128f3215338SJohn Baldwin */ 129f3215338SJohn Baldwin struct kaiocb { 130f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) list; /* (b) backend-specific list of jobs */ 131f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) plist; /* (a) lists of pending / done jobs */ 132f3215338SJohn Baldwin TAILQ_ENTRY(kaiocb) allist; /* (a) list of all jobs in proc */ 133f3215338SJohn Baldwin int jobflags; /* (a) job flags */ 134b1012d80SJohn Baldwin int inblock; /* (*) input blocks */ 135b1012d80SJohn Baldwin int outblock; /* (*) output blocks */ 136b1012d80SJohn Baldwin int msgsnd; /* (*) messages sent */ 137b1012d80SJohn Baldwin int msgrcv; /* (*) messages received */ 138f3215338SJohn Baldwin struct proc *userproc; /* (*) user process */ 139f3215338SJohn Baldwin struct ucred *cred; /* (*) active credential when created */ 140f3215338SJohn Baldwin struct file *fd_file; /* (*) pointer to file structure */ 141f3215338SJohn Baldwin struct aioliojob *lio; /* (*) optional lio job */ 142f3215338SJohn Baldwin struct aiocb *ujob; /* (*) pointer in userspace of aiocb */ 143f3215338SJohn Baldwin struct knlist klist; /* (a) list of knotes */ 144f3215338SJohn Baldwin struct aiocb uaiocb; /* (*) copy of user I/O control block */ 145022ca2fcSAlan Somers struct uio uio; /* (*) storage for non-vectored uio */ 146022ca2fcSAlan Somers struct iovec iov[1]; /* (*) storage for non-vectored uio */ 147022ca2fcSAlan Somers struct uio *uiop; /* (*) Possibly malloced uio */ 148f3215338SJohn Baldwin ksiginfo_t ksi; /* (a) realtime signal info */ 149f3215338SJohn Baldwin uint64_t seqno; /* (*) job number */ 150f3215338SJohn Baldwin aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */ 151f3215338SJohn Baldwin aio_handle_fn_t *handle_fn; /* (c) backend handle function */ 152fe0bdd1dSJohn Baldwin union { /* Backend-specific data fields */ 153022ca2fcSAlan Somers struct { /* BIO backend */ 154022ca2fcSAlan Somers int nbio; /* Number of remaining bios */ 155022ca2fcSAlan Somers int error; /* Worst error of all bios */ 156022ca2fcSAlan Somers long nbytes; /* Bytes completed so far */ 157022ca2fcSAlan Somers }; 158fe0bdd1dSJohn Baldwin struct { /* fsync() requests */ 159fe0bdd1dSJohn Baldwin int pending; /* (a) number of pending I/O */ 160fe0bdd1dSJohn Baldwin }; 16101206038SAlan Somers struct { /* socket backend */ 162fe0bdd1dSJohn Baldwin void *backend1; 163fe0bdd1dSJohn Baldwin long backend3; 164fe0bdd1dSJohn Baldwin int backend4; 165fe0bdd1dSJohn Baldwin }; 166fe0bdd1dSJohn Baldwin }; 167f3215338SJohn Baldwin }; 168f3215338SJohn Baldwin 169f3215338SJohn Baldwin struct socket; 170f3215338SJohn Baldwin struct sockbuf; 171f3215338SJohn Baldwin 172f3215338SJohn Baldwin /* 173f3215338SJohn Baldwin * AIO backends should permit cancellation of queued requests waiting to 174f3215338SJohn Baldwin * be serviced by installing a cancel routine while the request is 175f3215338SJohn Baldwin * queued. The cancellation routine should dequeue the request if 176f3215338SJohn Baldwin * necessary and cancel it. Care must be used to handle races between 177f3215338SJohn Baldwin * queueing and dequeueing requests and cancellation. 178f3215338SJohn Baldwin * 179f3215338SJohn Baldwin * When queueing a request somewhere such that it can be cancelled, the 180f3215338SJohn Baldwin * caller should: 181f3215338SJohn Baldwin * 182f3215338SJohn Baldwin * 1) Acquire lock that protects the associated queue. 183f3215338SJohn Baldwin * 2) Call aio_set_cancel_function() to install the cancel routine. 184f3215338SJohn Baldwin * 3) If that fails, the request has a pending cancel and should be 185f3215338SJohn Baldwin * cancelled via aio_cancel(). 186f3215338SJohn Baldwin * 4) Queue the request. 187f3215338SJohn Baldwin * 188f3215338SJohn Baldwin * When dequeueing a request to service it or hand it off to somewhere else, 189f3215338SJohn Baldwin * the caller should: 190f3215338SJohn Baldwin * 191f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 192f3215338SJohn Baldwin * 2) Dequeue the request. 193f3215338SJohn Baldwin * 3) Call aio_clear_cancel_function() to clear the cancel routine. 194f3215338SJohn Baldwin * 4) If that fails, the cancel routine is about to be called. The 195f3215338SJohn Baldwin * caller should ignore the request. 196f3215338SJohn Baldwin * 197f3215338SJohn Baldwin * The cancel routine should: 198f3215338SJohn Baldwin * 199f3215338SJohn Baldwin * 1) Acquire the lock that protects the associated queue. 200f3215338SJohn Baldwin * 2) Call aio_cancel_cleared() to determine if the request is already 201f3215338SJohn Baldwin * dequeued due to a race with dequeueing thread. 202f3215338SJohn Baldwin * 3) If that fails, dequeue the request. 203f3215338SJohn Baldwin * 4) Cancel the request via aio_cancel(). 204f3215338SJohn Baldwin */ 205f3215338SJohn Baldwin 206f3215338SJohn Baldwin bool aio_cancel_cleared(struct kaiocb *job); 207f3215338SJohn Baldwin void aio_cancel(struct kaiocb *job); 208f3215338SJohn Baldwin bool aio_clear_cancel_function(struct kaiocb *job); 209f3215338SJohn Baldwin void aio_complete(struct kaiocb *job, long status, int error); 210f3215338SJohn Baldwin void aio_schedule(struct kaiocb *job, aio_handle_fn_t *func); 211f3215338SJohn Baldwin bool aio_set_cancel_function(struct kaiocb *job, aio_cancel_fn_t *func); 212f3215338SJohn Baldwin void aio_switch_vmspace(struct kaiocb *job); 213f3215338SJohn Baldwin 214f3215338SJohn Baldwin #else /* !_KERNEL */ 215f0231545SDmitrij Tejblum 21634d3ac59SDavid Schultz struct timespec; 21734d3ac59SDavid Schultz 218f0231545SDmitrij Tejblum __BEGIN_DECLS 2190f606585SJohn Dyson /* 2200f606585SJohn Dyson * Asynchronously read from a file 2210f606585SJohn Dyson */ 222f0231545SDmitrij Tejblum int aio_read(struct aiocb *); 223022ca2fcSAlan Somers #if __BSD_VISIBLE 224022ca2fcSAlan Somers int aio_readv(struct aiocb *); 225022ca2fcSAlan Somers #endif 2260f606585SJohn Dyson 2270f606585SJohn Dyson /* 2280f606585SJohn Dyson * Asynchronously write to file 2290f606585SJohn Dyson */ 230f0231545SDmitrij Tejblum int aio_write(struct aiocb *); 231022ca2fcSAlan Somers #if __BSD_VISIBLE 232022ca2fcSAlan Somers int aio_writev(struct aiocb *); 233022ca2fcSAlan Somers #endif 2340f606585SJohn Dyson 2350f606585SJohn Dyson /* 2360f606585SJohn Dyson * List I/O Asynchronously/synchronously read/write to/from file 2370f606585SJohn Dyson * "lio_mode" specifies whether or not the I/O is synchronous. 2380f606585SJohn Dyson * "acb_list" is an array of "nacb_listent" I/O control blocks. 2390f606585SJohn Dyson * when all I/Os are complete, the optional signal "sig" is sent. 2400f606585SJohn Dyson */ 241049342a9SEd Schouten int lio_listio(int, struct aiocb *__restrict const *__restrict, int, 242049342a9SEd Schouten struct sigevent *); 2430f606585SJohn Dyson 2440f606585SJohn Dyson /* 2450f606585SJohn Dyson * Get completion status 2460f606585SJohn Dyson * returns EINPROGRESS until I/O is complete. 2470f606585SJohn Dyson * this routine does not block. 2480f606585SJohn Dyson */ 249f0231545SDmitrij Tejblum int aio_error(const struct aiocb *); 2500f606585SJohn Dyson 2510f606585SJohn Dyson /* 2520f606585SJohn Dyson * Finish up I/O, releasing I/O resources and returns the value 2530f606585SJohn Dyson * that would have been associated with a synchronous I/O request. 2540f606585SJohn Dyson * This routine must be called once and only once for each 2550f606585SJohn Dyson * I/O control block who has had I/O associated with it. 2560f606585SJohn Dyson */ 257f0231545SDmitrij Tejblum ssize_t aio_return(struct aiocb *); 2580f606585SJohn Dyson 2590f606585SJohn Dyson /* 2604270aed7SAlan Cox * Cancel I/O 2610f606585SJohn Dyson */ 262f0231545SDmitrij Tejblum int aio_cancel(int, struct aiocb *); 2630f606585SJohn Dyson 2640f606585SJohn Dyson /* 2650f606585SJohn Dyson * Suspend until all specified I/O or timeout is complete. 2660f606585SJohn Dyson */ 267f0231545SDmitrij Tejblum int aio_suspend(const struct aiocb * const[], int, const struct timespec *); 2680f606585SJohn Dyson 2696160e12cSGleb Smirnoff /* 2706160e12cSGleb Smirnoff * Asynchronous mlock 2716160e12cSGleb Smirnoff */ 2726160e12cSGleb Smirnoff int aio_mlock(struct aiocb *); 2736160e12cSGleb Smirnoff 274b8db1c9fSJohn Baldwin #if __BSD_VISIBLE 275bb430bc7SJohn Baldwin ssize_t aio_waitcomplete(struct aiocb **, struct timespec *); 27634d3ac59SDavid Schultz #endif 277bfbbc4aaSJason Evans 27853fcc63cSDavid Xu int aio_fsync(int op, struct aiocb *aiocbp); 279f0231545SDmitrij Tejblum __END_DECLS 28071af8fbaSJohn Dyson 281f3215338SJohn Baldwin #endif /* !_KERNEL */ 2825aaef07cSJohn Dyson 283f3215338SJohn Baldwin #endif /* !_SYS_AIO_H_ */ 284