VirtualBox

Changeset 28065 in vbox


Ignore:
Timestamp:
Apr 7, 2010 8:54:34 PM (15 years ago)
Author:
vboxsync
Message:

Storage: Convert from PDMDATASEG to RTSGSEG to avoid casting between those two in VBoxHDD and more async I/O updates

Location:
trunk
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxHDD.h

    r27977 r28065  
    3535#include <iprt/mem.h>
    3636#include <iprt/net.h>
     37#include <iprt/sg.h>
    3738#include <VBox/cdefs.h>
    3839#include <VBox/types.h>
     
    589590     */
    590591    DECLR3CALLBACKMEMBER(int, pfnReadAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
    591                                              PCPDMDATASEG paSegments, size_t cSegments,
     592                                             PCRTSGSEG paSegments, size_t cSegments,
    592593                                             size_t cbRead, void *pvCompletion,
    593594                                             void **ppTask));
     
    607608     */
    608609    DECLR3CALLBACKMEMBER(int, pfnWriteAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
    609                                               PCPDMDATASEG paSegments, size_t cSegments,
     610                                              PCRTSGSEG paSegments, size_t cSegments,
    610611                                              size_t cbWrite, void *pvCompletion,
    611612                                              void **ppTask));
     
    21882189 */
    21892190VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
    2190                               PPDMDATASEG paSeg, unsigned cSeg,
     2191                              PCRTSGSEG paSeg, unsigned cSeg,
    21912192                              PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
    21922193                              void *pvUser1, void *pvUser2);
     
    22062207 */
    22072208VBOXDDU_DECL(int) VDAsyncWrite(PVBOXHDD pDisk, uint64_t uOffset, size_t cbWrite,
    2208                                PPDMDATASEG paSeg, unsigned cSeg,
     2209                               PCRTSGSEG paSeg, unsigned cSeg,
    22092210                               PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
    22102211                               void *pvUser1, void *pvUser2);
  • trunk/include/VBox/pdmasynccompletion.h

    r27920 r28065  
    3535#include <VBox/err.h>
    3636#include <iprt/assert.h>
     37#include <iprt/sg.h>
    3738
    3839RT_C_DECLS_BEGIN
     
    258259 */
    259260VMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    260                                           PCPDMDATASEG paSegments, size_t cSegments,
     261                                          PCRTSGSEG paSegments, unsigned cSegments,
    261262                                          size_t cbRead, void *pvUser,
    262263                                          PPPDMASYNCCOMPLETIONTASK ppTask);
     
    276277 */
    277278VMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    278                                            PCPDMDATASEG paSegments, size_t cSegments,
     279                                           PCRTSGSEG paSegments, unsigned cSegments,
    279280                                           size_t cbWrite, void *pvUser,
    280281                                           PPPDMASYNCCOMPLETIONTASK ppTask);
  • trunk/include/VBox/pdmifs.h

    r28051 r28065  
    3131#define ___VBox_pdmifs_h
    3232
     33#include <iprt/sg.h>
    3334#include <VBox/types.h>
    3435#include <VBox/hgcmsvc.h>
     
    13921393     * @thread  Any thread.
    13931394     */
    1394     DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIBLOCKASYNC pInterface, uint64_t off, PPDMDATASEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser));
     1395    DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser));
    13951396
    13961397    /**
     
    14061407     * @thread  Any thread.
    14071408     */
    1408     DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIBLOCKASYNC pInterface, uint64_t off, PPDMDATASEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser));
     1409    DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser));
    14091410
    14101411} PDMIBLOCKASYNC;
     
    14551456     * @thread  Any thread.
    14561457     */
    1457     DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIMEDIAASYNC pInterface, uint64_t off, PPDMDATASEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser));
     1458    DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIMEDIAASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser));
    14581459
    14591460    /**
     
    14691470     * @thread  Any thread.
    14701471     */
    1471     DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIMEDIAASYNC pInterface, uint64_t off, PPDMDATASEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser));
     1472    DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIMEDIAASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser));
    14721473
    14731474} PDMIMEDIAASYNC;
     
    25342535    uint32_t               cScatterGatherEntries;
    25352536    /** Pointer to the head of the scatter gather list. */
    2536     PPDMDATASEG            paScatterGatherHead;
     2537    PRTSGSEG               paScatterGatherHead;
    25372538    /** Size of the sense buffer. */
    25382539    uint32_t               cbSenseBuffer;
  • trunk/include/VBox/vscsi.h

    r27901 r28065  
    3434#include <VBox/cdefs.h>
    3535#include <VBox/types.h>
     36#include <iprt/sg.h>
    3637
    3738RT_C_DECLS_BEGIN
     
    222223                                       uint32_t iLun, uint8_t *pbCDB, size_t cbCDB,
    223224                                       size_t cbSGList, unsigned cSGListEntries,
    224                                        PPDMDATASEG paSGList, uint8_t *pbSense,
     225                                       PCRTSGSEG paSGList, uint8_t *pbSense,
    225226                                       size_t cbSense, void *pvVScsiReqUser);
    226227
     
    280281VBOXDDU_DECL(int) VSCSIIoReqParamsGet(VSCSIIOREQ hVScsiIoReq, uint64_t *puOffset,
    281282                                      size_t *pcbTransfer, unsigned *pcSeg,
    282                                       size_t *pcbSeg, PCPDMDATASEG *ppaSeg);
     283                                      size_t *pcbSeg, PCRTSGSEG *ppaSeg);
    283284
    284285RT_C_DECLS_END
  • trunk/src/VBox/Devices/Storage/DevAHCI.cpp

    r27734 r28065  
    257257    uint32_t                   cSGListUsed;
    258258    /** Pointer to the first entry of the scatter gather list. */
    259     PPDMDATASEG                pSGListHead;
     259    PRTSGSEG                   pSGListHead;
    260260    /** Number of scatter gather list entries. */
    261261    uint32_t                   cSGEntries;
     
    40424042
    40434043        /* Allocate R3 scatter gather list. */
    4044         pAhciPortTaskState->pSGListHead = (PPDMDATASEG)RTMemAllocZ(cSGList * sizeof(PDMDATASEG));
     4044        pAhciPortTaskState->pSGListHead = (PRTSGSEG)RTMemAllocZ(cSGList * sizeof(RTSGSEG));
    40454045        if (!pAhciPortTaskState->pSGListHead)
    40464046            return VERR_NO_MEMORY;
     
    40914091    /* Make debugging easier. */
    40924092#ifdef DEBUG
    4093     memset(pAhciPortTaskState->pSGListHead, 0, pAhciPortTaskState->cSGListSize * sizeof(PDMDATASEG));
     4093    memset(pAhciPortTaskState->pSGListHead, 0, pAhciPortTaskState->cSGListSize * sizeof(RTSGSEG));
    40944094    memset(pAhciPortTaskState->paSGEntries, 0, pAhciPortTaskState->cSGListSize * sizeof(AHCIPORTTASKSTATESGENTRY));
    40954095    if (pAhciPortTaskState->pvBufferUnaligned)
     
    41634163        return VERR_NO_MEMORY;
    41644164
    4165     pAhciPortTaskState->pSGListHead = (PPDMDATASEG)RTMemAllocZ(1 * sizeof(PDMDATASEG));
     4165    pAhciPortTaskState->pSGListHead = (PRTSGSEG)RTMemAllocZ(1 * sizeof(RTSGSEG));
    41664166    if (!pAhciPortTaskState->pSGListHead)
    41674167    {
     
    42454245    PAHCIPORTTASKSTATESGENTRY  pSGInfoCurr  = NULL;
    42464246    PAHCIPORTTASKSTATESGENTRY  pSGInfoPrev  = NULL;
    4247     PPDMDATASEG                pSGEntryCurr = NULL;
    4248     PPDMDATASEG                pSGEntryPrev = NULL;
     4247    PRTSGSEG                   pSGEntryCurr = NULL;
     4248    PRTSGSEG                   pSGEntryPrev = NULL;
    42494249    RTGCPHYS                   GCPhysBufferPageAlignedPrev = NIL_RTGCPHYS;
    42504250    uint8_t                   *pu8BufferUnalignedPos = NULL;
     
    47934793    unsigned cSGEntry = 0;
    47944794    int cbCopied = 0;
    4795     PPDMDATASEG pSGEntry = &pAhciPortTaskState->pSGListHead[cSGEntry];
     4795    PRTSGSEG pSGEntry = &pAhciPortTaskState->pSGListHead[cSGEntry];
    47964796    uint8_t *pu8Buf = (uint8_t *)pvBuf;
    47974797
     
    53085308                rc = ahciTransferComplete(pAhciPort, pAhciPortTaskState);
    53095309
    5310             if (RT_FAILURE(rc))
     5310            if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
    53115311                AssertMsgFailed(("%s: Failed to enqueue command %Rrc\n", __FUNCTION__, rc));
    53125312        }
     
    54935493                    uint64_t uOffset;
    54945494                    size_t cbTransfer;
    5495                     PPDMDATASEG pSegCurr;
     5495                    PRTSGSEG pSegCurr;
    54965496                    PAHCIPORTTASKSTATESGENTRY pSGInfoCurr;
    54975497
  • trunk/src/VBox/Devices/Storage/DevBusLogic.cpp

    r27660 r28065  
    738738    PDMSCSIREQUEST      PDMScsiRequest;
    739739    /** Data buffer segment */
    740     PDMDATASEG          DataSeg;
     740    RTSGSEG             DataSeg;
    741741    /** Pointer to the R3 sense buffer. */
    742742    uint8_t            *pbSenseBuffer;
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp

    r27699 r28065  
    331331    uint32_t                   cSGListTooBig;
    332332    /** Pointer to the first entry of the scatter gather list. */
    333     PPDMDATASEG                pSGListHead;
     333    PRTSGSEG                   pSGListHead;
    334334    /** How many entries would fit into the sg info list. */
    335335    uint32_t                   cSGInfoSize;
     
    12921292{
    12931293    unsigned cSGEntry = 0;
    1294     PPDMDATASEG pSGEntry = &pTaskState->pSGListHead[cSGEntry];
     1294    PRTSGSEG pSGEntry = &pTaskState->pSGListHead[cSGEntry];
    12951295    uint8_t *pu8Buf = (uint8_t *)pvBuf;
    12961296
     
    13621362
    13631363        /* Allocate R3 scatter gather list. */
    1364         pTaskState->pSGListHead = (PPDMDATASEG)RTMemAllocZ(cSGList * sizeof(PDMDATASEG));
     1364        pTaskState->pSGListHead = (PRTSGSEG)RTMemAllocZ(cSGList * sizeof(RTSGSEG));
    13651365        if (!pTaskState->pSGListHead)
    13661366            return VERR_NO_MEMORY;
     
    14451445    /* Make debugging easier. */
    14461446#ifdef DEBUG
    1447     memset(pTaskState->pSGListHead, 0, pTaskState->cSGListSize * sizeof(PDMDATASEG));
     1447    memset(pTaskState->pSGListHead, 0, pTaskState->cSGListSize * sizeof(RTSGSEG));
    14481448    memset(pTaskState->paSGEntries, 0, pTaskState->cSGInfoSize * sizeof(LSILOGICTASKSTATESGENTRY));
    14491449    if (pTaskState->pvBufferUnaligned)
     
    17121712
    17131713    uint32_t    cSGEntries;
    1714     PPDMDATASEG pSGEntryCurr = pTaskState->pSGListHead;
     1714    PRTSGSEG    pSGEntryCurr = pTaskState->pSGListHead;
    17151715    pSGInfoCurr              = pTaskState->paSGEntries;
    17161716
  • trunk/src/VBox/Devices/Storage/DrvBlock.cpp

    r27806 r28065  
    289289
    290290/** @copydoc PDMIBLOCKASYNC::pfnStartRead */
    291 static DECLCALLBACK(int) drvblockAsyncReadStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PPDMDATASEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser)
     291static DECLCALLBACK(int) drvblockAsyncReadStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser)
    292292{
    293293    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
     
    308308
    309309/** @copydoc PDMIBLOCKASYNC::pfnStartWrite */
    310 static DECLCALLBACK(int) drvblockAsyncWriteStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PPDMDATASEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser)
     310static DECLCALLBACK(int) drvblockAsyncWriteStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser)
    311311{
    312312    PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
  • trunk/src/VBox/Devices/Storage/DrvSCSI.cpp

    r27977 r28065  
    126126        case VSCSIIOREQTXDIR_WRITE:
    127127        {
    128             uint64_t uOffset    = 0;
    129             size_t   cbTransfer = 0;
    130             size_t   cbSeg      = 0;
    131             PCPDMDATASEG paSeg  = NULL;
    132             unsigned    cSeg    = 0;
     128            uint64_t  uOffset    = 0;
     129            size_t    cbTransfer = 0;
     130            size_t    cbSeg      = 0;
     131            PCRTSGSEG paSeg      = NULL;
     132            unsigned  cSeg       = 0;
    133133
    134134            rc = VSCSIIoReqParamsGet(hVScsiIoReq, &uOffset, &cbTransfer, &cSeg, &cbSeg,
     
    242242            case VSCSIIOREQTXDIR_WRITE:
    243243            {
    244                 uint64_t uOffset    = 0;
    245                 size_t   cbTransfer = 0;
    246                 size_t   cbSeg      = 0;
    247                 PCPDMDATASEG paSeg  = NULL;
    248                 unsigned    cSeg    = 0;
     244                uint64_t  uOffset    = 0;
     245                size_t    cbTransfer = 0;
     246                size_t    cbSeg      = 0;
     247                PCRTSGSEG paSeg      = NULL;
     248                unsigned  cSeg       = 0;
    249249
    250250                rc = VSCSIIoReqParamsGet(hVScsiIoReq, &uOffset, &cbTransfer,
     
    256256                    pThis->pLed->Asserted.s.fReading = pThis->pLed->Actual.s.fReading = 1;
    257257                    rc = pThis->pDrvBlockAsync->pfnStartRead(pThis->pDrvBlockAsync, uOffset,
    258                                                              (PPDMDATASEG)paSeg, cSeg, cbTransfer,
     258                                                             paSeg, cSeg, cbTransfer,
    259259                                                             hVScsiIoReq);
    260260                    if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
     
    266266                    pThis->pLed->Asserted.s.fWriting = pThis->pLed->Actual.s.fWriting = 1;
    267267                    rc = pThis->pDrvBlockAsync->pfnStartWrite(pThis->pDrvBlockAsync, uOffset,
    268                                                               (PPDMDATASEG)paSeg, cSeg, cbTransfer,
     268                                                              paSeg, cSeg, cbTransfer,
    269269                                                              hVScsiIoReq);
    270270                    if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
  • trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp

    r26173 r28065  
    111111{
    112112    unsigned cSGEntry = 0;
    113     PPDMDATASEG pSGEntry = &pRequest->paScatterGatherHead[cSGEntry];
     113    PRTSGSEG pSGEntry = &pRequest->paScatterGatherHead[cSGEntry];
    114114    uint8_t *pu8Buf = (uint8_t *)pvBuf;
    115115
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r27977 r28065  
    3636#include <iprt/tcp.h>
    3737#include <iprt/semaphore.h>
     38#include <iprt/sg.h>
    3839
    3940#ifdef VBOX_WITH_INIP
     
    388389    PVBOXDISK pThis = (PVBOXDISK)pvUser;
    389390    PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pStorage;
    390     PDMDATASEG DataSeg;
     391    RTSGSEG DataSeg;
    391392    PPDMASYNCCOMPLETIONTASK pTask;
    392393
     
    420421    PVBOXDISK pThis = (PVBOXDISK)pvUser;
    421422    PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)pStorage;
    422     PDMDATASEG DataSeg;
     423    RTSGSEG DataSeg;
    423424    PPDMASYNCCOMPLETIONTASK pTask;
    424425
     
    473474
    474475static DECLCALLBACK(int) drvvdAsyncIOReadAsync(void *pvUser, void *pStorage, uint64_t uOffset,
    475                                                PCPDMDATASEG paSegments, size_t cSegments,
     476                                               PCRTSGSEG paSegments, size_t cSegments,
    476477                                               size_t cbRead, void *pvCompletion,
    477478                                               void **ppTask)
     
    489490
    490491static DECLCALLBACK(int) drvvdAsyncIOWriteAsync(void *pvUser, void *pStorage, uint64_t uOffset,
    491                                                 PCPDMDATASEG paSegments, size_t cSegments,
     492                                                PCRTSGSEG paSegments, size_t cSegments,
    492493                                                size_t cbWrite, void *pvCompletion,
    493494                                                void **ppTask)
     
    10001001
    10011002static DECLCALLBACK(int) drvvdStartRead(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,
    1002                                         PPDMDATASEG paSeg, unsigned cSeg,
     1003                                        PCRTSGSEG paSeg, unsigned cSeg,
    10031004                                        size_t cbRead, void *pvUser)
    10041005{
     
    10131014
    10141015static DECLCALLBACK(int) drvvdStartWrite(PPDMIMEDIAASYNC pInterface, uint64_t uOffset,
    1015                                          PPDMDATASEG paSeg, unsigned cSeg,
     1016                                         PCRTSGSEG paSeg, unsigned cSeg,
    10161017                                         size_t cbWrite, void *pvUser)
    10171018{
  • trunk/src/VBox/Devices/Storage/UsbMsd.cpp

    r27901 r28065  
    143143    PDMSCSIREQUEST      ScsiReq;
    144144    /** The scatter-gather segment used by ScsiReq for describing pbBuf. */
    145     PDMDATASEG          ScsiReqSeg;
     145    RTSGSEG             ScsiReqSeg;
    146146    /** The sense buffer for the current SCSI request. */
    147147    uint8_t             ScsiReqSense[64];
  • trunk/src/VBox/Devices/Storage/VBoxHDD.cpp

    r27977 r28065  
    4040#include <iprt/param.h>
    4141#include <iprt/memcache.h>
     42#include <iprt/sg.h>
    4243
    4344#include <VBox/VBoxHDD-Plugin.h>
     
    191192typedef struct VDIOCTX
    192193{
    193     /** Completion callback */
    194     PFNVDASYNCTRANSFERCOMPLETE   pfnComplete;
    195     /** User argument 1 passed on completion. */
    196     void                        *pvUser1;
    197     /** User argument 1 passed on completion. */
    198     void                        *pvUser2;
    199194    /** Disk this is request is for. */
    200195    PVBOXHDD                     pDisk;
     
    207202    /** Current offset */
    208203    volatile uint64_t            uOffset;
    209     /** Pointer to the scatter/gather list. */
    210     PCPDMDATASEG                 paDataSeg;
    211     /** Number of segments. */
    212     size_t                       cSeg;
    213     /** Current segment we are in. */
    214     unsigned                     iSegIdx;
    215     /** Pointer to the current buffer. */
    216     uint8_t                     *pbBuf;
    217     /** Number of bytes left in the current buffer. */
    218     size_t                       cbBufLeft;
     204    /** S/G buffer */
     205    RTSGBUF                      SgBuf;
    219206    /** How many meta data transfers are pending. */
    220207    volatile uint32_t            cMetaTransfersPending;
     208    /** Flag whether the request finished */
     209    volatile bool                fComplete;
     210    /** Parent I/O context if any. Sets the type of the context (root/child) */
     211    PVDIOCTX                     pIoCtxParent;
     212    /** Type dependent data (root/child) */
     213    union
     214    {
     215        /** Root data */
     216        struct
     217        {
     218            /** Completion callback */
     219            PFNVDASYNCTRANSFERCOMPLETE   pfnComplete;
     220            /** User argument 1 passed on completion. */
     221            void                        *pvUser1;
     222            /** User argument 1 passed on completion. */
     223            void                        *pvUser2;
     224        } Root;
     225        /** Child data */
     226        struct
     227        {
     228            /** Saved start offset */
     229            uint64_t                     uOffsetSaved;
     230            /** Saved transfer size */
     231            size_t                       cbTransferLeftSaved;
     232            /** Number of bytes transfered from the parent if this context completes. */
     233            size_t                       cbTransferParent;
     234        } Child;
     235    } Type;
    221236} VDIOCTX;
    222237
     
    510525}
    511526
    512 static PVDIOCTX vdIoCtxAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
    513                              uint64_t uOffset, size_t cbTransfer,
    514                              PPDMDATASEG paSeg, unsigned cSeg,
    515                              PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
    516                              void *pvUser1, void *pvUser2)
     527DECLINLINE(PVDIOCTX) vdIoCtxAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
     528                                  uint64_t uOffset, size_t cbTransfer,
     529                                  PCRTSGSEG pcaSeg, unsigned cSeg)
    517530{
    518531    PVDIOCTX pIoCtx = NULL;
    519532
    520533    pIoCtx = (PVDIOCTX)RTMemCacheAlloc(pDisk->hMemCacheIoCtx);
    521     if (pIoCtx)
    522     {
    523         pIoCtx->pfnComplete    = pfnComplete;
    524         pIoCtx->pvUser1        = pvUser1;
    525         pIoCtx->pvUser2        = pvUser2;
    526         pIoCtx->pDisk          = pDisk;
    527         pIoCtx->enmTxDir       = enmTxDir;
    528         pIoCtx->cbTransferLeft = cbTransfer;
    529         pIoCtx->uOffset        = uOffset;
    530         pIoCtx->paDataSeg      = paSeg;
    531         pIoCtx->cSeg           = cSeg;
    532         pIoCtx->iSegIdx        = 0;
    533         pIoCtx->pbBuf          = (uint8_t *)pIoCtx->paDataSeg[0].pvSeg;
    534         pIoCtx->cbBufLeft      = pIoCtx->paDataSeg[0].cbSeg;
     534    if (RT_LIKELY(pIoCtx))
     535    {
     536        pIoCtx->pDisk                 = pDisk;
     537        pIoCtx->enmTxDir              = enmTxDir;
     538        pIoCtx->cbTransferLeft        = cbTransfer;
     539        pIoCtx->uOffset               = uOffset;
    535540        pIoCtx->cMetaTransfersPending = 0;
     541        pIoCtx->fComplete             = false;
     542
     543        RTSgBufInit(&pIoCtx->SgBuf, pcaSeg, cSeg);
     544    }
     545
     546    return pIoCtx;
     547}
     548
     549static PVDIOCTX vdIoCtxRootAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
     550                                 uint64_t uOffset, size_t cbTransfer,
     551                                 PCRTSGSEG paSeg, unsigned cSeg,
     552                                 PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
     553                                 void *pvUser1, void *pvUser2)
     554{
     555    PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer,
     556                                   paSeg, cSeg);
     557
     558    if (RT_LIKELY(pIoCtx))
     559    {
     560        pIoCtx->pIoCtxParent          = NULL;
     561        pIoCtx->Type.Root.pfnComplete = pfnComplete;
     562        pIoCtx->Type.Root.pvUser1     = pvUser1;
     563        pIoCtx->Type.Root.pvUser2     = pvUser2;
     564    }
     565
     566    return pIoCtx;
     567}
     568
     569static PVDIOCTX vdIoCtxChildAlloc(PVBOXHDD pDisk, VDIOCTXTXDIR enmTxDir,
     570                                  uint64_t uOffset, size_t cbTransfer,
     571                                  PCRTSGSEG paSeg, unsigned cSeg,
     572                                  PVDIOCTX pIoCtxParent, size_t cbTransferParent)
     573{
     574    PVDIOCTX pIoCtx = vdIoCtxAlloc(pDisk, enmTxDir, uOffset, cbTransfer,
     575                                   paSeg, cSeg);
     576
     577    if (RT_LIKELY(pIoCtx))
     578    {
     579        pIoCtx->pIoCtxParent                   = pIoCtxParent;
     580        pIoCtx->Type.Child.uOffsetSaved        = uOffset;
     581        pIoCtx->Type.Child.cbTransferLeftSaved = cbTransfer;
     582        pIoCtx->Type.Child.cbTransferParent    = cbTransferParent;
    536583    }
    537584
     
    583630}
    584631
    585 static uint8_t *vdIoCtxGetBuffer(PVDIOCTX pIoCtx, size_t *pcbData)
    586 {
    587     size_t cbData = RT_MIN(*pcbData, pIoCtx->cbBufLeft);
    588     uint8_t *pbBuf = pIoCtx->pbBuf;
    589 
    590     pIoCtx->cbBufLeft -= cbData;
    591 
    592     /* Advance to the next segment if required. */
    593     if (!pIoCtx->cbBufLeft)
    594     {
    595         pIoCtx->iSegIdx++;
    596 
    597         if (RT_UNLIKELY(pIoCtx->iSegIdx == pIoCtx->cSeg))
    598         {
    599             pIoCtx->cbBufLeft = 0;
    600             pIoCtx->pbBuf     = NULL;
    601         }
    602         else
    603         {
    604             pIoCtx->pbBuf     = (uint8_t *)pIoCtx->paDataSeg[pIoCtx->iSegIdx].pvSeg;
    605             pIoCtx->cbBufLeft = pIoCtx->paDataSeg[pIoCtx->iSegIdx].cbSeg;
    606         }
    607 
    608         *pcbData = cbData;
    609     }
    610     else
    611         pIoCtx->pbBuf += cbData;
    612 
    613     return pbBuf;
    614 }
    615 
     632static void vdIoCtxChildReset(PVDIOCTX pIoCtx)
     633{
     634    AssertPtr(pIoCtx->pIoCtxParent);
     635
     636    RTSgBufReset(&pIoCtx->SgBuf);
     637    pIoCtx->uOffset        = pIoCtx->Type.Child.uOffsetSaved;
     638    pIoCtx->cbTransferLeft = pIoCtx->Type.Child.cbTransferLeftSaved;
     639}
     640
     641static size_t vdIoCtxCopy(PVDIOCTX pIoCtxDst, PVDIOCTX pIoCtxSrc, size_t cbData)
     642{
     643    return RTSgBufCopy(&pIoCtxDst->SgBuf, &pIoCtxSrc->SgBuf, cbData);
     644}
     645
     646static int vdIoCtxCmp(PVDIOCTX pIoCtx1, PVDIOCTX pIoCtx2, size_t cbData)
     647{
     648    return RTSgBufCmp(&pIoCtx1->SgBuf, &pIoCtx2->SgBuf, cbData);
     649}
    616650
    617651static size_t vdIoCtxCopyTo(PVDIOCTX pIoCtx, uint8_t *pbData, size_t cbData)
    618652{
    619     size_t cbLeft = cbData;
    620 
    621     while (cbLeft)
    622     {
    623         size_t cbCopy = cbLeft;
    624         uint8_t *pbBuf = vdIoCtxGetBuffer(pIoCtx, &cbCopy);
    625 
    626         if (!cbCopy)
    627             break;
    628 
    629         memcpy(pbBuf, pbData, cbCopy);
    630 
    631         cbLeft -= cbCopy;
    632         pbData += cbCopy;
    633     }
    634 
    635     return cbData - cbLeft;
     653    return RTSgBufCopyToBuf(&pIoCtx->SgBuf, pbData, cbData);
    636654}
    637655
     
    639657static size_t vdIoCtxCopyFrom(PVDIOCTX pIoCtx, uint8_t *pbData, size_t cbData)
    640658{
    641     size_t cbLeft = cbData;
    642 
    643     while (cbLeft)
    644     {
    645         size_t cbCopy = cbData;
    646         uint8_t *pbBuf = vdIoCtxGetBuffer(pIoCtx, &cbCopy);
    647 
    648         if (!cbCopy)
    649             break;
    650 
    651         memcpy(pbData, pbBuf, cbCopy);
    652 
    653         cbData -= cbCopy;
    654         pbData += cbCopy;
    655     }
    656 
    657     return cbData - cbLeft;
    658 }
    659 
    660 static size_t vdIoCtxSet(PVDIOCTX pIoCtx, int ch, size_t cbData)
    661 {
    662     size_t cbLeft = cbData;
    663 
    664     while (cbLeft)
    665     {
    666         size_t cbCopy = cbData;
    667         uint8_t *pbBuf = vdIoCtxGetBuffer(pIoCtx, &cbCopy);
    668 
    669         if (!cbCopy)
    670             break;
    671 
    672         memset(pbBuf, ch, cbCopy);
    673 
    674         cbData -= cbCopy;
    675     }
    676 
    677     return cbData - cbLeft;
     659    return RTSgBufCopyFromBuf(&pIoCtx->SgBuf, pbData, cbData);
     660}
     661
     662static size_t vdIoCtxSet(PVDIOCTX pIoCtx, uint8_t ch, size_t cbData)
     663{
     664    return RTSgBufSet(&pIoCtx->SgBuf, ch, cbData);
    678665}
    679666
     
    720707            /* No image in the chain contains the data for the block. */
    721708            vdIoCtxSet(pIoCtx, '\0', cbThisRead);
     709            ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbThisRead);
    722710            rc = VINF_SUCCESS;
    723711        }
    724712
    725         if (RT_SUCCESS(rc))
    726         {
    727             /* Success and no async task is pending. */
    728             ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbThisRead);
    729         }
     713        if (RT_FAILURE(rc))
     714            break;
    730715
    731716        cbRead  -= cbThisRead;
    732717        uOffset += cbThisRead;
    733     } while (cbRead != 0 && (   RT_SUCCESS(rc)
    734                              || rc == VERR_VD_ASYNC_IO_IN_PROGRESS));
     718    } while (cbRead != 0 && RT_SUCCESS(rc));
    735719
    736720    if (rc == VERR_VD_NOT_ENOUGH_METADATA)
     
    10161000
    10171001/**
     1002 * internal: write a complete block (only used for diff images), taking the
     1003 * remaining data from parent images. This implementation does not optimize
     1004 * anything (except that it tries to read only that portions from parent
     1005 * images that are really needed) - async version.
     1006 */
     1007static int vdWriteHelperStandardAsync(PVBOXHDD pDisk, PVDIMAGE pImage,
     1008                                      PVDIMAGE pImageParentOverride,
     1009                                      uint64_t uOffset, size_t cbWrite,
     1010                                      size_t cbThisWrite, size_t cbPreRead,
     1011                                      size_t cbPostRead, PVDIOCTX pIoCtxSrc,
     1012                                      PVDIOCTX pIoCtxDst)
     1013{
     1014    int rc = VINF_SUCCESS;
     1015
     1016    /* Read the data that goes before the write to fill the block. */
     1017    if (cbPreRead)
     1018    {
     1019        rc = vdReadHelperAsync(pDisk, pImage, pImageParentOverride, pIoCtxDst,
     1020                               uOffset - cbPreRead, cbPreRead);
     1021        if (RT_FAILURE(rc))
     1022            return rc;
     1023    }
     1024
     1025    /* Copy the data to the right place in the buffer. */
     1026    vdIoCtxCopy(pIoCtxDst, pIoCtxSrc, cbThisWrite);
     1027
     1028    /* Read the data that goes after the write to fill the block. */
     1029    if (cbPostRead)
     1030    {
     1031        /* If we have data to be written, use that instead of reading
     1032         * data from the image. */
     1033        size_t cbWriteCopy;
     1034        if (cbWrite > cbThisWrite)
     1035            cbWriteCopy = RT_MIN(cbWrite - cbThisWrite, cbPostRead);
     1036        else
     1037            cbWriteCopy = 0;
     1038        /* Figure out how much we cannnot read from the image, because
     1039         * the last block to write might exceed the nominal size of the
     1040         * image for technical reasons. */
     1041        size_t cbFill;
     1042        if (uOffset + cbThisWrite + cbPostRead > pDisk->cbSize)
     1043            cbFill = uOffset + cbThisWrite + cbPostRead - pDisk->cbSize;
     1044        else
     1045            cbFill = 0;
     1046        /* The rest must be read from the image. */
     1047        size_t cbReadImage = cbPostRead - cbWriteCopy - cbFill;
     1048
     1049        /* Now assemble the remaining data. */
     1050        if (cbWriteCopy)
     1051        {
     1052            vdIoCtxCopy(pIoCtxDst, pIoCtxSrc, cbWriteCopy);
     1053            ASMAtomicSubU32(&pIoCtxDst->cbTransferLeft, cbWriteCopy);
     1054        }
     1055
     1056        if (cbReadImage)
     1057            rc = vdReadHelperAsync(pDisk, pImage, pImageParentOverride, pIoCtxDst,
     1058                                   uOffset + cbThisWrite + cbWriteCopy,
     1059                                   cbReadImage);
     1060        if (RT_FAILURE(rc))
     1061            return rc;
     1062        /* Zero out the remainder of this block. Will never be visible, as this
     1063         * is beyond the limit of the image. */
     1064        if (cbFill)
     1065        {
     1066            vdIoCtxSet(pIoCtxDst, '\0', cbFill);
     1067            ASMAtomicSubU32(&pIoCtxDst->cbTransferLeft, cbFill);
     1068        }
     1069    }
     1070
     1071    if (   !pIoCtxDst->cbTransferLeft
     1072        && !pIoCtxDst->cMetaTransfersPending
     1073        && ASMAtomicCmpXchgBool(&pIoCtxDst->fComplete, true, false))
     1074    {
     1075        /* Write the full block to the virtual disk. */
     1076        vdIoCtxChildReset(pIoCtxDst);
     1077        rc = pImage->Backend->pfnAsyncWrite(pImage->pvBackendData,
     1078                                            uOffset - cbPreRead,
     1079                                            cbPreRead + cbThisWrite + cbPostRead,
     1080                                            pIoCtxDst,
     1081                                            NULL, &cbPreRead, &cbPostRead, 0);
     1082        Assert(rc != VERR_VD_BLOCK_FREE);
     1083        Assert(cbPreRead == 0);
     1084        Assert(cbPostRead == 0);
     1085    }
     1086    else
     1087    {
     1088        LogFlow(("cbTransferLeft=%u cMetaTransfersPending=%u fComplete=%RTbool\n",
     1089                 pIoCtxDst->cbTransferLeft, pIoCtxDst->cMetaTransfersPending,
     1090                 pIoCtxDst->fComplete));
     1091        rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     1092    }
     1093
     1094    return rc;
     1095}
     1096
     1097/**
     1098 * internal: write a complete block (only used for diff images), taking the
     1099 * remaining data from parent images. This implementation optimizes out writes
     1100 * that do not change the data relative to the state as of the parent images.
     1101 * All backends which support differential/growing images support this - async version.
     1102 */
     1103static int vdWriteHelperOptimizedAsync(PVBOXHDD pDisk, PVDIMAGE pImage,
     1104                                       PVDIMAGE pImageParentOverride,
     1105                                       uint64_t uOffset, size_t cbWrite,
     1106                                       size_t cbThisWrite, size_t cbPreRead,
     1107                                       size_t cbPostRead, PVDIOCTX pIoCtxSrc,
     1108                                       PVDIOCTX pIoCtxDst)
     1109{
     1110    size_t cbFill = 0;
     1111    size_t cbWriteCopy = 0;
     1112    size_t cbReadImage = 0;
     1113    int rc;
     1114
     1115    if (cbPostRead)
     1116    {
     1117        /* Figure out how much we cannnot read from the image, because
     1118         * the last block to write might exceed the nominal size of the
     1119         * image for technical reasons. */
     1120        if (uOffset + cbThisWrite + cbPostRead > pDisk->cbSize)
     1121            cbFill = uOffset + cbThisWrite + cbPostRead - pDisk->cbSize;
     1122
     1123        /* If we have data to be written, use that instead of reading
     1124         * data from the image. */
     1125        if (cbWrite > cbThisWrite)
     1126            cbWriteCopy = RT_MIN(cbWrite - cbThisWrite, cbPostRead);
     1127
     1128        /* The rest must be read from the image. */
     1129        cbReadImage = cbPostRead - cbWriteCopy - cbFill;
     1130    }
     1131
     1132    /* Read the entire data of the block so that we can compare whether it will
     1133     * be modified by the write or not. */
     1134    rc = vdReadHelperAsync(pDisk, pImage, pImageParentOverride, pIoCtxDst,
     1135                           uOffset - cbPreRead,
     1136                           cbPreRead + cbThisWrite + cbPostRead - cbFill);
     1137    if (RT_FAILURE(rc))
     1138        return rc;
     1139
     1140#if 0
     1141    /* Check if the write would modify anything in this block. */
     1142    if (   !memcmp((char *)pvTmp + cbPreRead, pvBuf, cbThisWrite)
     1143        && (!cbWriteCopy || !memcmp((char *)pvTmp + cbPreRead + cbThisWrite,
     1144                                    (char *)pvBuf + cbThisWrite, cbWriteCopy)))
     1145    {
     1146        /* Block is completely unchanged, so no need to write anything. */
     1147        return VINF_SUCCESS;
     1148    }
     1149
     1150    /* Copy the data to the right place in the buffer. */
     1151    memcpy((char *)pvTmp + cbPreRead, pvBuf, cbThisWrite);
     1152
     1153    /* Handle the data that goes after the write to fill the block. */
     1154    if (cbPostRead)
     1155    {
     1156        /* Now assemble the remaining data. */
     1157        if (cbWriteCopy)
     1158            memcpy((char *)pvTmp + cbPreRead + cbThisWrite,
     1159                   (char *)pvBuf + cbThisWrite, cbWriteCopy);
     1160        /* Zero out the remainder of this block. Will never be visible, as this
     1161         * is beyond the limit of the image. */
     1162        if (cbFill)
     1163            memset((char *)pvTmp + cbPreRead + cbThisWrite + cbWriteCopy + cbReadImage,
     1164                   '\0', cbFill);
     1165    }
     1166
     1167    /* Write the full block to the virtual disk. */
     1168    rc = pImage->Backend->pfnWrite(pImage->pvBackendData,
     1169                                   uOffset - cbPreRead, pvTmp,
     1170                                   cbPreRead + cbThisWrite + cbPostRead,
     1171                                   NULL, &cbPreRead, &cbPostRead, 0);
     1172    Assert(rc != VERR_VD_BLOCK_FREE);
     1173    Assert(cbPreRead == 0);
     1174    Assert(cbPostRead == 0);
     1175#endif
     1176    return rc;
     1177}
     1178
     1179/**
    10181180 * internal: write buffer to the image, taking care of block boundaries and
    10191181 * write optimizations - async version.
     
    10431205                                            &cbThisWrite, &cbPreRead,
    10441206                                            &cbPostRead, fWrite);
    1045 #if 0
    10461207        if (rc == VERR_VD_BLOCK_FREE)
    10471208        {
    1048             void *pvTmp = RTMemTmpAlloc(cbPreRead + cbThisWrite + cbPostRead);
    1049             AssertBreakStmt(VALID_PTR(pvTmp), rc = VERR_NO_MEMORY);
     1209            /*
     1210             * Allocate segment and buffer in one go.
     1211             * A bit hackish but avoids the need to allocate memory twice.
     1212             */
     1213            PRTSGSEG pTmp = (PRTSGSEG)RTMemTmpAlloc(cbPreRead + cbThisWrite + cbPostRead + sizeof(RTSGSEG));
     1214            AssertBreakStmt(VALID_PTR(pTmp), rc = VERR_NO_MEMORY);
     1215
     1216            pTmp->pvSeg = pTmp + 1;
     1217            pTmp->cbSeg = cbPreRead + cbThisWrite + cbPostRead;
     1218
     1219            PVDIOCTX pIoCtxWrite = vdIoCtxChildAlloc(pDisk, VDIOCTXTXDIR_WRITE,
     1220                                                     uOffset, pTmp->cbSeg,
     1221                                                     pTmp, 1,
     1222                                                     pIoCtx, cbThisWrite);
     1223            if (!VALID_PTR(pIoCtxWrite))
     1224            {
     1225                RTMemTmpFree(pTmp);
     1226                rc = VERR_NO_MEMORY;
     1227                break;
     1228            }
    10501229
    10511230            if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_HONOR_SAME))
     
    10531232                /* Optimized write, suppress writing to a so far unallocated
    10541233                 * block if the data is in fact not changed. */
    1055                 rc = vdWriteHelperOptimized(pDisk, pImage, pImageParentOverride,
    1056                                             uOffset, cbWrite,
    1057                                             cbThisWrite, cbPreRead, cbPostRead,
    1058                                             pvBuf, pvTmp);
     1234                rc = vdWriteHelperOptimizedAsync(pDisk, pImage, pImageParentOverride,
     1235                                                 uOffset, cbWrite,
     1236                                                 cbThisWrite, cbPreRead, cbPostRead,
     1237                                                 pIoCtx, pIoCtxWrite);
    10591238            }
    10601239            else
     
    10641243                 * backend has some further optimization enabled) cause the
    10651244                 * block to be allocated. */
    1066                 rc = vdWriteHelperStandard(pDisk, pImage, pImageParentOverride,
    1067                                            uOffset, cbWrite,
    1068                                            cbThisWrite, cbPreRead, cbPostRead,
    1069                                            pvBuf, pvTmp);
     1245                rc = vdWriteHelperStandardAsync(pDisk, pImage, pImageParentOverride,
     1246                                                uOffset, cbWrite,
     1247                                                cbThisWrite, cbPreRead, cbPostRead,
     1248                                                pIoCtx, pIoCtxWrite);
    10701249            }
    1071             RTMemTmpFree(pvTmp);
     1250
    10721251            if (RT_FAILURE(rc))
     1252            {
     1253                RTMemTmpFree(pTmp);
     1254                vdIoCtxFree(pDisk, pIoCtxWrite);
    10731255                break;
    1074         }
    1075 #endif
    1076 
    1077         if (RT_SUCCESS(rc))
    1078         {
    1079             /* Success and no async task is pending. */
    1080             Assert(rc == VINF_SUCCESS);
    1081             ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbThisWrite);
    1082         }
     1256            }
     1257
     1258            if (   !(pIoCtxWrite->cbTransferLeft || pIoCtxWrite->cMetaTransfersPending)
     1259                && ASMAtomicCmpXchgBool(&pIoCtxWrite->fComplete, true, false))
     1260            {
     1261                RTMemTmpFree(pTmp);
     1262                ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbThisWrite);
     1263                vdIoCtxFree(pDisk, pIoCtxWrite);
     1264            }
     1265        }
     1266
     1267        if (RT_FAILURE(rc))
     1268            break;
    10831269
    10841270        cbWrite -= cbThisWrite;
    10851271        uOffset += cbThisWrite;
    1086     } while (cbWrite != 0 && (   RT_SUCCESS(rc)
    1087                               || rc == VERR_VD_ASYNC_IO_IN_PROGRESS));
     1272    } while (cbWrite != 0 && RT_SUCCESS(rc));
    10881273
    10891274    return rc;
     
    13131498 */
    13141499static int vdAsyncIOReadAsync(void *pvUser, void *pStorage, uint64_t uOffset,
    1315                               PCPDMDATASEG paSegments, size_t cSegments,
     1500                              PCRTSGSEG paSegments, size_t cSegments,
    13161501                              size_t cbRead, void *pvCompletion,
    13171502                              void **ppTask)
     
    13241509 */
    13251510static int vdAsyncIOWriteAsync(void *pvUser, void *pStorage, uint64_t uOffset,
    1326                                PCPDMDATASEG paSegments, size_t cSegments,
     1511                               PCRTSGSEG paSegments, size_t cSegments,
    13271512                               size_t cbWrite, void *pvCompletion,
    13281513                               void **ppTask)
     
    13451530    PVDIOCTX  pIoCtx  = pIoTask->pIoCtx;
    13461531    PVBOXHDD  pDisk   = pIoCtx->pDisk;
    1347     uint32_t  cbLeft  = ASMAtomicSubU32(&pIoCtx->cbTransferLeft, pIoTask->Type.User.cbTransfer);
    1348 
    1349     Assert(!pIoTask->fMeta); /* No meta tasks spawned at the moment. */
    1350 
    1351     if (cbLeft == pIoTask->Type.User.cbTransfer)
    1352     {
    1353         vdIoTaskFree(pDisk, pIoTask);
    1354         pIoCtx->pfnComplete(pIoCtx->pvUser1, pIoCtx->pvUser2);
     1532
     1533    LogFlowFunc(("Task completed pIoTask=%#p pIoCtx=%#p pDisk=%#p\n",
     1534                 pIoTask, pIoCtx, pDisk));
     1535
     1536    if (!pIoTask->fMeta)
     1537        ASMAtomicSubU32(&pIoCtx->cbTransferLeft, pIoTask->Type.User.cbTransfer);
     1538    else
     1539    {
     1540        Assert(pIoTask->Type.Meta.enmTxDir == VDIOCTXTXDIR_WRITE);
     1541        if (pIoTask->Type.Meta.pfnMetaComplete)
     1542            pIoTask->Type.Meta.pfnMetaComplete(NULL, pIoTask->Type.Meta.pvMetaUser);
     1543        ASMAtomicDecU32(&pIoCtx->cMetaTransfersPending);
     1544    }
     1545
     1546    vdIoTaskFree(pDisk, pIoTask);
     1547
     1548    if (   !pIoCtx->cbTransferLeft
     1549        && !pIoCtx->cMetaTransfersPending
     1550        && ASMAtomicCmpXchgBool(&pIoCtx->fComplete, true, false))
     1551    {
     1552        LogFlowFunc(("I/O context completed\n"));
     1553        Assert(!pIoCtx->pIoCtxParent);
     1554        pIoCtx->Type.Root.pfnComplete(pIoCtx->Type.Root.pvUser1, pIoCtx->Type.Root.pvUser2);
    13551555        vdIoCtxFree(pDisk, pIoCtx);
    13561556    }
    1357     else
    1358         vdIoTaskFree(pDisk, pIoTask);
    13591557
    13601558    return VINF_SUCCESS;
     
    14591657    while (cbRead)
    14601658    {
    1461         PDMDATASEG  aSeg[VD_IO_TASK_SEGMENTS_MAX];
    1462         unsigned    cSegments  = 0;
    1463         unsigned    cbTaskRead = 0;
    1464 
    1465         while (   cbRead
    1466                && cSegments < VD_IO_TASK_SEGMENTS_MAX)
    1467         {
    1468 
    1469             size_t      cbThisSeg = cbRead;
    1470             uint8_t    *pbBuf     = NULL;
    1471 
    1472             pbBuf = vdIoCtxGetBuffer(pIoCtx, &cbThisSeg);
    1473 
    1474             aSeg[cSegments].cbSeg = cbThisSeg;
    1475             aSeg[cSegments].pvSeg = pbBuf;
    1476             cSegments++;
    1477             cbRead     -= cbThisSeg;
    1478             cbTaskRead += cbThisSeg;
    1479         }
     1659        RTSGSEG  aSeg[VD_IO_TASK_SEGMENTS_MAX];
     1660        unsigned cSegments  = VD_IO_TASK_SEGMENTS_MAX;
     1661        size_t   cbTaskRead = 0;
     1662
     1663        cbTaskRead = RTSgBufSegArrayCreate(&pIoCtx->SgBuf, aSeg, &cSegments, cbRead);
    14801664
    14811665        PVDIOTASK pIoTask = vdIoTaskUserAlloc(pDisk, pIoCtx, cbTaskRead);
     
    14911675                                                                  &pvTask);
    14921676        if (rc2 == VINF_SUCCESS)
     1677        {
     1678            AssertMsg(cbTaskRead <= pIoCtx->cbTransferLeft, ("Impossible!\n"));
     1679            ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbTaskRead);
    14931680            vdIoTaskFree(pDisk, pIoTask);
     1681        }
    14941682        else if (rc2 == VERR_VD_ASYNC_IO_IN_PROGRESS)
    1495             rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     1683            rc = VINF_SUCCESS;
    14961684        else if (RT_FAILURE(rc2))
     1685        {
    14971686            rc = rc2;
     1687            break;
     1688        }
    14981689
    14991690        uOffset += cbTaskRead;
     
    15131704    while (cbWrite)
    15141705    {
    1515         PDMDATASEG  aSeg[VD_IO_TASK_SEGMENTS_MAX];
    1516         unsigned    cSegments   = 0;
    1517         unsigned    cbTaskWrite = 0;
    1518 
    1519         while (   cbWrite
    1520                && cSegments < VD_IO_TASK_SEGMENTS_MAX)
    1521         {
    1522 
    1523             size_t      cbThisSeg = cbWrite;
    1524             uint8_t    *pbBuf     = NULL;
    1525 
    1526             pbBuf = vdIoCtxGetBuffer(pIoCtx, &cbThisSeg);
    1527 
    1528             aSeg[cSegments].cbSeg = cbThisSeg;
    1529             aSeg[cSegments].pvSeg = pbBuf;
    1530             cSegments++;
    1531             cbWrite     -= cbThisSeg;
    1532             cbTaskWrite += cbThisSeg;
    1533         }
     1706        RTSGSEG  aSeg[VD_IO_TASK_SEGMENTS_MAX];
     1707        unsigned cSegments   = VD_IO_TASK_SEGMENTS_MAX;
     1708        size_t   cbTaskWrite = 0;
     1709
     1710        cbTaskWrite = RTSgBufSegArrayCreate(&pIoCtx->SgBuf, aSeg, &cSegments, cbWrite);
    15341711
    15351712        PVDIOTASK pIoTask = vdIoTaskUserAlloc(pDisk, pIoCtx, cbTaskWrite);
     
    15451722                                                                   &pvTask);
    15461723        if (rc2 == VINF_SUCCESS)
     1724        {
     1725            AssertMsg(cbTaskWrite <= pIoCtx->cbTransferLeft, ("Impossible!\n"));
     1726            ASMAtomicSubU32(&pIoCtx->cbTransferLeft, cbTaskWrite);
    15471727            vdIoTaskFree(pDisk, pIoTask);
     1728        }
    15481729        else if (rc2 == VERR_VD_ASYNC_IO_IN_PROGRESS)
    1549             rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     1730            rc = VINF_SUCCESS;
    15501731        else if (RT_FAILURE(rc2))
     1732        {
    15511733            rc = rc2;
     1734            break;
     1735        }
    15521736
    15531737        uOffset += cbTaskWrite;
     
    15601744                             uint64_t uOffset, void *pvBuf,
    15611745                             size_t cbRead, PVDIOCTX pIoCtx,
    1562                              PFNVDMETACOMPLETED pfnMetaCompleted,
     1746                             PFNVDMETACOMPLETED pfnMetaComplete,
    15631747                             void *pvMetaUser)
    15641748{
    1565     return VERR_NOT_IMPLEMENTED;
    1566 }
    1567 
    1568 static int vdIOWriteMetaAsync(void *pvUser, PVDIOSTORAGE pStorage,
     1749    PVBOXHDD pDisk = (PVBOXHDD)pvUser;
     1750    int rc = VINF_SUCCESS;
     1751    RTSGSEG Seg;
     1752    PVDIOTASK pIoTask;
     1753    void *pvTask = NULL;
     1754
     1755    pIoTask = vdIoTaskMetaAlloc(pDisk, pIoCtx, VDIOCTXTXDIR_READ,
     1756                                pfnMetaComplete, pvMetaUser);
     1757    if (!pIoTask)
     1758        return VERR_NO_MEMORY;
     1759
     1760    Seg.cbSeg = cbRead;
     1761    Seg.pvSeg = pvBuf;
     1762
     1763    ASMAtomicIncU32(&pIoCtx->cMetaTransfersPending);
     1764
     1765    int rc2 = pDisk->pInterfaceAsyncIOCallbacks->pfnReadAsync(pDisk->pInterfaceAsyncIO->pvUser,
     1766                                                              pIoStorage->u.pStorage,
     1767                                                              uOffset, &Seg, 1,
     1768                                                              cbRead, pIoTask,
     1769                                                              &pvTask);
     1770    if (rc2 == VINF_SUCCESS)
     1771    {
     1772        ASMAtomicDecU32(&pIoCtx->cMetaTransfersPending);
     1773        vdIoTaskFree(pDisk, pIoTask);
     1774    }
     1775    else if (rc2 == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1776        rc = VERR_VD_NOT_ENOUGH_METADATA;
     1777    else if (RT_FAILURE(rc2))
     1778        rc = rc2;
     1779
     1780    return rc;
     1781}
     1782
     1783static int vdIOWriteMetaAsync(void *pvUser, PVDIOSTORAGE pIoStorage,
    15691784                              uint64_t uOffset, void *pvBuf,
    15701785                              size_t cbWrite, PVDIOCTX pIoCtx,
    1571                               PFNVDMETACOMPLETED pfnMetaCompleted,
     1786                              PFNVDMETACOMPLETED pfnMetaComplete,
    15721787                              void *pvMetaUser)
    15731788{
    1574     return VERR_NOT_IMPLEMENTED;
     1789    PVBOXHDD pDisk = (PVBOXHDD)pvUser;
     1790    int rc = VINF_SUCCESS;
     1791    RTSGSEG Seg;
     1792    PVDIOTASK pIoTask;
     1793    void *pvTask = NULL;
     1794
     1795    pIoTask = vdIoTaskMetaAlloc(pDisk, pIoCtx, VDIOCTXTXDIR_WRITE,
     1796                                pfnMetaComplete, pvMetaUser);
     1797    if (!pIoTask)
     1798        return VERR_NO_MEMORY;
     1799
     1800    Seg.cbSeg = cbWrite;
     1801    Seg.pvSeg = pvBuf;
     1802
     1803    ASMAtomicIncU32(&pIoCtx->cMetaTransfersPending);
     1804
     1805    int rc2 = pDisk->pInterfaceAsyncIOCallbacks->pfnWriteAsync(pDisk->pInterfaceAsyncIO->pvUser,
     1806                                                               pIoStorage->u.pStorage,
     1807                                                               uOffset, &Seg, 1,
     1808                                                               cbWrite, pIoTask,
     1809                                                               &pvTask);
     1810    if (rc2 == VINF_SUCCESS)
     1811    {
     1812        ASMAtomicDecU32(&pIoCtx->cMetaTransfersPending);
     1813        vdIoTaskFree(pDisk, pIoTask);
     1814    }
     1815    else if (rc2 == VERR_VD_ASYNC_IO_IN_PROGRESS)
     1816        rc = VINF_SUCCESS;
     1817    else if (RT_FAILURE(rc2))
     1818        rc = rc2;
     1819
     1820    return rc;
    15751821}
    15761822
     
    52475493
    52485494VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
    5249                               PPDMDATASEG paSeg, unsigned cSeg,
     5495                              PCRTSGSEG paSeg, unsigned cSeg,
    52505496                              PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
    52515497                              void *pvUser1, void *pvUser2)
     
    52845530                           rc = VERR_INVALID_PARAMETER);
    52855531
    5286         pIoCtx = vdIoCtxAlloc(pDisk, VDIOCTXTXDIR_READ, uOffset,
    5287                               cbRead, paSeg, cSeg,
    5288                               pfnComplete, pvUser1, pvUser2);
     5532        pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_READ, uOffset,
     5533                                  cbRead, paSeg, cSeg,
     5534                                  pfnComplete, pvUser1, pvUser2);
    52895535        if (!pIoCtx)
    52905536        {
     
    53055551    }
    53065552
    5307     if (rc == VINF_SUCCESS)
    5308     {
    5309         vdIoCtxFree(pDisk, pIoCtx);
    5310         rc = VINF_VD_ASYNC_IO_FINISHED;
     5553    if (RT_SUCCESS(rc))
     5554    {
     5555        if (   !pIoCtx->cbTransferLeft
     5556            && !pIoCtx->cMetaTransfersPending
     5557            && ASMAtomicCmpXchgBool(&pIoCtx->fComplete, true, false))
     5558        {
     5559            vdIoCtxFree(pDisk, pIoCtx);
     5560            rc = VINF_VD_ASYNC_IO_FINISHED;
     5561        }
     5562        else
     5563        {
     5564            LogFlow(("cbTransferLeft=%u cMetaTransfersPending=%u fComplete=%RTbool\n",
     5565                     pIoCtx->cbTransferLeft, pIoCtx->cMetaTransfersPending,
     5566                     pIoCtx->fComplete));
     5567            rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     5568        }
    53115569    }
    53125570
     
    53175575
    53185576VBOXDDU_DECL(int) VDAsyncWrite(PVBOXHDD pDisk, uint64_t uOffset, size_t cbWrite,
    5319                                PPDMDATASEG paSeg, unsigned cSeg,
     5577                               PCRTSGSEG paSeg, unsigned cSeg,
    53205578                               PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
    53215579                               void *pvUser1, void *pvUser2)
     
    53545612                           rc = VERR_INVALID_PARAMETER);
    53555613
    5356         pIoCtx = vdIoCtxAlloc(pDisk, VDIOCTXTXDIR_READ, uOffset,
    5357                               cbWrite, paSeg, cSeg,
    5358                               pfnComplete, pvUser1, pvUser2);
     5614        pIoCtx = vdIoCtxRootAlloc(pDisk, VDIOCTXTXDIR_READ, uOffset,
     5615                                  cbWrite, paSeg, cSeg,
     5616                                  pfnComplete, pvUser1, pvUser2);
    53595617        if (!pIoCtx)
    53605618        {
     
    53765634    }
    53775635
    5378     if (rc == VINF_SUCCESS)
    5379     {
    5380         vdIoCtxFree(pDisk, pIoCtx);
    5381         rc = VINF_VD_ASYNC_IO_FINISHED;
     5636    if (RT_SUCCESS(rc))
     5637    {
     5638        if (   !pIoCtx->cbTransferLeft
     5639            && !pIoCtx->cMetaTransfersPending
     5640            && ASMAtomicCmpXchgBool(&pIoCtx->fComplete, true, false))
     5641        {
     5642            vdIoCtxFree(pDisk, pIoCtx);
     5643            rc = VINF_VD_ASYNC_IO_FINISHED;
     5644        }
     5645        else
     5646        {
     5647            LogFlow(("cbTransferLeft=%u cMetaTransfersPending=%u fComplete=%RTbool\n",
     5648                     pIoCtx->cbTransferLeft, pIoCtx->cMetaTransfersPending,
     5649                     pIoCtx->fComplete));
     5650            rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     5651        }
    53825652    }
    53835653
  • trunk/src/VBox/Devices/Storage/VBoxSCSI.cpp

    r26495 r28065  
    248248
    249249    /** Allocate scatter gather element. */
    250     pScsiRequest->paScatterGatherHead = (PPDMDATASEG)RTMemAllocZ(sizeof(PDMDATASEG) * 1); /* Only one element. */
     250    pScsiRequest->paScatterGatherHead = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * 1); /* Only one element. */
    251251    if (!pScsiRequest->paScatterGatherHead)
    252252    {
  • trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp

    r27977 r28065  
    6363static int  vdiUpdateBlockInfo(PVDIIMAGEDESC pImage, unsigned uBlock);
    6464static void vdiFreeImage(PVDIIMAGEDESC pImage, bool fDelete);
    65 
     65static int  vdiUpdateHeaderAsync(PVDIIMAGEDESC pImage, PVDIOCTX pIoCtx);
     66static int  vdiUpdateBlockInfoAsync(PVDIIMAGEDESC pImage, unsigned uBlock, PVDIOCTX pIoCtx);
    6667
    6768/**
     
    206207
    207208    return rc;
     209}
     210
     211static int vdiFileWriteMetaAsync(PVDIIMAGEDESC pImage, uint64_t off, void *pcvBuf, size_t cbWrite,
     212                                 PVDIOCTX pIoCtx, PFNVDMETACOMPLETED pfnMetaComplete, void *pvMetaUser)
     213{
     214    return pImage->pInterfaceIOCallbacks->pfnWriteMetaAsync(pImage->pInterfaceIO->pvUser,
     215                                                            pImage->pStorage,
     216                                                            off, pcvBuf, cbWrite, pIoCtx,
     217                                                            pfnMetaComplete, pvMetaUser);
     218}
     219
     220static int vdiFileReadMetaAsync(PVDIIMAGEDESC pImage, uint64_t off, void *pvBuf, size_t cbRead,
     221                                PVDIOCTX pIoCtx, PFNVDMETACOMPLETED pfnMetaComplete, void *pvMetaUser)
     222{
     223    return pImage->pInterfaceIOCallbacks->pfnReadMetaAsync(pImage->pInterfaceIO->pvUser,
     224                                                           pImage->pStorage,
     225                                                           off, pvBuf, cbRead, pIoCtx,
     226                                                           pfnMetaComplete, pvMetaUser);
    208227}
    209228
     
    845864
    846865/**
     866 * Internal: Save header to file - async version.
     867 */
     868static int vdiUpdateHeaderAsync(PVDIIMAGEDESC pImage, PVDIOCTX pIoCtx)
     869{
     870    int rc;
     871    switch (GET_MAJOR_HEADER_VERSION(&pImage->Header))
     872    {
     873        case 0:
     874            rc = vdiFileWriteMetaAsync(pImage, sizeof(VDIPREHEADER),
     875                                       &pImage->Header.u.v0, sizeof(pImage->Header.u.v0),
     876                                       pIoCtx, NULL, NULL);
     877            break;
     878        case 1:
     879            if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus))
     880                rc = vdiFileWriteMetaAsync(pImage, sizeof(VDIPREHEADER),
     881                                           &pImage->Header.u.v1, sizeof(pImage->Header.u.v1),
     882                                           pIoCtx, NULL, NULL);
     883            else
     884                rc = vdiFileWriteMetaAsync(pImage, sizeof(VDIPREHEADER),
     885                                           &pImage->Header.u.v1plus, sizeof(pImage->Header.u.v1plus),
     886                                           pIoCtx, NULL, NULL);
     887            break;
     888        default:
     889            rc = VERR_VD_VDI_UNSUPPORTED_VERSION;
     890            break;
     891    }
     892    AssertMsgRC(rc, ("vdiUpdateHeader failed, filename=\"%s\" rc=%Rrc\n", pImage->pszFilename, rc));
     893    return rc;
     894}
     895
     896/**
    847897 * Internal: Save block pointer to file, save header to file.
    848898 */
     
    859909                              sizeof(VDIIMAGEBLOCKPOINTER),
    860910                              NULL);
     911        AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n",
     912                         uBlock, pImage->pszFilename, rc));
     913    }
     914    return rc;
     915}
     916
     917/**
     918 * Internal: Save block pointer to file, save header to file - async version.
     919 */
     920static int vdiUpdateBlockInfoAsync(PVDIIMAGEDESC pImage, unsigned uBlock,
     921                                   PVDIOCTX pIoCtx)
     922{
     923    /* Update image header. */
     924    int rc = vdiUpdateHeaderAsync(pImage, pIoCtx);
     925    if (RT_SUCCESS(rc))
     926    {
     927        /* write only one block pointer. */
     928        rc = vdiFileWriteMetaAsync(pImage,
     929                                   pImage->offStartBlocks + uBlock * sizeof(VDIIMAGEBLOCKPOINTER),
     930                                   &pImage->paBlocks[uBlock],
     931                                   sizeof(VDIIMAGEBLOCKPOINTER),
     932                                   pIoCtx,
     933                                   NULL, NULL);
    861934        AssertMsgRC(rc, ("vdiUpdateBlockInfo failed to update block=%u, filename=\"%s\", rc=%Rrc\n",
    862935                         uBlock, pImage->pszFilename, rc));
     
    21252198                setImageBlocksAllocated(&pImage->Header, cBlocksAllocated + 1);
    21262199
    2127                 /** @todo Async */
    2128                 rc = vdiUpdateBlockInfo(pImage, uBlock);
     2200                rc = vdiUpdateBlockInfoAsync(pImage, uBlock, pIoCtx);
    21292201                if (RT_FAILURE(rc))
    21302202                    goto out;
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp

    r27665 r28065  
    312312                                       uint32_t iLun, uint8_t *pbCDB, size_t cbCDB,
    313313                                       size_t cbSGList, unsigned cSGListEntries,
    314                                        PPDMDATASEG paSGList, uint8_t *pbSense,
     314                                       PCRTSGSEG paSGList, uint8_t *pbSense,
    315315                                       size_t cbSense, void *pvVScsiReqUser)
    316316{
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h

    r27653 r28065  
    8888{
    8989    /** Pointer to the scatter/gather list. */
    90     PCPDMDATASEG   paDataSeg;
     90    PCRTSGSEG      paDataSeg;
    9191    /** Number of segments. */
    9292    size_t         cSegments;
     
    142142    unsigned            cSeg;
    143143    /** Segment array. */
    144     PCPDMDATASEG        paSeg;
     144    PCRTSGSEG           paSeg;
    145145} VSCSIIOREQINT;
    146146
     
    207207 * @param   cSegments    Number of segments in the S/G list.
    208208 */
    209 void vscsiIoMemCtxInit(PVSCSIIOMEMCTX pIoMemCtx, PCPDMDATASEG paDataSeg, size_t cSegments);
     209void vscsiIoMemCtxInit(PVSCSIIOMEMCTX pIoMemCtx, PCRTSGSEG paDataSeg, size_t cSegments);
    210210
    211211/**
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSIIoReq.cpp

    r27671 r28065  
    142142VBOXDDU_DECL(int) VSCSIIoReqParamsGet(VSCSIIOREQ hVScsiIoReq, uint64_t *puOffset,
    143143                                      size_t *pcbTransfer, unsigned *pcSeg,
    144                                       size_t *pcbSeg, PCPDMDATASEG *ppaSeg)
     144                                      size_t *pcbSeg, PCRTSGSEG *ppaSeg)
    145145{
    146146    PVSCSIIOREQINT pVScsiIoReq = hVScsiIoReq;
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSISgBuf.cpp

    r27976 r28065  
    2727
    2828
    29 void vscsiIoMemCtxInit(PVSCSIIOMEMCTX pIoMemCtx, PCPDMDATASEG paDataSeg, size_t cSegments)
     29void vscsiIoMemCtxInit(PVSCSIIOMEMCTX pIoMemCtx, PCRTSGSEG paDataSeg, size_t cSegments)
    3030{
    3131    if (RT_UNLIKELY(!cSegments))
  • trunk/src/VBox/VMM/PDMAsyncCompletion.cpp

    r27920 r28065  
    11171117
    11181118VMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    1119                                           PCPDMDATASEG paSegments, size_t cSegments,
     1119                                          PCRTSGSEG paSegments, unsigned cSegments,
    11201120                                          size_t cbRead, void *pvUser,
    11211121                                          PPPDMASYNCCOMPLETIONTASK ppTask)
     
    11491149
    11501150VMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    1151                                            PCPDMDATASEG paSegments, size_t cSegments,
     1151                                           PCRTSGSEG paSegments, unsigned cSegments,
    11521152                                           size_t cbWrite, void *pvUser,
    11531153                                           PPPDMASYNCCOMPLETIONTASK ppTask)
  • trunk/src/VBox/VMM/PDMAsyncCompletionFile.cpp

    r27978 r28065  
    284284int pdmacFileEpTaskInitiate(PPDMASYNCCOMPLETIONTASK pTask,
    285285                            PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    286                             PCPDMDATASEG paSegments, size_t cSegments,
     286                            PCRTSGSEG paSegments, size_t cSegments,
    287287                            size_t cbTransfer, PDMACTASKFILETRANSFER enmTransfer)
    288288{
     
    968968static int pdmacFileEpRead(PPDMASYNCCOMPLETIONTASK pTask,
    969969                           PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    970                            PCPDMDATASEG paSegments, size_t cSegments,
     970                           PCRTSGSEG paSegments, size_t cSegments,
    971971                           size_t cbRead)
    972972{
     
    990990static int pdmacFileEpWrite(PPDMASYNCCOMPLETIONTASK pTask,
    991991                            PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    992                             PCPDMDATASEG paSegments, size_t cSegments,
     992                            PCRTSGSEG paSegments, size_t cSegments,
    993993                            size_t cbWrite)
    994994{
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileCache.cpp

    r27921 r28065  
    4343{
    4444    /** Pointer to the scatter/gather list. */
    45     PCPDMDATASEG   paDataSeg;
     45    PCRTSGSEG      paDataSeg;
    4646    /** Number of segments. */
    4747    size_t         cSegments;
     
    118118 * @param   cSegments    Number of segments in the S/G list.
    119119 */
    120 DECLINLINE(void) pdmIoMemCtxInit(PPDMIOMEMCTX pIoMemCtx, PCPDMDATASEG paDataSeg, size_t cSegments)
     120DECLINLINE(void) pdmIoMemCtxInit(PPDMIOMEMCTX pIoMemCtx, PCRTSGSEG paDataSeg, size_t cSegments)
    121121{
    122122    AssertMsg((cSegments > 0) && paDataSeg, ("Trying to initialize a I/O memory context without a S/G list\n"));
     
    17111711 */
    17121712int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
    1713                          RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
     1713                         RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
    17141714                         size_t cbRead)
    17151715{
     
    19451945 */
    19461946int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
    1947                           RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
     1947                          RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
    19481948                          size_t cbWrite)
    19491949{
  • trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h

    r27920 r28065  
    403403    RTLISTNODE                           NodeCacheEndpoint;
    404404#ifdef VBOX_WITH_STATISTICS
     405    /** Alignment */
     406    bool                                 afAlignment[3];
    405407    /** Number of times a write was deferred because the cache entry was still in progress */
    406408    STAMCOUNTER                          StatWriteDeferred;
     
    520522     */
    521523    volatile uint64_t                      cbFile;
    522     /** Flag whether caching is enabled for this file. */
    523     bool                                   fCaching;
    524     /** Flag whether the file was opened readonly. */
    525     bool                                   fReadonly;
    526524    /** List of new tasks. */
    527525    R3PTRTYPE(volatile PPDMACTASKFILE)     pTasksNewHead;
     
    544542    PPDMACTASKFILE                         pFlushReq;
    545543
    546     /** Event sempahore for blocking external events.
    547      * The caller waits on it until the async I/O manager
    548      * finished processing the event. */
    549     RTSEMEVENT                             EventSemBlock;
    550     /** Flag whether a blocking event is pending and needs
    551      * processing by the I/O manager. */
    552     bool                                   fBlockingEventPending;
    553     /** Blocking event type */
    554     PDMACEPFILEBLOCKINGEVENT               enmBlockingEvent;
    555 
    556544#ifdef VBOX_WITH_STATISTICS
    557545    /** Time spend in a read. */
     
    560548    STAMPROFILEADV                         StatWrite;
    561549#endif
     550
     551    /** Event sempahore for blocking external events.
     552     * The caller waits on it until the async I/O manager
     553     * finished processing the event. */
     554    RTSEMEVENT                             EventSemBlock;
     555    /** Flag whether caching is enabled for this file. */
     556    bool                                   fCaching;
     557    /** Flag whether the file was opened readonly. */
     558    bool                                   fReadonly;
     559    /** Flag whether a blocking event is pending and needs
     560     * processing by the I/O manager. */
     561    bool                                   fBlockingEventPending;
     562    /** Blocking event type */
     563    PDMACEPFILEBLOCKINGEVENT               enmBlockingEvent;
    562564
    563565    /** Additional data needed for the event types. */
     
    640642    RTFOFF                               Off;
    641643    /** Data segment. */
    642     PDMDATASEG                           DataSeg;
     644    RTSGSEG                              DataSeg;
    643645    /** Flag whether this segment uses a bounce buffer
    644646     * because the provided buffer doesn't meet host requirements. */
     
    698700
    699701int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
    700                          RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
     702                         RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
    701703                         size_t cbRead);
    702704int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
    703                           RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
     705                          RTFOFF off, PCRTSGSEG paSegments, size_t cSegments,
    704706                          size_t cbWrite);
    705707int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask);
  • trunk/src/VBox/VMM/PDMAsyncCompletionInternal.h

    r27920 r28065  
    2626#include <iprt/critsect.h>
    2727#include <iprt/memcache.h>
     28#include <iprt/sg.h>
    2829#include <VBox/types.h>
    2930#include <VBox/cfgm.h>
     
    114115    DECLR3CALLBACKMEMBER(int, pfnEpRead, (PPDMASYNCCOMPLETIONTASK pTask,
    115116                                          PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    116                                           PCPDMDATASEG paSegments, size_t cSegments,
     117                                          PCRTSGSEG paSegments, size_t cSegments,
    117118                                         size_t cbRead));
    118119
     
    130131    DECLR3CALLBACKMEMBER(int, pfnEpWrite, (PPDMASYNCCOMPLETIONTASK pTask,
    131132                                           PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
    132                                            PCPDMDATASEG paSegments, size_t cSegments,
     133                                           PCRTSGSEG paSegments, size_t cSegments,
    133134                                           size_t cbWrite));
    134135
  • trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletion.cpp

    r27920 r28065  
    180180                            {
    181181                                size_t cbRead = ((size_t)offSrc + BUFFER_SIZE) <= cbSrc ? BUFFER_SIZE : cbSrc - offSrc;
    182                                 PDMDATASEG DataSeg;
     182                                RTSGSEG DataSeg;
    183183
    184184                                DataSeg.pvSeg = g_AsyncCompletionTasksBuffer[i];
     
    200200                            {
    201201                                size_t cbWrite = (offDst + BUFFER_SIZE) <= cbSrc ? BUFFER_SIZE : cbSrc - offDst;
    202                                 PDMDATASEG DataSeg;
     202                                RTSGSEG DataSeg;
    203203
    204204                                DataSeg.pvSeg = g_AsyncCompletionTasksBuffer[i];
  • trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp

    r27920 r28065  
    114114    RTFOFF                      off;
    115115    /** Data segment */
    116     PDMDATASEG                  DataSeg;
     116    RTSGSEG                     DataSeg;
    117117    /** Task handle. */
    118118    PPDMASYNCCOMPLETIONTASK     hTask;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette