Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/aio.h
Show All 21 Lines | |||||
#define _SYS_AIO_H_ | #define _SYS_AIO_H_ | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/signal.h> | #include <sys/signal.h> | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/event.h> | #include <sys/event.h> | ||||
#include <sys/signalvar.h> | #include <sys/signalvar.h> | ||||
#include <sys/uio.h> | |||||
#endif | #endif | ||||
/* | /* | ||||
* Returned by aio_cancel: | * Returned by aio_cancel: | ||||
*/ | */ | ||||
#define AIO_CANCELED 0x1 | #define AIO_CANCELED 0x1 | ||||
#define AIO_NOTCANCELED 0x2 | #define AIO_NOTCANCELED 0x2 | ||||
#define AIO_ALLDONE 0x3 | #define AIO_ALLDONE 0x3 | ||||
/* | /* | ||||
* LIO opcodes | * LIO opcodes | ||||
*/ | */ | ||||
#define LIO_NOP 0x0 | #define LIO_NOP 0x0 | ||||
#define LIO_WRITE 0x1 | #define LIO_WRITE 0x1 | ||||
#define LIO_READ 0x2 | #define LIO_READ 0x2 | ||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
#define LIO_SYNC 0x3 | #define LIO_SYNC 0x3 | ||||
#define LIO_MLOCK 0x4 | #define LIO_MLOCK 0x4 | ||||
#define LIO_WRITEV 0x5 | |||||
#define LIO_READV 0x6 | |||||
#endif | #endif | ||||
/* | /* | ||||
* LIO modes | * LIO modes | ||||
*/ | */ | ||||
#define LIO_NOWAIT 0x0 | #define LIO_NOWAIT 0x0 | ||||
#define LIO_WAIT 0x1 | #define LIO_WAIT 0x1 | ||||
Show All 31 Lines | |||||
}; | }; | ||||
/* | /* | ||||
* I/O control block | * I/O control block | ||||
*/ | */ | ||||
typedef struct aiocb { | typedef struct aiocb { | ||||
int aio_fildes; /* File descriptor */ | int aio_fildes; /* File descriptor */ | ||||
off_t aio_offset; /* File offset for I/O */ | off_t aio_offset; /* File offset for I/O */ | ||||
union { | |||||
volatile void *aio_buf; /* I/O buffer in process space */ | volatile void *aio_buf; /* I/O buffer in process space */ | ||||
struct iovec *aio_iov; /* I/O scatter/gather list */ | |||||
asomers: AFAICT, the only reason why the standard mandates `volatile` here is so the user can manipulate… | |||||
}; | |||||
union { | |||||
size_t aio_nbytes; /* Number of bytes for I/O */ | size_t aio_nbytes; /* Number of bytes for I/O */ | ||||
int aio_iovcnt; /* Length of aio_iov */ | |||||
Done Inline ActionsShould I add some kind of padding field for LP64 arches? asomers: Should I add some kind of padding field for LP64 arches? | |||||
}; | |||||
int __spare__[2]; | int __spare__[2]; | ||||
void *__spare2__; | void *__spare2__; | ||||
int aio_lio_opcode; /* LIO opcode */ | int aio_lio_opcode; /* LIO opcode */ | ||||
int aio_reqprio; /* Request priority -- ignored */ | int aio_reqprio; /* Request priority -- ignored */ | ||||
struct __aiocb_private _aiocb_private; | struct __aiocb_private _aiocb_private; | ||||
struct sigevent aio_sigevent; /* Signal to deliver */ | struct sigevent aio_sigevent; /* Signal to deliver */ | ||||
} aiocb_t; | } aiocb_t; | ||||
Show All 22 Lines | struct kaiocb { | ||||
int msgrcv; /* (*) messages received */ | int msgrcv; /* (*) messages received */ | ||||
struct proc *userproc; /* (*) user process */ | struct proc *userproc; /* (*) user process */ | ||||
struct ucred *cred; /* (*) active credential when created */ | struct ucred *cred; /* (*) active credential when created */ | ||||
struct file *fd_file; /* (*) pointer to file structure */ | struct file *fd_file; /* (*) pointer to file structure */ | ||||
struct aioliojob *lio; /* (*) optional lio job */ | struct aioliojob *lio; /* (*) optional lio job */ | ||||
struct aiocb *ujob; /* (*) pointer in userspace of aiocb */ | struct aiocb *ujob; /* (*) pointer in userspace of aiocb */ | ||||
struct knlist klist; /* (a) list of knotes */ | struct knlist klist; /* (a) list of knotes */ | ||||
struct aiocb uaiocb; /* (*) copy of user I/O control block */ | struct aiocb uaiocb; /* (*) copy of user I/O control block */ | ||||
struct uio uio; /* (*) storage for non-vectored uio */ | |||||
struct iovec iov[1]; /* (*) Storage for non-vectored uios */ | |||||
struct uio *uiop; /* (*) Possibly malloced uio */ | |||||
ksiginfo_t ksi; /* (a) realtime signal info */ | ksiginfo_t ksi; /* (a) realtime signal info */ | ||||
uint64_t seqno; /* (*) job number */ | uint64_t seqno; /* (*) job number */ | ||||
aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */ | aio_cancel_fn_t *cancel_fn; /* (a) backend cancel function */ | ||||
aio_handle_fn_t *handle_fn; /* (c) backend handle function */ | aio_handle_fn_t *handle_fn; /* (c) backend handle function */ | ||||
union { /* Backend-specific data fields */ | union { /* Backend-specific data fields */ | ||||
struct { /* BIO backend */ | struct { /* BIO backend */ | ||||
struct bio *bp; /* (*) BIO pointer */ | int nbio; /* Number of remaining bios */ | ||||
Done Inline ActionsIt turns out that the bp, pbuf, and pages fields were redundant. pbuf and pages were already stored in the bio, and bp is available during aio_biowakeup. So I could just delete those fields. asomers: It turns out that the `bp`, `pbuf`, and `pages` fields were redundant. `pbuf` and `pages` were… | |||||
Not Done Inline ActionsI think this change should be extracted and reviewed/committed alone in advance. kib: I think this change should be extracted and reviewed/committed alone in advance. | |||||
Done Inline ActionsOk, I'll open another review for that. asomers: Ok, I'll open another review for that. | |||||
struct buf *pbuf; /* (*) buffer pointer */ | int error; /* Worst error of all bios */ | ||||
int npages; /* (*) number of pages */ | long nbytes; /* Bytes completed so far */ | ||||
struct vm_page **pages; /* (*) */ | |||||
}; | }; | ||||
struct { /* fsync() requests */ | struct { /* fsync() requests */ | ||||
int pending; /* (a) number of pending I/O */ | int pending; /* (a) number of pending I/O */ | ||||
}; | }; | ||||
struct { | struct { | ||||
void *backend1; | void *backend1; | ||||
void *backend2; | void *backend2; | ||||
long backend3; | long backend3; | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
struct timespec; | struct timespec; | ||||
__BEGIN_DECLS | __BEGIN_DECLS | ||||
/* | /* | ||||
* Asynchronously read from a file | * Asynchronously read from a file | ||||
*/ | */ | ||||
int aio_read(struct aiocb *); | int aio_read(struct aiocb *); | ||||
#if __BSD_VISIBLE | |||||
Done Inline ActionsShould be under BSD_VISIBLE guard, the functions are not POSIX. kib: Should be under BSD_VISIBLE guard, the functions are not POSIX. | |||||
int aio_readv(struct aiocb *); | |||||
#endif | |||||
/* | /* | ||||
* Asynchronously write to file | * Asynchronously write to file | ||||
*/ | */ | ||||
int aio_write(struct aiocb *); | int aio_write(struct aiocb *); | ||||
#if __BSD_VISIBLE | |||||
int aio_writev(struct aiocb *); | |||||
#endif | |||||
/* | /* | ||||
* List I/O Asynchronously/synchronously read/write to/from file | * List I/O Asynchronously/synchronously read/write to/from file | ||||
* "lio_mode" specifies whether or not the I/O is synchronous. | * "lio_mode" specifies whether or not the I/O is synchronous. | ||||
* "acb_list" is an array of "nacb_listent" I/O control blocks. | * "acb_list" is an array of "nacb_listent" I/O control blocks. | ||||
* when all I/Os are complete, the optional signal "sig" is sent. | * when all I/Os are complete, the optional signal "sig" is sent. | ||||
*/ | */ | ||||
int lio_listio(int, struct aiocb *__restrict const *__restrict, int, | int lio_listio(int, struct aiocb *__restrict const *__restrict, int, | ||||
▲ Show 20 Lines • Show All 42 Lines • Show Last 20 Lines |
AFAICT, the only reason why the standard mandates volatile here is so the user can manipulate the aiocb's data while it's being processed by the kernel or vice versa. But that's dumb. I don't think it's necessary, so I didn't include it on aio_iov.