|
|
Use of AIO requires disk driver support; all SCO hard disk drivers support AIO. The DKIOCASTAT ioctl can be used to query whether a given open file descriptor supports AIO.
Support for AIO is not present in the default kernel. In order to use AIO, the administrator must first run mkdev aio.
AIO supports the option of locking an area of physical memory for the use of AIO transfers; this can be configured by the UNIX system administrator by using the /usr/lib/aiomemlock file and the aiolkinit(ADM) command. AIO can be performed whether or not such a lock is available.
typedef struct asyncmlock { char *avaddr; /* starting user virtual addr */ uint asize; /* size of area to be locked */ } ASYNCMLOCK;The area of memory spanned by the ASYNCMLOCK structure must already be allocated to the calling program, for example, by a previous call to malloc(S). If asize is 0, or the user does not have AIO memory lock privileges, DKIOCMLOCK does not lock physical memory, but returns without an error. Possession of memory locking privileges by a user does not affect the success or failure of a locking call, but determines whether or not the call does anything.
If the program is doing AIO to multiple partitions, DKIOCMLOCK must be called on each open file descriptor. The DKIOCMLOCK for all calls by one process must refer to the same area of memory, and DKIOCMLOCK should only be called once for each file descriptor. Memory should not be locked more than once for any file descriptor.
On failure, errno is set to one of the following values:
typedef struct areqbuf { long au_cmd; long au_daddr; char *au_maddr; long au_size; char *au_ref; } AREQBUF;/* * Command bits */
#define AU_READ 01 #define AU_WRITE 02
au_cmd
is set to either AU_READ or
AU_WRITE.
au_daddr
is the (512-byte) disk block number where the
I/O is to start from.
au_maddr
is the user's address for I/O.
au_size
is the length in bytes of the transfer.
au_ref
is a context pointer for the caller's use. It is returned
with the status from the I/O request.
The AIO facility imposes restrictions on the I/O
request parameters. au_size
must be a multiple of 512
(that is, only multiples of 512-byte disk blocks are
permitted). au_maddr
must be aligned on a 512-byte
address boundary. The entire transfer must fit within
an MMU page, that is, within a 4KB aligned page in the
user's space.
Finally, for a given process doing asynchronous I/O,
only one memory range can be locked, and the same range must be specified
for all file descriptors; otherwise an error will result.
On failure, aio sets errno to one of the following values (the disk driver itself may set other values on errors).
au_cmd
is unrecognized, or the user has locked
AIO memory and the transfer is not within this locked
range, or AIO is not supported for this file descriptor,
or AIO has not been linked into the running kernel.
DKIOCASTAT also determines whether a particular open
file descriptor supports AIO. If AIO is not
supported, the ioctl returns -1, and errno is set to
EINVAL.
arg is a pointer to an ASYNCSTATUS structure, which is filled in by the ioctl system call:
#define MAXSTATUS 15typedef struct asyncstatus { long acount; IOSTAT astatus[MAXSTATUS]; } ASYNCSTATUS;
typedef struct aiostat { short iostatus; short iobsize; char *iomaddr; char *ioref; } IOSTAT;
acount
is set to the number of IOSTAT
structures actually returned in this call. iostatus
is
set to 0 for a successful I/O request, and to nonzero (typically
a valid errno code) on an error. iobsize
is
set to the number of bytes transferred. iomaddr
is the
user's transfer address as given in the AREQBUF
structure, and ioref
is the context pointer; these two
values associate the returned status with the initial
request.
On failure, aio sets errno to one of the following values:
NOTICE: AIO: aio_dma_xfer: invalid vtopThe virtual address specified to an AIO data transfer request is invalid.
NOTICE: AIO: aio_memlock: not enough memory for lockNot enough memory is available to lock a chunk of user memory prior to a data transfer.
NOTICE: AIO: no dmaable buffers (DMAABLEBUF)No buffers are available in DMA memory (below 16MB in physical address space).