VirtualBox

Changeset 33745 in vbox


Ignore:
Timestamp:
Nov 3, 2010 6:31:53 PM (14 years ago)
Author:
vboxsync
Message:

VCI: Updates

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r33567 r33745  
    188188    /** Bandwidth group the disk is assigned to. */
    189189    char               *pszBwGroup;
     190
     191    /** I/O interface for a cache image. */
     192    VDINTERFACE         VDIIOCache;
     193    /** Interface list for the cache image. */
     194    PVDINTERFACE        pVDIfsCache;
    190195} VBOXDISK, *PVBOXDISK;
    191196
     
    19311936    PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
    19321937    int rc = VINF_SUCCESS;
    1933     char *pszName = NULL;   /**< The path of the disk image file. */
    1934     char *pszFormat = NULL; /**< The format backed to use for this image. */
    1935     bool fReadOnly;         /**< True if the media is read-only. */
    1936     bool fMaybeReadOnly;    /**< True if the media may or may not be read-only. */
    1937     bool fHonorZeroWrites;  /**< True if zero blocks should be written. */
     1938    char *pszName = NULL;        /**< The path of the disk image file. */
     1939    char *pszFormat = NULL;      /**< The format backed to use for this image. */
     1940    char *pszCachePath = NULL;   /**< The path to the cache image. */
     1941    char *pszCacheFormat = NULL; /**< The format backend to use for the cache image. */
     1942    bool fReadOnly;              /**< True if the media is read-only. */
     1943    bool fMaybeReadOnly;         /**< True if the media may or may not be read-only. */
     1944    bool fHonorZeroWrites;       /**< True if zero blocks should be written. */
    19381945    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
    19391946
     
    20182025                                          "ReadOnly\0MaybeReadOnly\0TempReadOnly\0Shareable\0HonorZeroWrites\0"
    20192026                                          "HostIPStack\0UseNewIo\0BootAcceleration\0BootAccelerationBuffer\0"
    2020                                           "SetupMerge\0MergeSource\0MergeTarget\0BwGroup\0Type\0");
     2027                                          "SetupMerge\0MergeSource\0MergeTarget\0BwGroup\0Type\0"
     2028                                          "CachePath\0CacheFormat\0");
    20212029        }
    20222030        else
     
    21552163            }
    21562164            MMR3HeapFree(psz); psz = NULL;
     2165
     2166            rc = CFGMR3QueryStringAlloc(pCurNode, "CachePath", &pszCachePath);
     2167            if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
     2168            {
     2169                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2170                                      N_("DrvVD: Configuration error: Querying \"CachePath\" as string failed"));
     2171                break;
     2172            }
     2173            else
     2174                rc = VINF_SUCCESS;
     2175
     2176            if (pszCachePath)
     2177            {
     2178                rc = CFGMR3QueryStringAlloc(pCurNode, "CacheFormat", &pszCacheFormat);
     2179                if (RT_FAILURE(rc))
     2180                {
     2181                    rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2182                                          N_("DrvVD: Configuration error: Querying \"CacheFormat\" as string failed"));
     2183                    break;
     2184                }
     2185            }
    21572186        }
    21582187
     
    24562485        pCurNode = CFGMR3GetParent(pCurNode);
    24572486    }
     2487
     2488    /* Open the cache image if set. */
     2489    if (   RT_SUCCESS(rc)
     2490        && VALID_PTR(pszCachePath))
     2491    {
     2492        /* Insert the custom I/O interface only if we're told to use new IO.
     2493         * Since the I/O interface is per image we could make this more
     2494         * flexible in the future if we want to. */
     2495        if (fUseNewIo)
     2496        {
     2497            rc = VDInterfaceAdd(&pThis->VDIIOCache, "DrvVD_IO", VDINTERFACETYPE_IO,
     2498                                &pThis->VDIIOCallbacks, pThis,
     2499                                &pThis->pVDIfsCache);
     2500            AssertRC(rc);
     2501        }
     2502
     2503        rc = VDCacheOpen(pThis->pDisk, pszCacheFormat, pszCachePath, VD_OPEN_FLAGS_NORMAL, pThis->pVDIfsCache);
     2504        if (RT_FAILURE(rc))
     2505            rc = PDMDRV_SET_ERROR(pDrvIns, rc, N_("DrvVD: Could not open cache image"));
     2506    }
     2507
     2508    if (VALID_PTR(pszCachePath))
     2509        MMR3HeapFree(pszCachePath);
     2510    if (VALID_PTR(pszCacheFormat))
     2511        MMR3HeapFree(pszCacheFormat);
    24582512
    24592513    if (   RT_SUCCESS(rc)
  • trunk/src/VBox/Storage/VCICache.cpp

    r33567 r33745  
    8282
    8383/** VCI signature to identify a valid image. */
    84 #define VCI_HDR_SIGNATURE          UINT32_C(0x56434900) /* VCI\0 */
     84#define VCI_HDR_SIGNATURE          UINT32_C(0x00494356) /* \0ICV */
    8585/** Current version we support. */
    8686#define VCI_HDR_VERSION            UINT32_C(0x00000001)
     
    193193
    194194/** The magic which identifies a block map. */
    195 #define VCI_BLKMAP_MAGIC   UINT32_C(0x56424c4b) /* VBLK */
     195#define VCI_BLKMAP_MAGIC   UINT32_C(0x4b4c4256) /* KLBV */
    196196/** Current version. */
    197197#define VCI_BLKMAP_VERSION UINT32_C(0x00000001)
     
    466466{
    467467    return pCache->pInterfaceIOCallbacks->pfnWriteSync(pCache->pInterfaceIO->pvUser,
    468                                                        pCache->pStorage, uOffset,
    469                                                        pvBuffer, cbBuffer, NULL);
     468                                                       pCache->pStorage, VCI_BLOCK2BYTE(uOffset),
     469                                                       pvBuffer, VCI_BLOCK2BYTE(cbBuffer), NULL);
    470470}
    471471
     
    474474{
    475475    return pCache->pInterfaceIOCallbacks->pfnReadSync(pCache->pInterfaceIO->pvUser,
    476                                                       pCache->pStorage, uOffset,
    477                                                       pvBuffer, cbBuffer, NULL);
     476                                                      pCache->pStorage, VCI_BLOCK2BYTE(uOffset),
     477                                                      pvBuffer, VCI_BLOCK2BYTE(cbBuffer), NULL);
    478478}
    479479
     
    596596        pBlkMap->pRangesTail = pFree;
    597597
    598         Assert(!((cbBlkMap + sizeof(VciBlkMap) % VCI_BLOCK_SIZE)));
     598        Assert(!((cbBlkMap + sizeof(VciBlkMap)) % VCI_BLOCK_SIZE));
    599599        *ppBlkMap = pBlkMap;
    600         *pcBlkMap = (cbBlkMap + sizeof(VciBlkMap)) / VCI_BLOCK_SIZE;
     600        *pcBlkMap = VCI_BYTE2BLOCK(cbBlkMap + sizeof(VciBlkMap));
    601601    }
    602602    else
     
    662662        cBlkMap -= VCI_BYTE2BLOCK(sizeof(VciBlkMap));
    663663
    664         rc = vciFileReadSync(pStorage, VCI_BLOCK2BYTE(offBlkMap), &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
     664        rc = vciFileReadSync(pStorage, offBlkMap, &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
    665665        if (RT_SUCCESS(rc))
    666666        {
     
    677677                && BlkMap.u32Version == VCI_BLKMAP_VERSION
    678678                && BlkMap.cBlocks == BlkMap.cBlocksFree + BlkMap.cBlocksAllocMeta + BlkMap.cBlocksAllocData
    679                 && BlkMap.cBlocks / 8 == cBlkMap)
     679                && VCI_BYTE2BLOCK(BlkMap.cBlocks / 8) == cBlkMap)
    680680            {
    681681                PVCIBLKMAP pBlkMap = (PVCIBLKMAP)RTMemAllocZ(sizeof(VCIBLKMAP));
     
    696696                        uint8_t abBitmapBuffer[16 * _1K];
    697697                        uint32_t cBlocksRead = 0;
    698                         int iBit = 0;
    699                         uint64_t cBlocksLeft = pBlkMap->cBlocks;
     698                        uint64_t cBlocksLeft = VCI_BYTE2BLOCK(pBlkMap->cBlocks / 8);
    700699
    701700                        cBlocksRead = RT_MIN(VCI_BYTE2BLOCK(sizeof(abBitmapBuffer)), cBlocksLeft);
    702                         rc = vciFileReadSync(pStorage, VCI_BLOCK2BYTE(offBlkMap), abBitmapBuffer,
    703                                              VCI_BLOCK2BYTE(cBlocksRead));
     701                        rc = vciFileReadSync(pStorage, offBlkMap, abBitmapBuffer,
     702                                             cBlocksRead);
    704703
    705704                        if (RT_SUCCESS(rc))
     
    717716                               && cBlocksLeft)
    718717                        {
    719 #if 0
    720                             while (cBlocksRead)
     718                            int iBit = 0;
     719                            uint32_t cBits = VCI_BLOCK2BYTE(cBlocksRead) * 8;
     720                            uint32_t iBitPrev = 0xffffffff;
     721
     722                            while (cBits)
    721723                            {
    722724                                if (pRangeCur->fFree)
    723725                                {
    724726                                    /* Check for the first set bit. */
     727                                    iBit = ASMBitNextSet(abBitmapBuffer, cBits, iBitPrev);
    725728                                }
    726729                                else
    727730                                {
    728731                                    /* Check for the first free bit. */
     732                                    iBit = ASMBitNextClear(abBitmapBuffer, cBits, iBitPrev);
    729733                                }
    730734
     
    732736                                {
    733737                                    /* No change. */
    734                                     pRangeCur->cBlocks += cBlocksRead;
    735                                     cBlocksRead = 0;
     738                                    pRangeCur->cBlocks += cBits;
     739                                    cBits = 0;
    736740                                }
    737741                                else
    738742                                {
     743                                    Assert((uint32_t)iBit < cBits);
     744                                    pRangeCur->cBlocks += iBit;
     745
    739746                                    /* Create a new range descriptor. */
     747                                    PVCIBLKRANGEDESC pRangeNew = (PVCIBLKRANGEDESC)RTMemAllocZ(sizeof(VCIBLKRANGEDESC));
     748                                    if (!pRangeNew)
     749                                    {
     750                                        rc = VERR_NO_MEMORY;
     751                                        break;
     752                                    }
     753
     754                                    pRangeNew->fFree = !pRangeCur->fFree;
     755                                    pRangeNew->offAddrStart = pRangeCur->offAddrStart + pRangeCur->cBlocks;
     756                                    pRangeNew->cBlocks = 0;
     757                                    pRangeNew->pPrev = pRangeCur;
     758                                    pRangeCur->pNext = pRangeNew;
     759                                    pBlkMap->pRangesTail = pRangeNew;
     760                                    pRangeCur = pRangeNew;
     761                                    cBits -= iBit;
     762                                    iBitPrev = iBit;
    740763                                }
    741764                            }
    742 #endif
     765
    743766                            cBlocksLeft -= cBlocksRead;
    744767                            offBlkMap   += cBlocksRead;
    745768
    746                             if (cBlocksLeft)
     769                            if (   RT_SUCCESS(rc)
     770                                && cBlocksLeft)
    747771                            {
    748772                                /* Read next chunk. */
     773                                cBlocksRead = RT_MIN(VCI_BYTE2BLOCK(sizeof(abBitmapBuffer)), cBlocksLeft);
     774                                rc = vciFileReadSync(pStorage, offBlkMap, abBitmapBuffer, cBlocksRead);
    749775                            }
    750776                        }
     
    797823
    798824    /* Make sure the number of blocks allocated for us match our expectations. */
    799     if ((pBlkMap->cBlocks / 8) + VCI_BYTE2BLOCK(sizeof(VciBlkMap)) == cBlkMap)
     825    if (VCI_BYTE2BLOCK(pBlkMap->cBlocks / 8) + VCI_BYTE2BLOCK(sizeof(VciBlkMap)) == cBlkMap)
    800826    {
    801827        /* Setup the header */
     
    809835        BlkMap.cBlocksAllocData = RT_H2LE_U32(pBlkMap->cBlocksAllocData);
    810836
    811         rc = vciFileWriteSync(pStorage, VCI_BLOCK2BYTE(offBlkMap), &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
     837        rc = vciFileWriteSync(pStorage, offBlkMap, &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
    812838        if (RT_SUCCESS(rc))
    813839        {
     
    838864                    {
    839865                        /* Buffer is full, write to file and reset. */
    840                         rc = vciFileWriteSync(pStorage, offBlkMap, abBitmapBuffer, sizeof(abBitmapBuffer));
     866                        rc = vciFileWriteSync(pStorage, offBlkMap, abBitmapBuffer, VCI_BYTE2BLOCK(sizeof(abBitmapBuffer)));
    841867                        if (RT_FAILURE(rc))
    842868                            break;
     
    853879
    854880            if (RT_SUCCESS(rc) && iBit)
    855                 rc = vciFileWriteSync(pStorage, offBlkMap, abBitmapBuffer, iBit / 8);
     881                rc = vciFileWriteSync(pStorage, offBlkMap, abBitmapBuffer, VCI_BYTE2BLOCK(iBit / 8));
    856882        }
    857883    }
     
    932958                pFree->fFree = true;
    933959                pFree->cBlocks = pBestFit->cBlocks - cBlocks;
     960                pBestFit->cBlocks -= pFree->cBlocks;
    934961                pFree->offAddrStart = pBestFit->offAddrStart + cBlocks;
    935962
     
    12801307    }
    12811308
    1282     rc = vciFileReadSync(pCache, 0, &Hdr, sizeof(Hdr));
     1309    rc = vciFileReadSync(pCache, 0, &Hdr, VCI_BYTE2BLOCK(sizeof(Hdr)));
    12831310    if (RT_FAILURE(rc))
    12841311    {
     
    13021329
    13031330        /* Load the block map. */
    1304         rc = vciBlkMapLoad(pCache, VCI_BLOCK2BYTE(pCache->offBlksBitmap), Hdr.cBlkMap, &pCache->pBlkMap);
     1331        rc = vciBlkMapLoad(pCache, pCache->offBlksBitmap, Hdr.cBlkMap, &pCache->pBlkMap);
    13051332        if (RT_SUCCESS(rc))
    13061333        {
     
    13081335            VciTreeNode RootNode;
    13091336
    1310             rc = vciFileReadSync(pCache, VCI_BLOCK2BYTE(pCache->offTreeRoot), &RootNode, sizeof(VciTreeNode));
     1337            rc = vciFileReadSync(pCache, pCache->offTreeRoot, &RootNode, VCI_BYTE2BLOCK(sizeof(VciTreeNode)));
    13111338            if (RT_SUCCESS(rc))
    13121339            {
     
    17421769    Assert(cbToWrite % 512 == 0);
    17431770
     1771    *pcbWriteProcess = cbToWrite; /** @todo: Implement. */
    17441772out:
    17451773    LogFlowFunc(("returns %Rrc\n", rc));
  • trunk/src/VBox/Storage/VD.cpp

    r33595 r33745  
    6666
    6767/**
     68 * Structure containing everything I/O related
     69 * for the image and cache descriptors.
     70 */
     71typedef struct VDIO
     72{
     73    /** I/O interface to the upper layer. */
     74    PVDINTERFACE        pInterfaceIO;
     75    /** I/O interface callback table. */
     76    PVDINTERFACEIO      pInterfaceIOCallbacks;
     77
     78    /** Per image internal I/O interface. */
     79    VDINTERFACE         VDIIOInt;
     80
     81    /** Fallback I/O interface, only used if the caller doesn't provide it. */
     82    VDINTERFACE         VDIIO;
     83
     84    /** Opaque backend data. */
     85    void               *pBackendData;
     86    /** Disk this image is part of */
     87    PVBOXHDD            pDisk;
     88} VDIO, *PVDIO;
     89
     90/**
    6891 * VBox HDD Container image descriptor.
    6992 */
     
    86109    /** Function pointers for the various backend methods. */
    87110    PCVBOXHDDBACKEND    Backend;
    88 
    89111    /** Pointer to list of VD interfaces, per-image. */
    90112    PVDINTERFACE        pVDIfsImage;
    91 
    92     /** I/O interface to the upper layer. */
    93     PVDINTERFACE        pInterfaceIO;
    94     /** I/O interface callback table. */
    95     PVDINTERFACEIO      pInterfaceIOCallbacks;
    96 
    97     /** Per image internal I/O interface. */
    98     VDINTERFACE         VDIIOInt;
    99 
    100     /** Fallback I/O interface, only used if the caller doesn't provide it. */
    101     VDINTERFACE         VDIIO;
    102 
    103     /** Disk this image is part of */
    104     PVBOXHDD            pDisk;
     113    /** I/O related things. */
     114    VDIO                VDIo;
    105115} VDIMAGE, *PVDIMAGE;
    106116
     
    133143    /** Pointer to list of VD interfaces, per-cache. */
    134144    PVDINTERFACE        pVDIfsCache;
    135 
    136     /** I/O interface to the upper layer. */
    137     PVDINTERFACE        pInterfaceIO;
    138     /** I/O interface callback table. */
    139     PVDINTERFACEIO      pInterfaceIOCallbacks;
    140 
    141     /** Per image internal I/O interface. */
    142     VDINTERFACE         VDIIOInt;
    143 
    144     /** Fallback I/O interface, only used if the caller doesn't provide it. */
    145     VDINTERFACE         VDIIO;
    146 
    147     /** Disk this image is part of */
    148     PVBOXHDD            pDisk;
     145    /** I/O related things. */
     146    VDIO                VDIo;
    149147} VDCACHE, *PVDCACHE;
    150148
     
    392390typedef struct VDIOSTORAGE
    393391{
    394     /** Image this storage handle belongs to. */
    395     PVDIMAGE                     pImage;
     392    /** Image I/O state this storage handle belongs to. */
     393    PVDIO                        pVDIo;
    396394    /** AVL tree for pending async metadata transfers. */
    397395    PAVLRFOFFTREE                pTreeMetaXfers;
     
    799797    }
    800798
    801     if (RT_SUCCESS(rc))
     799    if (RT_SUCCESS(rc) || rc == VERR_VD_BLOCK_FREE)
    802800        *pcbThisRead = cbThisRead;
    803801
     
    991989    PVDIOTASK pIoTask = NULL;
    992990
    993     pIoTask = (PVDIOTASK)RTMemCacheAlloc(pIoStorage->pImage->pDisk->hMemCacheIoTask);
     991    pIoTask = (PVDIOTASK)RTMemCacheAlloc(pIoStorage->pVDIo->pDisk->hMemCacheIoTask);
    994992    if (pIoTask)
    995993    {
     
    10091007    PVDIOTASK pIoTask = NULL;
    10101008
    1011     pIoTask = (PVDIOTASK)RTMemCacheAlloc(pIoStorage->pImage->pDisk->hMemCacheIoTask);
     1009    pIoTask = (PVDIOTASK)RTMemCacheAlloc(pIoStorage->pVDIo->pDisk->hMemCacheIoTask);
    10121010    if (pIoTask)
    10131011    {
     
    10471045}
    10481046
    1049 DECLINLINE(PVDMETAXFER) vdMetaXferAlloc(PVDIMAGE pImage, PVDIOSTORAGE pIoStorage, uint64_t uOffset, size_t cb)
     1047DECLINLINE(PVDMETAXFER) vdMetaXferAlloc(PVDIOSTORAGE pIoStorage, uint64_t uOffset, size_t cb)
    10501048{
    10511049    PVDMETAXFER pMetaXfer = (PVDMETAXFER)RTMemAlloc(RT_OFFSETOF(VDMETAXFER, abData[cb]));
     
    26032601    {
    26042602        RTCritSectEnter(&pDisk->CritSect);
    2605         rc = pfnComplete(pIoStorage->pImage->pBackendData, pIoCtx, pvUser, rcReq);
     2603        rc = pfnComplete(pIoStorage->pVDIo->pBackendData, pIoCtx, pvUser, rcReq);
    26062604        RTCritSectLeave(&pDisk->CritSect);
    26072605    }
     
    26212619                               PVDMETAXFER pMetaXfer, int rcReq)
    26222620{
    2623     PVBOXHDD pDisk = pIoStorage->pImage->pDisk;
     2621    PVBOXHDD pDisk = pIoStorage->pVDIo->pDisk;
    26242622    RTLISTNODE ListIoCtxWaiting;
    26252623    bool fFlush;
     
    26692667        {
    26702668            RTCritSectEnter(&pDisk->CritSect);
    2671             rc = pfnComplete(pIoStorage->pImage->pBackendData, pIoCtx, pvUser, rcReq);
     2669            rc = pfnComplete(pIoStorage->pVDIo->pBackendData, pIoCtx, pvUser, rcReq);
    26722670            RTCritSectLeave(&pDisk->CritSect);
    26732671        }
     
    27212719                                 pIoTask->Type.Meta.pMetaXfer, rcReq);
    27222720
    2723     vdIoTaskFree(pIoStorage->pImage->pDisk, pIoTask);
     2721    vdIoTaskFree(pIoStorage->pVDIo->pDisk, pIoTask);
    27242722
    27252723    return rc;
     
    27332731{
    27342732    int rc = VINF_SUCCESS;
    2735     PVDIMAGE pImage         = (PVDIMAGE)pvUser;
     2733    PVDIO pVDIo             = (PVDIO)pvUser;
    27362734    PVDIOSTORAGE pIoStorage = (PVDIOSTORAGE)RTMemAllocZ(sizeof(VDIOSTORAGE));
    27372735
    27382736    if (!pIoStorage)
    27392737        return VERR_NO_MEMORY;
    2740 
    2741     pIoStorage->pImage = pImage;
    27422738
    27432739    /* Create the AVl tree. */
     
    27452741    if (pIoStorage->pTreeMetaXfers)
    27462742    {
    2747         rc = pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser,
    2748                                                     pszLocation, uOpenFlags,
    2749                                                     vdIOIntReqCompleted,
    2750                                                     &pIoStorage->pStorage);
     2743        rc = pVDIo->pInterfaceIOCallbacks->pfnOpen(pVDIo->pInterfaceIO->pvUser,
     2744                                                   pszLocation, uOpenFlags,
     2745                                                   vdIOIntReqCompleted,
     2746                                                   &pIoStorage->pStorage);
    27512747        if (RT_SUCCESS(rc))
    27522748        {
     2749            pIoStorage->pVDIo = pVDIo;
    27532750            *ppIoStorage = pIoStorage;
    27542751            return VINF_SUCCESS;
     
    27722769static int vdIOIntClose(void *pvUser, PVDIOSTORAGE pIoStorage)
    27732770{
    2774     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2775 
    2776     int rc = pImage->pInterfaceIOCallbacks->pfnClose(pImage->pInterfaceIO->pvUser,
    2777                                                      pIoStorage->pStorage);
     2771    PVDIO pVDIo             = (PVDIO)pvUser;
     2772
     2773    int rc = pVDIo->pInterfaceIOCallbacks->pfnClose(pVDIo->pInterfaceIO->pvUser,
     2774                                                    pIoStorage->pStorage);
    27782775    AssertRC(rc);
    27792776
     
    27862783static int vdIOIntDelete(void *pvUser, const char *pcszFilename)
    27872784{
    2788     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2789     return pImage->pInterfaceIOCallbacks->pfnDelete(pImage->pInterfaceIO->pvUser,
    2790                                                     pcszFilename);
     2785    PVDIO pVDIo = (PVDIO)pvUser;
     2786    return pVDIo->pInterfaceIOCallbacks->pfnDelete(pVDIo->pInterfaceIO->pvUser,
     2787                                                   pcszFilename);
    27912788}
    27922789
     
    27942791                       unsigned fMove)
    27952792{
    2796     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2797     return pImage->pInterfaceIOCallbacks->pfnMove(pImage->pInterfaceIO->pvUser,
    2798                                                   pcszSrc, pcszDst, fMove);
     2793    PVDIO pVDIo = (PVDIO)pvUser;
     2794    return pVDIo->pInterfaceIOCallbacks->pfnMove(pVDIo->pInterfaceIO->pvUser,
     2795                                                 pcszSrc, pcszDst, fMove);
    27992796}
    28002797
     
    28022799                               int64_t *pcbFreeSpace)
    28032800{
    2804     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2805     return pImage->pInterfaceIOCallbacks->pfnGetFreeSpace(pImage->pInterfaceIO->pvUser,
    2806                                                           pcszFilename,
    2807                                                           pcbFreeSpace);
     2801    PVDIO pVDIo = (PVDIO)pvUser;
     2802    return pVDIo->pInterfaceIOCallbacks->pfnGetFreeSpace(pVDIo->pInterfaceIO->pvUser,
     2803                                                         pcszFilename,
     2804                                                         pcbFreeSpace);
    28082805}
    28092806
     
    28112808                                      PRTTIMESPEC pModificationTime)
    28122809{
    2813     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2814     return pImage->pInterfaceIOCallbacks->pfnGetModificationTime(pImage->pInterfaceIO->pvUser,
    2815                                                                  pcszFilename,
    2816                                                                  pModificationTime);
     2810    PVDIO pVDIo = (PVDIO)pvUser;
     2811    return pVDIo->pInterfaceIOCallbacks->pfnGetModificationTime(pVDIo->pInterfaceIO->pvUser,
     2812                                                                pcszFilename,
     2813                                                                pModificationTime);
    28172814}
    28182815
     
    28202817                          uint64_t *pcbSize)
    28212818{
    2822     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2823 
    2824     return pImage->pInterfaceIOCallbacks->pfnGetSize(pImage->pInterfaceIO->pvUser,
     2819    PVDIO pVDIo = (PVDIO)pvUser;
     2820    return pVDIo->pInterfaceIOCallbacks->pfnGetSize(pVDIo->pInterfaceIO->pvUser,
    28252821                                                    pIoStorage->pStorage,
    28262822                                                    pcbSize);
     
    28302826                          uint64_t cbSize)
    28312827{
    2832     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2833 
    2834     return pImage->pInterfaceIOCallbacks->pfnSetSize(pImage->pInterfaceIO->pvUser,
    2835                                                      pIoStorage->pStorage,
    2836                                                      cbSize);
     2828    PVDIO pVDIo = (PVDIO)pvUser;
     2829
     2830    return pVDIo->pInterfaceIOCallbacks->pfnSetSize(pVDIo->pInterfaceIO->pvUser,
     2831                                                    pIoStorage->pStorage,
     2832                                                    cbSize);
    28372833}
    28382834
     
    28412837                            size_t cbWrite, size_t *pcbWritten)
    28422838{
    2843     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2844 
    2845     return pImage->pInterfaceIOCallbacks->pfnWriteSync(pImage->pInterfaceIO->pvUser,
    2846                                                        pIoStorage->pStorage,
    2847                                                        uOffset, pvBuf, cbWrite,
    2848                                                        pcbWritten);
     2839    PVDIO pVDIo = (PVDIO)pvUser;
     2840
     2841    return pVDIo->pInterfaceIOCallbacks->pfnWriteSync(pVDIo->pInterfaceIO->pvUser,
     2842                                                      pIoStorage->pStorage,
     2843                                                      uOffset, pvBuf, cbWrite,
     2844                                                      pcbWritten);
    28492845}
    28502846
     
    28532849                           size_t *pcbRead)
    28542850{
    2855     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2856 
    2857     return pImage->pInterfaceIOCallbacks->pfnReadSync(pImage->pInterfaceIO->pvUser,
    2858                                                       pIoStorage->pStorage,
    2859                                                       uOffset, pvBuf, cbRead,
    2860                                                       pcbRead);
     2851    PVDIO pVDIo = (PVDIO)pvUser;
     2852    return pVDIo->pInterfaceIOCallbacks->pfnReadSync(pVDIo->pInterfaceIO->pvUser,
     2853                                                     pIoStorage->pStorage,
     2854                                                     uOffset, pvBuf, cbRead,
     2855                                                     pcbRead);
    28612856}
    28622857
    28632858static int vdIOIntFlushSync(void *pvUser, PVDIOSTORAGE pIoStorage)
    28642859{
    2865     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2866 
    2867     return pImage->pInterfaceIOCallbacks->pfnFlushSync(pImage->pInterfaceIO->pvUser,
    2868                                                        pIoStorage->pStorage);
     2860    PVDIO pVDIo = (PVDIO)pvUser;
     2861    return pVDIo->pInterfaceIOCallbacks->pfnFlushSync(pVDIo->pInterfaceIO->pvUser,
     2862                                                      pIoStorage->pStorage);
    28692863}
    28702864
     
    28742868{
    28752869    int rc = VINF_SUCCESS;
    2876     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2877     PVBOXHDD pDisk  = pImage->pDisk;
     2870    PVDIO    pVDIo = (PVDIO)pvUser;
     2871    PVBOXHDD pDisk = pVDIo->pDisk;
    28782872
    28792873    LogFlowFunc(("pvUser=%#p pIoStorage=%#p uOffset=%llu pIoCtx=%#p cbRead=%u\n",
     
    29092903
    29102904        void *pvTask;
    2911         rc = pImage->pInterfaceIOCallbacks->pfnReadAsync(pImage->pInterfaceIO->pvUser,
    2912                                                          pIoStorage->pStorage,
    2913                                                          uOffset, aSeg, cSegments,
    2914                                                          cbTaskRead, pIoTask,
    2915                                                          &pvTask);
     2905        rc = pVDIo->pInterfaceIOCallbacks->pfnReadAsync(pVDIo->pInterfaceIO->pvUser,
     2906                                                        pIoStorage->pStorage,
     2907                                                        uOffset, aSeg, cSegments,
     2908                                                        cbTaskRead, pIoTask,
     2909                                                        &pvTask);
    29162910        if (RT_SUCCESS(rc))
    29172911        {
     
    29422936{
    29432937    int rc = VINF_SUCCESS;
    2944     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    2945     PVBOXHDD pDisk  = pImage->pDisk;
     2938    PVDIO    pVDIo = (PVDIO)pvUser;
     2939    PVBOXHDD pDisk = pVDIo->pDisk;
    29462940
    29472941    LogFlowFunc(("pvUser=%#p pIoStorage=%#p uOffset=%llu pIoCtx=%#p cbWrite=%u\n",
     
    29772971
    29782972        void *pvTask;
    2979         rc = pImage->pInterfaceIOCallbacks->pfnWriteAsync(pImage->pInterfaceIO->pvUser,
    2980                                                           pIoStorage->pStorage,
    2981                                                           uOffset, aSeg, cSegments,
    2982                                                           cbTaskWrite, pIoTask,
    2983                                                           &pvTask);
     2973        rc = pVDIo->pInterfaceIOCallbacks->pfnWriteAsync(pVDIo->pInterfaceIO->pvUser,
     2974                                                         pIoStorage->pStorage,
     2975                                                         uOffset, aSeg, cSegments,
     2976                                                         cbTaskWrite, pIoTask,
     2977                                                         &pvTask);
    29842978        if (RT_SUCCESS(rc))
    29852979        {
     
    30093003                                void *pvCompleteUser)
    30103004{
    3011     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3012     PVBOXHDD pDisk  = pImage->pDisk;
     3005    PVDIO pVDIo     = (PVDIO)pvUser;
     3006    PVBOXHDD pDisk  = pVDIo->pDisk;
    30133007    int rc = VINF_SUCCESS;
    30143008    RTSGSEG Seg;
     
    30323026
    30333027        /* Allocate a new meta transfer. */
    3034         pMetaXfer = vdMetaXferAlloc(pImage, pIoStorage, uOffset, cbRead);
     3028        pMetaXfer = vdMetaXferAlloc(pIoStorage, uOffset, cbRead);
    30353029        if (!pMetaXfer)
    30363030            return VERR_NO_MEMORY;
     
    30473041
    30483042        VDMETAXFER_TXDIR_SET(pMetaXfer->fFlags, VDMETAXFER_TXDIR_READ);
    3049         rc = pImage->pInterfaceIOCallbacks->pfnReadAsync(pImage->pInterfaceIO->pvUser,
    3050                                                          pIoStorage->pStorage,
    3051                                                          uOffset, &Seg, 1,
    3052                                                          cbRead, pIoTask,
    3053                                                          &pvTask);
     3043        rc = pVDIo->pInterfaceIOCallbacks->pfnReadAsync(pVDIo->pInterfaceIO->pvUser,
     3044                                                        pIoStorage->pStorage,
     3045                                                        uOffset, &Seg, 1,
     3046                                                        cbRead, pIoTask,
     3047                                                        &pvTask);
    30543048
    30553049        if (RT_SUCCESS(rc) || rc == VERR_VD_ASYNC_IO_IN_PROGRESS)
     
    31073101                                 void *pvCompleteUser)
    31083102{
    3109     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3110     PVBOXHDD pDisk  = pImage->pDisk;
     3103    PVDIO    pVDIo = (PVDIO)pvUser;
     3104    PVBOXHDD pDisk = pVDIo->pDisk;
    31113105    int rc = VINF_SUCCESS;
    31123106    RTSGSEG Seg;
     
    31253119    {
    31263120        /* Allocate a new meta transfer. */
    3127         pMetaXfer = vdMetaXferAlloc(pImage, pIoStorage, uOffset, cbWrite);
     3121        pMetaXfer = vdMetaXferAlloc(pIoStorage, uOffset, cbWrite);
    31283122        if (!pMetaXfer)
    31293123            return VERR_NO_MEMORY;
     
    31523146
    31533147    VDMETAXFER_TXDIR_SET(pMetaXfer->fFlags, VDMETAXFER_TXDIR_WRITE);
    3154     rc = pImage->pInterfaceIOCallbacks->pfnWriteAsync(pImage->pInterfaceIO->pvUser,
    3155                                                       pIoStorage->pStorage,
    3156                                                       uOffset, &Seg, 1,
    3157                                                       cbWrite, pIoTask,
    3158                                                       &pvTask);
     3148    rc = pVDIo->pInterfaceIOCallbacks->pfnWriteAsync(pVDIo->pInterfaceIO->pvUser,
     3149                                                     pIoStorage->pStorage,
     3150                                                     uOffset, &Seg, 1,
     3151                                                     cbWrite, pIoTask,
     3152                                                     &pvTask);
    31593153    if (RT_SUCCESS(rc))
    31603154    {
     
    31983192static void vdIOIntMetaXferRelease(void *pvUser, PVDMETAXFER pMetaXfer)
    31993193{
    3200     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3201     PVBOXHDD pDisk  = pImage->pDisk;
     3194    PVDIO    pVDIo = (PVDIO)pvUser;
     3195    PVBOXHDD pDisk = pVDIo->pDisk;
    32023196    PVDIOSTORAGE pIoStorage = pMetaXfer->pIoStorage;
    32033197
     
    32263220                             void *pvCompleteUser)
    32273221{
    3228     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3229     PVBOXHDD pDisk  = pImage->pDisk;
     3222    PVDIO    pVDIo = (PVDIO)pvUser;
     3223    PVBOXHDD pDisk = pVDIo->pDisk;
    32303224    int rc = VINF_SUCCESS;
    32313225    PVDIOTASK pIoTask;
     
    32393233
    32403234    /* Allocate a new meta transfer. */
    3241     pMetaXfer = vdMetaXferAlloc(pImage, pIoStorage, 0, 0);
     3235    pMetaXfer = vdMetaXferAlloc(pIoStorage, 0, 0);
    32423236    if (!pMetaXfer)
    32433237        return VERR_NO_MEMORY;
     
    32603254    RTListAppend(&pMetaXfer->ListIoCtxWaiting, &pDeferred->NodeDeferred);
    32613255    VDMETAXFER_TXDIR_SET(pMetaXfer->fFlags, VDMETAXFER_TXDIR_FLUSH);
    3262     rc = pImage->pInterfaceIOCallbacks->pfnFlushAsync(pImage->pInterfaceIO->pvUser,
    3263                                                       pIoStorage->pStorage,
    3264                                                       pIoTask, &pvTask);
     3256    rc = pVDIo->pInterfaceIOCallbacks->pfnFlushAsync(pVDIo->pInterfaceIO->pvUser,
     3257                                                     pIoStorage->pStorage,
     3258                                                     pIoTask, &pvTask);
    32653259    if (RT_SUCCESS(rc))
    32663260    {
     
    32803274                                 void *pvBuf, size_t cbBuf)
    32813275{
    3282     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3283     PVBOXHDD pDisk  = pImage->pDisk;
     3276    PVDIO    pVDIo = (PVDIO)pvUser;
     3277    PVBOXHDD pDisk = pVDIo->pDisk;
    32843278    size_t cbCopied = 0;
    32853279
     
    32973291                                   void *pvBuf, size_t cbBuf)
    32983292{
    3299     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3300     PVBOXHDD pDisk  = pImage->pDisk;
     3293    PVDIO    pVDIo = (PVDIO)pvUser;
     3294    PVBOXHDD pDisk = pVDIo->pDisk;
    33013295    size_t cbCopied = 0;
    33023296
     
    33133307static size_t vdIOIntIoCtxSet(void *pvUser, PVDIOCTX pIoCtx, int ch, size_t cb)
    33143308{
    3315     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3316     PVBOXHDD pDisk  = pImage->pDisk;
     3309    PVDIO    pVDIo = (PVDIO)pvUser;
     3310    PVBOXHDD pDisk = pVDIo->pDisk;
    33173311    size_t cbSet = 0;
    33183312
     
    33313325                                         size_t cbData)
    33323326{
    3333     PVDIMAGE pImage = (PVDIMAGE)pvUser;
    3334     PVBOXHDD pDisk  = pImage->pDisk;
     3327    PVDIO    pVDIo = (PVDIO)pvUser;
     3328    PVBOXHDD pDisk = pVDIo->pDisk;
    33353329    size_t cbCreated = 0;
    33363330
     
    40114005        }
    40124006
    4013         pImage->pDisk       = pDisk;
     4007        pImage->VDIo.pDisk  = pDisk;
    40144008        pImage->pVDIfsImage = pVDIfsImage;
    40154009
     
    40254019
    40264020        /* Set up the I/O interface. */
    4027         pImage->pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
    4028         if (pImage->pInterfaceIO)
    4029             pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
     4021        pImage->VDIo.pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
     4022        if (pImage->VDIo.pInterfaceIO)
     4023            pImage->VDIo.pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->VDIo.pInterfaceIO);
    40304024        else
    40314025        {
    4032             rc = VDInterfaceAdd(&pImage->VDIIO, "VD_IO", VDINTERFACETYPE_IO,
     4026            rc = VDInterfaceAdd(&pImage->VDIo.VDIIO, "VD_IO", VDINTERFACETYPE_IO,
    40334027                                &pDisk->VDIIOCallbacks, pDisk, &pVDIfsImage);
    4034             pImage->pInterfaceIO = &pImage->VDIIO;
    4035             pImage->pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
     4028            pImage->VDIo.pInterfaceIO = &pImage->VDIo.VDIIO;
     4029            pImage->VDIo.pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
    40364030        }
    40374031
     
    40394033        AssertBreakStmt(!VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IOINT),
    40404034                        rc = VERR_INVALID_PARAMETER);
    4041         rc = VDInterfaceAdd(&pImage->VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
    4042                             &pDisk->VDIIOIntCallbacks, pImage, &pImage->pVDIfsImage);
     4035        rc = VDInterfaceAdd(&pImage->VDIo.VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
     4036                            &pDisk->VDIIOIntCallbacks, &pImage->VDIo, &pImage->pVDIfsImage);
    40434037        AssertRC(rc);
    40444038
     
    40794073        fLockWrite = true;
    40804074
     4075        pImage->VDIo.pBackendData = pImage->pBackendData;
     4076
    40814077        /* Check image type. As the image itself has only partial knowledge
    40824078         * whether it's a base image or not, this info is derived here. The
     
    42644260        }
    42654261
    4266         pCache->pDisk       = pDisk;
     4262        pCache->VDIo.pDisk  = pDisk;
    42674263        pCache->pVDIfsCache = pVDIfsCache;
    42684264
     
    42784274
    42794275        /* Set up the I/O interface. */
    4280         pCache->pInterfaceIO = VDInterfaceGet(pVDIfsCache, VDINTERFACETYPE_IO);
    4281         if (pCache->pInterfaceIO)
    4282             pCache->pInterfaceIOCallbacks = VDGetInterfaceIO(pCache->pInterfaceIO);
     4276        pCache->VDIo.pInterfaceIO = VDInterfaceGet(pVDIfsCache, VDINTERFACETYPE_IO);
     4277        if (pCache->VDIo.pInterfaceIO)
     4278            pCache->VDIo.pInterfaceIOCallbacks = VDGetInterfaceIO(pCache->VDIo.pInterfaceIO);
    42834279        else
    42844280        {
    4285             rc = VDInterfaceAdd(&pCache->VDIIO, "VD_IO", VDINTERFACETYPE_IO,
     4281            rc = VDInterfaceAdd(&pCache->VDIo.VDIIO, "VD_IO", VDINTERFACETYPE_IO,
    42864282                                &pDisk->VDIIOCallbacks, pDisk, &pVDIfsCache);
    4287             pCache->pInterfaceIO = &pCache->VDIIO;
    4288             pCache->pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
     4283            pCache->VDIo.pInterfaceIO = &pCache->VDIo.VDIIO;
     4284            pCache->VDIo.pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
    42894285        }
    42904286
     
    42924288        AssertBreakStmt(!VDInterfaceGet(pVDIfsCache, VDINTERFACETYPE_IOINT),
    42934289                        rc = VERR_INVALID_PARAMETER);
    4294         rc = VDInterfaceAdd(&pCache->VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
    4295                             &pDisk->VDIIOIntCallbacks, pCache, &pCache->pVDIfsCache);
     4290        rc = VDInterfaceAdd(&pCache->VDIo.VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
     4291                            &pDisk->VDIIOIntCallbacks, &pCache->VDIo, &pCache->pVDIfsCache);
    42964292        AssertRC(rc);
    42974293
     
    45094505            break;
    45104506        }
    4511         pImage->pDisk       = pDisk;
     4507        pImage->VDIo.pDisk  = pDisk;
    45124508        pImage->pVDIfsImage = pVDIfsImage;
    45134509
    45144510        /* Set up the I/O interface. */
    4515         pImage->pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
    4516         if (pImage->pInterfaceIO)
    4517             pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
     4511        pImage->VDIo.pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
     4512        if (pImage->VDIo.pInterfaceIO)
     4513            pImage->VDIo.pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->VDIo.pInterfaceIO);
    45184514        else
    45194515        {
    4520             rc = VDInterfaceAdd(&pImage->VDIIO, "VD_IO", VDINTERFACETYPE_IO,
     4516            rc = VDInterfaceAdd(&pImage->VDIo.VDIIO, "VD_IO", VDINTERFACETYPE_IO,
    45214517                                &pDisk->VDIIOCallbacks, pDisk, &pVDIfsImage);
    4522             pImage->pInterfaceIO = &pImage->VDIIO;
    4523             pImage->pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
     4518            pImage->VDIo.pInterfaceIO = &pImage->VDIo.VDIIO;
     4519            pImage->VDIo.pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
    45244520        }
    45254521
     
    45274523        AssertBreakStmt(!VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IOINT),
    45284524                        rc = VERR_INVALID_PARAMETER);
    4529         rc = VDInterfaceAdd(&pImage->VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
    4530                             &pDisk->VDIIOIntCallbacks, pImage, &pImage->pVDIfsImage);
     4525        rc = VDInterfaceAdd(&pImage->VDIo.VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
     4526                            &pDisk->VDIIOIntCallbacks, &pImage->VDIo, &pImage->pVDIfsImage);
    45314527        AssertRC(rc);
    45324528
     
    45764572        if (RT_SUCCESS(rc))
    45774573        {
     4574            pImage->VDIo.pBackendData = pImage->pBackendData;
    45784575            pImage->uImageFlags = uImageFlags;
    45794576
     
    47914788        }
    47924789
    4793         pImage->pDisk       = pDisk;
     4790        pImage->VDIo.pDisk  = pDisk;
    47944791        pImage->pVDIfsImage = pVDIfsImage;
    47954792
    47964793        /* Set up the I/O interface. */
    4797         pImage->pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
    4798         if (pImage->pInterfaceIO)
    4799             pImage->pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->pInterfaceIO);
     4794        pImage->VDIo.pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IO);
     4795        if (pImage->VDIo.pInterfaceIO)
     4796            pImage->VDIo.pInterfaceIOCallbacks = VDGetInterfaceIO(pImage->VDIo.pInterfaceIO);
    48004797        else
    48014798        {
    4802             rc = VDInterfaceAdd(&pImage->VDIIO, "VD_IO", VDINTERFACETYPE_IO,
     4799            rc = VDInterfaceAdd(&pImage->VDIo.VDIIO, "VD_IO", VDINTERFACETYPE_IO,
    48034800                                &pDisk->VDIIOCallbacks, pDisk, &pVDIfsImage);
    4804             pImage->pInterfaceIO = &pImage->VDIIO;
    4805             pImage->pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
     4801            pImage->VDIo.pInterfaceIO = &pImage->VDIo.VDIIO;
     4802            pImage->VDIo.pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
    48064803        }
    48074804
     
    48094806        AssertBreakStmt(!VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IOINT),
    48104807                        rc = VERR_INVALID_PARAMETER);
    4811         rc = VDInterfaceAdd(&pImage->VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
    4812                             &pDisk->VDIIOIntCallbacks, pImage, &pImage->pVDIfsImage);
     4808        rc = VDInterfaceAdd(&pImage->VDIo.VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
     4809                            &pDisk->VDIIOIntCallbacks, &pImage->VDIo, &pImage->pVDIfsImage);
    48134810        AssertRC(rc);
    48144811
     
    48424839        if (RT_SUCCESS(rc))
    48434840        {
     4841            pImage->VDIo.pBackendData = pImage->pBackendData;
    48444842            pImage->uImageFlags = uImageFlags;
    48454843
     
    50135011        AssertRC(rc2);
    50145012        fLockRead = true;
    5015         AssertMsgBreakStmt(pDisk->cImages != 0,
    5016                            ("Create diff image cannot be done without other images open\n"),
    5017                            rc = VERR_VD_INVALID_STATE);
    50185013        AssertMsgBreakStmt(!pDisk->pCache,
    50195014                           ("Create cache image cannot be done with a cache already attached\n"),
     
    50475042        }
    50485043
    5049         pCache->pDisk       = pDisk;
    5050         pCache->pVDIfsCache = pVDIfsCache;
     5044        pCache->VDIo.pDisk        = pDisk;
     5045        pCache->pVDIfsCache       = pVDIfsCache;
    50515046
    50525047        /* Set up the I/O interface. */
    5053         pCache->pInterfaceIO = VDInterfaceGet(pVDIfsCache, VDINTERFACETYPE_IO);
    5054         if (pCache->pInterfaceIO)
    5055             pCache->pInterfaceIOCallbacks = VDGetInterfaceIO(pCache->pInterfaceIO);
     5048        pCache->VDIo.pInterfaceIO = VDInterfaceGet(pVDIfsCache, VDINTERFACETYPE_IO);
     5049        if (pCache->VDIo.pInterfaceIO)
     5050            pCache->VDIo.pInterfaceIOCallbacks = VDGetInterfaceIO(pCache->VDIo.pInterfaceIO);
    50565051        else
    50575052        {
    5058             rc = VDInterfaceAdd(&pCache->VDIIO, "VD_IO", VDINTERFACETYPE_IO,
     5053            rc = VDInterfaceAdd(&pCache->VDIo.VDIIO, "VD_IO", VDINTERFACETYPE_IO,
    50595054                                &pDisk->VDIIOCallbacks, pDisk, &pVDIfsCache);
    5060             pCache->pInterfaceIO = &pCache->VDIIO;
    5061             pCache->pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
     5055            pCache->VDIo.pInterfaceIO = &pCache->VDIo.VDIIO;
     5056            pCache->VDIo.pInterfaceIOCallbacks = &pDisk->VDIIOCallbacks;
    50625057        }
    50635058
     
    50655060        AssertBreakStmt(!VDInterfaceGet(pVDIfsCache, VDINTERFACETYPE_IOINT),
    50665061                        rc = VERR_INVALID_PARAMETER);
    5067         rc = VDInterfaceAdd(&pCache->VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
    5068                             &pDisk->VDIIOIntCallbacks, pCache, &pCache->pVDIfsCache);
     5062        rc = VDInterfaceAdd(&pCache->VDIo.VDIIOInt, "VD_IOINT", VDINTERFACETYPE_IOINT,
     5063                            &pDisk->VDIIOIntCallbacks, &pCache->VDIo, &pCache->pVDIfsCache);
    50695064        AssertRC(rc);
    50705065
     
    51015096            fLockWrite = true;
    51025097
     5098            pCache->VDIo.pBackendData = pCache->pBackendData;
     5099
    51035100            /* Re-check state, as the lock wasn't held and another image
    51045101             * creation call could have been done by another thread. */
     
    51085105        }
    51095106
    5110         if (RT_SUCCESS(rc))
     5107        if (   RT_SUCCESS(rc)
     5108            && pDisk->pLast)
    51115109        {
    51125110            RTUUID UuidModification;
  • trunk/src/VBox/Storage/testcase/vbox-img.cpp

    r33595 r33745  
    5252                 "   info         --filename <filename>\n"
    5353                 "\n"
    54                  "   compact      --filename <filename>\n",
     54                 "   compact      --filename <filename>\n"
     55                 "   createcache  --filename <filename>\n"
     56                 "                --size <cache size>\n",
    5557                 g_pszProgName);
    5658}
     
    969971
    970972
     973int handleCreateCache(HandlerArg *a)
     974{
     975    int rc = VINF_SUCCESS;
     976    PVBOXHDD pDisk = NULL;
     977    const char *pszFilename = NULL;
     978    uint64_t cbSize = 0;
     979
     980    /* Parse the command line. */
     981    static const RTGETOPTDEF s_aOptions[] =
     982    {
     983        { "--filename", 'f', RTGETOPT_REQ_STRING },
     984        { "--size",     's', RTGETOPT_REQ_UINT64 }
     985    };
     986    int ch;
     987    RTGETOPTUNION ValueUnion;
     988    RTGETOPTSTATE GetState;
     989    RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0 /* fFlags */);
     990    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     991    {
     992        switch (ch)
     993        {
     994            case 'f':   // --filename
     995                pszFilename = ValueUnion.psz;
     996                break;
     997
     998            case 's':   // --size
     999                cbSize = ValueUnion.u64;
     1000                break;
     1001
     1002            default:
     1003                ch = RTGetOptPrintError(ch, &ValueUnion);
     1004                printUsage(g_pStdErr);
     1005                return ch;
     1006        }
     1007    }
     1008
     1009    /* Check for mandatory parameters. */
     1010    if (!pszFilename)
     1011        return errorSyntax("Mandatory --filename option missing\n");
     1012
     1013    if (!cbSize)
     1014        return errorSyntax("Mandatory --size option missing\n");
     1015
     1016    /* just try it */
     1017    rc = VDCreate(pVDIfs, VDTYPE_HDD, &pDisk);
     1018    if (RT_FAILURE(rc))
     1019        return errorRuntime("Error while creating the virtual disk container: %Rrc\n", rc);
     1020
     1021    rc = VDCreateCache(pDisk, "VCI", pszFilename, cbSize, VD_IMAGE_FLAGS_DEFAULT,
     1022                       NULL, NULL, VD_OPEN_FLAGS_NORMAL, NULL, NULL);
     1023    if (RT_FAILURE(rc))
     1024        return errorRuntime("Error while creating the virtual disk cache: %Rrc\n", rc);
     1025
     1026    VDCloseAll(pDisk);
     1027
     1028    return rc;
     1029}
     1030
     1031
    9711032int main(int argc, char *argv[])
    9721033{
     
    10521113    } s_commandHandlers[] =
    10531114    {
    1054         { "setuuid", handleSetUUID },
    1055         { "convert", handleConvert },
    1056         { "info",    handleInfo    },
    1057         { "compact", handleCompact },
    1058         { NULL,               NULL }
     1115        { "setuuid",     handleSetUUID     },
     1116        { "convert",     handleConvert     },
     1117        { "info",        handleInfo        },
     1118        { "compact",     handleCompact     },
     1119        { "createcache", handleCreateCache },
     1120        { NULL,                       NULL }
    10591121    };
    10601122
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