fileaio-linux.cpp revision be1d2a01ea76c7617fb635c9036f9295628de297
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * IPRT - File async I/O, native implementation for the Linux host platform.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * available from http://www.virtualbox.org. This file is free software;
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * you can redistribute it and/or modify it under the terms of the GNU
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * General Public License (GPL) as published by the Free Software
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * The contents of this file may alternatively be used under the terms
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * of the Common Development and Distribution License Version 1.0
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * VirtualBox OSE distribution, in which case the provisions of the
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * CDDL are applicable instead of those of the GPL.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * You may elect to license modified versions of this file under the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * terms and conditions of either the GPL or the CDDL or both.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * additional information or have any questions.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync/** @page pg_rtfileaio_linux RTFile Async I/O - Linux Implementation Notes
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * @internal
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * Linux implements the kernel async I/O API through the io_* syscalls. They are
0aaf889969ebdaba8a310db13adcec8c10174796vboxsync * not exposed in the glibc (the aio_* API uses userspace threads and blocking
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * I/O operations to simulate async behavior). There is an external library
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * called libaio which implements these syscalls but because we don't want to
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * have another dependency and this library is not installed by default and the
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * interface is really simple we use the kernel interface directly using wrapper
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * functions.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * The interface has some limitations. The first one is that the file must be
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * opened with O_DIRECT. This disables caching done by the kernel which can be
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * compensated if the user of this API implements caching itself. The next
5e5603ae40c7a0a884fe91e269b7d6d6c0ba56f5vboxsync * limitation is that data buffers must be aligned at a 512 byte boundary or the
5e5603ae40c7a0a884fe91e269b7d6d6c0ba56f5vboxsync * request will fail.
5e5603ae40c7a0a884fe91e269b7d6d6c0ba56f5vboxsync/** @todo r=bird: What's this about "must be opened with O_DIRECT"? An
5e5603ae40c7a0a884fe91e269b7d6d6c0ba56f5vboxsync * explanation would be nice, esp. seeing what Linus is quoted saying
5e5603ae40c7a0a884fe91e269b7d6d6c0ba56f5vboxsync * about it in the open man page... */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync/*******************************************************************************
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync* Header Files *
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync*******************************************************************************/
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync/*******************************************************************************
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync* Structures and Typedefs *
d23a94a28e59f64d02905f20bb8f3b23f1c9eb17vboxsync*******************************************************************************/
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync/** The async I/O context handle */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsynctypedef unsigned long LNXKAIOCONTEXT;
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * Supported commands for the iocbs
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * The iocb structure of a request which is passed to the kernel.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * We redefined this here because the version in the header lacks padding
0aaf889969ebdaba8a310db13adcec8c10174796vboxsync * for 32bit.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsynctypedef struct LNXKAIOIOCB
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Opaque pointer to data which is returned on an I/O event. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Contains the request number and is set by the kernel. */
0aaf889969ebdaba8a310db13adcec8c10174796vboxsync /** Reserved. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** The I/O opcode. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Request priority. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** The file descriptor. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** The userspace pointer to the buffer containing/receiving the data. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** How many bytes to transfer. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** At which offset to start the transfer. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Reserved. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Flags */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Readyness signal file descriptor. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * I/O event structure to notify about completed requests.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * Redefined here too because of the padding.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** The pvUser field from the iocb. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** The LNXKAIOIOCB object this event is for. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** The result code of the operation .*/
d23a94a28e59f64d02905f20bb8f3b23f1c9eb17vboxsync /** Secondary result code. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync * Async I/O completion context state.
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Handle to the async I/O context. */
5c1381fc884d30a749517579368ff6cb4b43e809vboxsync /** Maximum number of requests this context can handle. */
volatile bool fWokenUp;
volatile bool fWaiting;
typedef struct RTFILEAIOREQINTERNAL
int Rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
DECLINLINE(int) rtFileAsyncIoLinuxSubmit(LNXKAIOCONTEXT AioContext, long cReqs, LNXKAIOIOCB **ppIoCB, int *pcSubmitted)
return VINF_SUCCESS;
DECLINLINE(int) rtFileAsyncIoLinuxCancel(LNXKAIOCONTEXT AioContext, PLNXKAIOIOCB pIoCB, PLNXKAIOIOEVENT pIoResult)
return VINF_SUCCESS;
return rc;
return rc;
return rc;
return VINF_SUCCESS;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
void *pvUser)
return VINF_SUCCESS;
return VERR_NOT_IMPLEMENTED;
return VINF_SUCCESS;
return VERR_FILE_AIO_IN_PROGRESS;
return rc;
if ( pcbTransfered
return VERR_OUT_OF_RANGE;
return VERR_NO_MEMORY;
return rc;
return VINF_SUCCESS;
return VERR_FILE_AIO_BUSY;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
while (iUndo-- > i)
return VERR_INVALID_HANDLE;
int cReqsSubmitted = 0;
i = cReqs;
return rc;
} while (cReqs);
return rc;
return VERR_FILE_AIO_NO_REQUEST;
if (!cMinReqs)
int cRequestsCompleted = 0;
rc = rtFileAsyncIoLinuxGetEvents(pCtxInt->AioContext, cMinReqs, cRequestsToWait, &aPortEvents[0], pTimeout);
return rc;
if ( !fWokenUp
&& fWaiting)
return VINF_SUCCESS;