VirtualBox

Changeset 33481 in vbox for trunk/src


Ignore:
Timestamp:
Oct 27, 2010 8:24:45 AM (14 years ago)
Author:
vboxsync
Message:

VCI: Updates

File:
1 edited

Legend:

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

    r32688 r33481  
    2727#include <iprt/alloc.h>
    2828#include <iprt/file.h>
     29#include <iprt/asm.h>
    2930
    3031/*******************************************************************************
     
    155156AssertCompileSize(VciTreeNode, 8 * VCI_BLOCK_SIZE);
    156157
    157 /** Node type: Root of the tree (VciTreeNodeInternal). */
    158 #define VCI_TREE_NODE_TYPE_ROOT     UINT32_C(0x00000001)
    159158/** Node type: Internal node containing links to other nodes (VciTreeNodeInternal). */
    160 #define VCI_TREE_NODE_TYPE_INTERNAL UINT32_C(0x00000002)
     159#define VCI_TREE_NODE_TYPE_INTERNAL UINT8_C(0x00000001)
    161160/** Node type: Leaf of the tree (VciCacheExtent). */
    162 #define VCI_TREE_NODE_TYPE_LEAF     UINT32_C(0x00000003)
     161#define VCI_TREE_NODE_TYPE_LEAF     UINT8_C(0x00000002)
     162
     163/** Number of cache extents described by one node. */
     164#define VCI_TREE_EXTENTS_PER_NODE        (sizeof(VciTreeNode)-1 / sizeof(VciCacheExtent))
     165/** Number of internal nodes managed by one tree node. */
     166#define VCI_TREE_INTERNAL_NODES_PER_NODE (sizeof(VciTreeNode)-1 / sizeof(VciTreeNodeInternal))
    163167
    164168/**
     
    236240    PVCIBLKRANGEDESC pRangesTail;
    237241
    238     /** Pointer to the block bitmap. */
    239     VciBlkMapEnt *pBlkBitmap;
    240242} VCIBLKMAP;
    241243/** Pointer to a block map. */
    242244typedef VCIBLKMAP *PVCIBLKMAP;
     245
     246/**
     247 * B+-Tree node header.
     248 */
     249typedef struct VCITREENODE
     250{
     251    /** Type of the node (VCI_TREE_NODE_TYPE_*). */
     252    uint8_t             u8Type;
     253    /** Block address where the node is stored. */
     254    uint64_t            u64BlockAddr;
     255    /** Pointer to the parent. */
     256    struct VCITREENODE *pParent;
     257} VCITREENODE, *PVCITREENODE;
     258
     259/**
     260 * B+-Tree node pointer.
     261 */
     262typedef struct VCITREENODEPTR
     263{
     264    /** Flag whether the node is in memory or still on the disk. */
     265    bool         fInMemory;
     266    /** Type dependent data. */
     267    union
     268    {
     269        /** Pointer to a in memory node. */
     270        PVCITREENODE pNode;
     271        /** Start block address of the node. */
     272        uint64_t     offAddrBlockNode;
     273    } u;
     274} VCITREENODEPTR, *PVCITREENODEPTR;
     275
     276/**
     277 * Internal node.
     278 */
     279typedef struct VCINODEINTERNAL
     280{
     281    /** First block of cached data the internal node represents. */
     282    uint64_t       u64BlockOffset;
     283    /** Number of blocks the internal node represents. */
     284    uint32_t       u32Blocks;
     285    /** Pointer to the child node. */
     286    VCITREENODEPTR PtrChild;
     287} VCINODEINTERNAL, *PVCINODEINTERNAL;
     288
     289/**
     290 * A in memory internal B+-tree node.
     291 */
     292typedef struct VCITREENODEINT
     293{
     294    /** Node core. */
     295    VCITREENODE     Core;
     296    /** Number of used nodes. */
     297    unsigned        cUsedNodes;
     298    /** Array of internal nodes. */
     299    VCINODEINTERNAL aIntNodes[VCI_TREE_INTERNAL_NODES_PER_NODE];
     300} VCITREENODEINT, *PVCITREENODEINT;
     301
     302/**
     303 * A in memory cache extent.
     304 */
     305typedef struct VCICACHEEXTENT
     306{
     307    /** First block of cached data the extent represents. */
     308    uint64_t    u64BlockOffset;
     309    /** Number of blocks the extent represents. */
     310    uint32_t    u32Blocks;
     311    /** First block in the image where the data is stored. */
     312    uint64_t    u64BlockAddr;
     313} VCICACHEEXTENT, *PVCICACHEEXTENT;
     314
     315/**
     316 * A in memory leaf B+-tree node.
     317 */
     318typedef struct VCITREENODELEAF
     319{
     320    /** Node core. */
     321    VCITREENODE    Core;
     322    /** Number of used nodes. */
     323    unsigned       cUsedNodes;
     324    /** The extents in the node. */
     325    VCICACHEEXTENT aExtents[VCI_TREE_EXTENTS_PER_NODE];
     326} VCITREENODELEAF, *PVCITREENODELEAF;
    243327
    244328/**
     
    275359    /** Offset of the B+-Tree in the image in bytes. */
    276360    uint64_t          offTreeRoot;
    277     /** @todo Pointer to the root of the tree in memory. */
    278 
    279 
     361    /** Pointer to the root node of the B+-Tree. */
     362    PVCITREENODE      pRoot;
    280363    /** Offset to the block allocation bitmap in bytes. */
    281364    uint64_t          offBlksBitmap;
     
    284367} VCICACHE, *PVCICACHE;
    285368
     369/** No block free in bitmap error code. */
     370#define VERR_VCI_NO_BLOCKS_FREE (-65536)
     371
    286372/*******************************************************************************
    287373*   Static Variables                                                           *
     
    302388 * Internal: signal an error to the frontend.
    303389 */
    304 DECLINLINE(int) vciError(PVCICACHE pImage, int rc, RT_SRC_POS_DECL,
     390DECLINLINE(int) vciError(PVCICACHE pCache, int rc, RT_SRC_POS_DECL,
    305391                         const char *pszFormat, ...)
    306392{
    307393    va_list va;
    308394    va_start(va, pszFormat);
    309     if (pImage->pInterfaceError)
    310         pImage->pInterfaceErrorCallbacks->pfnError(pImage->pInterfaceError->pvUser, rc, RT_SRC_POS_ARGS,
     395    if (pCache->pInterfaceError)
     396        pCache->pInterfaceErrorCallbacks->pfnError(pCache->pInterfaceError->pvUser, rc, RT_SRC_POS_ARGS,
    311397                                                   pszFormat, va);
    312398    va_end(va);
     
    317403 * Internal: signal an informational message to the frontend.
    318404 */
    319 DECLINLINE(int) vciMessage(PVCICACHE pImage, const char *pszFormat, ...)
     405DECLINLINE(int) vciMessage(PVCICACHE pCache, const char *pszFormat, ...)
    320406{
    321407    int rc = VINF_SUCCESS;
    322408    va_list va;
    323409    va_start(va, pszFormat);
    324     if (pImage->pInterfaceError)
    325         rc = pImage->pInterfaceErrorCallbacks->pfnMessage(pImage->pInterfaceError->pvUser,
     410    if (pCache->pInterfaceError)
     411        rc = pCache->pInterfaceErrorCallbacks->pfnMessage(pCache->pInterfaceError->pvUser,
    326412                                                          pszFormat, va);
    327413    va_end(va);
     
    330416
    331417
    332 DECLINLINE(int) vciFileOpen(PVCICACHE pImage, const char *pszFilename,
     418DECLINLINE(int) vciFileOpen(PVCICACHE pCache, const char *pszFilename,
    333419                            uint32_t fOpen)
    334420{
    335     return pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser,
     421    return pCache->pInterfaceIOCallbacks->pfnOpen(pCache->pInterfaceIO->pvUser,
    336422                                                  pszFilename, fOpen,
    337                                                   &pImage->pStorage);
    338 }
    339 
    340 DECLINLINE(int) vciFileClose(PVCICACHE pImage)
    341 {
    342     return pImage->pInterfaceIOCallbacks->pfnClose(pImage->pInterfaceIO->pvUser,
    343                                                    pImage->pStorage);
    344 }
    345 
    346 DECLINLINE(int) vciFileDelete(PVCICACHE pImage, const char *pszFilename)
    347 {
    348     return pImage->pInterfaceIOCallbacks->pfnDelete(pImage->pInterfaceIO->pvUser,
     423                                                  &pCache->pStorage);
     424}
     425
     426DECLINLINE(int) vciFileClose(PVCICACHE pCache)
     427{
     428    return pCache->pInterfaceIOCallbacks->pfnClose(pCache->pInterfaceIO->pvUser,
     429                                                   pCache->pStorage);
     430}
     431
     432DECLINLINE(int) vciFileDelete(PVCICACHE pCache, const char *pszFilename)
     433{
     434    return pCache->pInterfaceIOCallbacks->pfnDelete(pCache->pInterfaceIO->pvUser,
    349435                                                    pszFilename);
    350436}
    351437
    352 DECLINLINE(int) vciFileMove(PVCICACHE pImage, const char *pszSrc,
     438DECLINLINE(int) vciFileMove(PVCICACHE pCache, const char *pszSrc,
    353439                            const char *pszDst, unsigned fMove)
    354440{
    355     return pImage->pInterfaceIOCallbacks->pfnMove(pImage->pInterfaceIO->pvUser,
     441    return pCache->pInterfaceIOCallbacks->pfnMove(pCache->pInterfaceIO->pvUser,
    356442                                                  pszSrc, pszDst, fMove);
    357443}
    358444
    359 DECLINLINE(int) vciFileGetFreeSpace(PVCICACHE pImage, const char *pszFilename,
     445DECLINLINE(int) vciFileGetFreeSpace(PVCICACHE pCache, const char *pszFilename,
    360446                                    int64_t *pcbFree)
    361447{
    362     return pImage->pInterfaceIOCallbacks->pfnGetFreeSpace(pImage->pInterfaceIO->pvUser,
     448    return pCache->pInterfaceIOCallbacks->pfnGetFreeSpace(pCache->pInterfaceIO->pvUser,
    363449                                                          pszFilename, pcbFree);
    364450}
    365451
    366 DECLINLINE(int) vciFileGetSize(PVCICACHE pImage, uint64_t *pcbSize)
    367 {
    368     return pImage->pInterfaceIOCallbacks->pfnGetSize(pImage->pInterfaceIO->pvUser,
    369                                                      pImage->pStorage, pcbSize);
    370 }
    371 
    372 DECLINLINE(int) vciFileSetSize(PVCICACHE pImage, uint64_t cbSize)
    373 {
    374     return pImage->pInterfaceIOCallbacks->pfnSetSize(pImage->pInterfaceIO->pvUser,
    375                                                      pImage->pStorage, cbSize);
    376 }
    377 
    378 DECLINLINE(int) vciFileWriteSync(PVCICACHE pImage, uint64_t uOffset,
     452DECLINLINE(int) vciFileGetSize(PVCICACHE pCache, uint64_t *pcbSize)
     453{
     454    return pCache->pInterfaceIOCallbacks->pfnGetSize(pCache->pInterfaceIO->pvUser,
     455                                                     pCache->pStorage, pcbSize);
     456}
     457
     458DECLINLINE(int) vciFileSetSize(PVCICACHE pCache, uint64_t cbSize)
     459{
     460    return pCache->pInterfaceIOCallbacks->pfnSetSize(pCache->pInterfaceIO->pvUser,
     461                                                     pCache->pStorage, cbSize);
     462}
     463
     464DECLINLINE(int) vciFileWriteSync(PVCICACHE pCache, uint64_t uOffset,
    379465                                 const void *pvBuffer, size_t cbBuffer)
    380466{
    381     return pImage->pInterfaceIOCallbacks->pfnWriteSync(pImage->pInterfaceIO->pvUser,
    382                                                        pImage->pStorage, uOffset,
     467    return pCache->pInterfaceIOCallbacks->pfnWriteSync(pCache->pInterfaceIO->pvUser,
     468                                                       pCache->pStorage, uOffset,
    383469                                                       pvBuffer, cbBuffer, NULL);
    384470}
    385471
    386 DECLINLINE(int) vciFileReadSync(PVCICACHE pImage, uint64_t uOffset,
     472DECLINLINE(int) vciFileReadSync(PVCICACHE pCache, uint64_t uOffset,
    387473                                void *pvBuffer, size_t cbBuffer)
    388474{
    389     return pImage->pInterfaceIOCallbacks->pfnReadSync(pImage->pInterfaceIO->pvUser,
    390                                                       pImage->pStorage, uOffset,
     475    return pCache->pInterfaceIOCallbacks->pfnReadSync(pCache->pInterfaceIO->pvUser,
     476                                                      pCache->pStorage, uOffset,
    391477                                                      pvBuffer, cbBuffer, NULL);
    392478}
    393479
    394 DECLINLINE(int) vciFileFlushSync(PVCICACHE pImage)
    395 {
    396     return pImage->pInterfaceIOCallbacks->pfnFlushSync(pImage->pInterfaceIO->pvUser,
    397                                                        pImage->pStorage);
    398 }
    399 
    400 DECLINLINE(int) vciFileReadUserAsync(PVCICACHE pImage, uint64_t uOffset,
     480DECLINLINE(int) vciFileFlushSync(PVCICACHE pCache)
     481{
     482    return pCache->pInterfaceIOCallbacks->pfnFlushSync(pCache->pInterfaceIO->pvUser,
     483                                                       pCache->pStorage);
     484}
     485
     486DECLINLINE(int) vciFileReadUserAsync(PVCICACHE pCache, uint64_t uOffset,
    401487                                     PVDIOCTX pIoCtx, size_t cbRead)
    402488{
    403     return pImage->pInterfaceIOCallbacks->pfnReadUserAsync(pImage->pInterfaceIO->pvUser,
    404                                                            pImage->pStorage,
     489    return pCache->pInterfaceIOCallbacks->pfnReadUserAsync(pCache->pInterfaceIO->pvUser,
     490                                                           pCache->pStorage,
    405491                                                           uOffset, pIoCtx,
    406492                                                           cbRead);
    407493}
    408494
    409 DECLINLINE(int) vciFileWriteUserAsync(PVCICACHE pImage, uint64_t uOffset,
     495DECLINLINE(int) vciFileWriteUserAsync(PVCICACHE pCache, uint64_t uOffset,
    410496                                      PVDIOCTX pIoCtx, size_t cbWrite,
    411497                                      PFNVDXFERCOMPLETED pfnComplete,
    412498                                      void *pvCompleteUser)
    413499{
    414     return pImage->pInterfaceIOCallbacks->pfnWriteUserAsync(pImage->pInterfaceIO->pvUser,
    415                                                             pImage->pStorage,
     500    return pCache->pInterfaceIOCallbacks->pfnWriteUserAsync(pCache->pInterfaceIO->pvUser,
     501                                                            pCache->pStorage,
    416502                                                            uOffset, pIoCtx,
    417503                                                            cbWrite,
     
    420506}
    421507
    422 DECLINLINE(int) vciFileFlushAsync(PVCICACHE pImage, PVDIOCTX pIoCtx,
     508DECLINLINE(int) vciFileFlushAsync(PVCICACHE pCache, PVDIOCTX pIoCtx,
    423509                                  PFNVDXFERCOMPLETED pfnComplete,
    424510                                  void *pvCompleteUser)
    425511{
    426     return pImage->pInterfaceIOCallbacks->pfnFlushAsync(pImage->pInterfaceIO->pvUser,
    427                                                         pImage->pStorage,
     512    return pCache->pInterfaceIOCallbacks->pfnFlushAsync(pCache->pInterfaceIO->pvUser,
     513                                                        pCache->pStorage,
    428514                                                        pIoCtx, pfnComplete,
    429515                                                        pvCompleteUser);
     
    433519 * Internal. Flush image data to disk.
    434520 */
    435 static int vciFlushImage(PVCICACHE pImage)
     521static int vciFlushImage(PVCICACHE pCache)
    436522{
    437523    int rc = VINF_SUCCESS;
    438524
    439     if (   pImage->pStorage
    440         && !(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    441         rc = vciFileFlushSync(pImage);
    442 
    443     return rc;
    444 }
    445 
    446 /**
    447  * Internal. Free all allocated space for representing an image except pImage,
     525    if (   pCache->pStorage
     526        && !(pCache->uOpenFlags & VD_OPEN_FLAGS_READONLY))
     527        rc = vciFileFlushSync(pCache);
     528
     529    return rc;
     530}
     531
     532/**
     533 * Internal. Free all allocated space for representing an image except pCache,
    448534 * and optionally delete the image from disk.
    449535 */
    450 static int vciFreeImage(PVCICACHE pImage, bool fDelete)
     536static int vciFreeImage(PVCICACHE pCache, bool fDelete)
    451537{
    452538    int rc = VINF_SUCCESS;
     
    454540    /* Freeing a never allocated image (e.g. because the open failed) is
    455541     * not signalled as an error. After all nothing bad happens. */
    456     if (pImage)
    457     {
    458         if (pImage->pStorage)
     542    if (pCache)
     543    {
     544        if (pCache->pStorage)
    459545        {
    460546            /* No point updating the file that is deleted anyway. */
    461547            if (!fDelete)
    462                 vciFlushImage(pImage);
    463 
    464             vciFileClose(pImage);
    465             pImage->pStorage = NULL;
    466         }
    467 
    468         if (fDelete && pImage->pszFilename)
    469             vciFileDelete(pImage, pImage->pszFilename);
     548                vciFlushImage(pCache);
     549
     550            vciFileClose(pCache);
     551            pCache->pStorage = NULL;
     552        }
     553
     554        if (fDelete && pCache->pszFilename)
     555            vciFileDelete(pCache, pCache->pszFilename);
    470556    }
    471557
     
    490576    uint32_t cbBlkMap = RT_ALIGN_Z(cBlocks / sizeof(VciBlkMapEnt) / 8, VCI_BLOCK_SIZE);
    491577    PVCIBLKMAP pBlkMap = (PVCIBLKMAP)RTMemAllocZ(sizeof(VCIBLKMAP));
    492     VciBlkMapEnt *pBlkBitmap = (VciBlkMapEnt *)RTMemAllocZ(cbBlkMap);
    493578    PVCIBLKRANGEDESC pFree   = (PVCIBLKRANGEDESC)RTMemAllocZ(sizeof(VCIBLKRANGEDESC));
    494579
    495580    LogFlowFunc(("cBlocks=%u ppBlkMap=%#p pcBlkMap=%#p\n", cBlocks, ppBlkMap, pcBlkMap));
    496581
    497     if (pBlkMap && pBlkBitmap && pFree)
     582    if (pBlkMap && pFree)
    498583    {
    499584        pBlkMap->cBlocks          = cBlocks;
     
    501586        pBlkMap->cBlocksAllocData = 0;
    502587        pBlkMap->cBlocksFree      = cBlocks;
    503         pBlkMap->pBlkBitmap       = pBlkBitmap;
    504588
    505589        pFree->pPrev = NULL;
     
    520604        if (pBlkMap)
    521605            RTMemFree(pBlkMap);
    522         if (pBlkBitmap)
    523             RTMemFree(pBlkBitmap);
    524606        if (pFree)
    525607            RTMemFree(pFree);
     
    553635    }
    554636
    555     RTMemFree(pBlkMap->pBlkBitmap);
    556637    RTMemFree(pBlkMap);
    557638
     
    581662        cBlkMap -= VCI_BYTE2BLOCK(sizeof(VciBlkMap));
    582663
    583         rc = vciFileReadSync(pStorage, offBlkMap, &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
     664        rc = vciFileReadSync(pStorage, VCI_BLOCK2BYTE(offBlkMap), &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
    584665        if (RT_SUCCESS(rc))
    585666        {
     
    606687                    pBlkMap->cBlocksAllocData = BlkMap.cBlocksAllocData;
    607688
    608                     pBlkMap->pBlkBitmap = (VciBlkMapEnt *)RTMemAllocZ(pBlkMap->cBlocks / 8);
    609                     if (pBlkMap->pBlkBitmap)
     689                    /* Load the bitmap and construct the range list. */
     690                    uint32_t cBlocksFree = 0;
     691                    uint32_t cBlocksAllocated = 0;
     692                    PVCIBLKRANGEDESC pRangeCur = (PVCIBLKRANGEDESC)RTMemAllocZ(sizeof(VCIBLKRANGEDESC));
     693
     694                    if (pRangeCur)
    610695                    {
    611                         rc = vciFileReadSync(pStorage, offBlkMap, pBlkMap->pBlkBitmap, cBlkMap);
     696                        uint8_t abBitmapBuffer[16 * _1K];
     697                        uint32_t cBlocksRead = 0;
     698                        int iBit = 0;
     699                        uint64_t cBlocksLeft = pBlkMap->cBlocks;
     700
     701                        cBlocksRead = RT_MIN(VCI_BYTE2BLOCK(sizeof(abBitmapBuffer)), cBlocksLeft);
     702                        rc = vciFileReadSync(pStorage, VCI_BLOCK2BYTE(offBlkMap), abBitmapBuffer,
     703                                             VCI_BLOCK2BYTE(cBlocksRead));
     704
    612705                        if (RT_SUCCESS(rc))
    613706                        {
    614                             *ppBlkMap = pBlkMap;
    615                             LogFlowFunc(("return success\n"));
    616                             return VINF_SUCCESS;
     707                            pRangeCur->fFree        = !(abBitmapBuffer[0] & 0x01);
     708                            pRangeCur->offAddrStart = 0;
     709                            pRangeCur->cBlocks      = 0;
     710                            pRangeCur->pNext        = NULL;
     711                            pRangeCur->pPrev        = NULL;
     712                            pBlkMap->pRangesHead = pRangeCur;
     713                            pBlkMap->pRangesTail = pRangeCur;
    617714                        }
    618715
    619                         RTMemFree(pBlkMap->pBlkBitmap);
     716                        while (   RT_SUCCESS(rc)
     717                               && cBlocksLeft)
     718                        {
     719                            while (cBlocksRead)
     720                            {
     721                                if (pRangeCur->fFree)
     722                                {
     723                                    /* Check for the first set bit. */
     724                                }
     725                                else
     726                                {
     727                                    /* Check for the first free bit. */
     728                                }
     729
     730                                if (iBit == -1)
     731                                {
     732                                    /* No change. */
     733                                    pRangeCur->cBlocks += cBlocksRead;
     734                                    cBlocksRead = 0;
     735                                }
     736                                else
     737                                {
     738                                    /* Create a new range descriptor. */
     739                                }
     740                            }
     741                            cBlocksLeft -= cBlocksRead;
     742                            offBlkMap   += cBlocksRead;
     743
     744                            if (cBlocksLeft)
     745                            {
     746                                /* Read next chunk. */
     747                            }
     748                        }
    620749                    }
    621750                    else
    622751                        rc = VERR_NO_MEMORY;
    623752
    624                     RTMemFree(pBlkMap);
     753                    if (RT_SUCCESS(rc))
     754                    {
     755                        *ppBlkMap = pBlkMap;
     756                        LogFlowFunc(("return success\n"));
     757                        return VINF_SUCCESS;
     758                    }
     759                    else
     760                        RTMemFree(pBlkMap);
    625761                }
    626762                else
     
    671807        BlkMap.cBlocksAllocData = RT_H2LE_U32(pBlkMap->cBlocksAllocData);
    672808
    673         rc = vciFileWriteSync(pStorage, offBlkMap, &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
     809        rc = vciFileWriteSync(pStorage, VCI_BLOCK2BYTE(offBlkMap), &BlkMap, VCI_BYTE2BLOCK(sizeof(VciBlkMap)));
    674810        if (RT_SUCCESS(rc))
    675811        {
     812            uint8_t abBitmapBuffer[16*_1K];
     813            unsigned iBit = 0;
     814            PVCIBLKRANGEDESC pCur = pBlkMap->pRangesHead;
     815
    676816            offBlkMap += VCI_BYTE2BLOCK(sizeof(VciBlkMap));
    677             rc = vciFileWriteSync(pStorage, offBlkMap, pBlkMap->pBlkBitmap, pBlkMap->cBlocks / 8);
     817
     818            /* Write the descriptor ranges. */
     819            while (pCur)
     820            {
     821                uint64_t cBlocks = pCur->cBlocks;
     822
     823                while (cBlocks)
     824                {
     825                    uint64_t cBlocksMax = RT_MIN(cBlocks, sizeof(abBitmapBuffer) * 8 - iBit);
     826
     827                    if (pCur->fFree)
     828                        ASMBitClearRange(abBitmapBuffer, iBit, iBit + cBlocksMax);
     829                    else
     830                        ASMBitSetRange(abBitmapBuffer, iBit, iBit + cBlocksMax);
     831
     832                    iBit    += cBlocksMax;
     833                    cBlocks -= cBlocksMax;
     834
     835                    if (iBit == sizeof(abBitmapBuffer) * 8)
     836                    {
     837                        /* Buffer is full, write to file and reset. */
     838                        rc = vciFileWriteSync(pStorage, offBlkMap, abBitmapBuffer, sizeof(abBitmapBuffer));
     839                        if (RT_FAILURE(rc))
     840                            break;
     841
     842                        offBlkMap += VCI_BYTE2BLOCK(sizeof(abBitmapBuffer));
     843                        iBit = 0;
     844                    }
     845                }
     846
     847                pCur = pCur->pNext;
     848            }
     849
     850            Assert(iBit % 8 == 0);
     851
     852            if (RT_SUCCESS(rc) && iBit)
     853                rc = vciFileWriteSync(pStorage, offBlkMap, abBitmapBuffer, iBit / 8);
    678854        }
    679855    }
     
    683859    LogFlowFunc(("returns rc=%Rrc\n", rc));
    684860    return rc;
     861}
     862
     863/**
     864 * Finds the range block describing the given block address.
     865 *
     866 * @returns Pointer to the block range descriptor or NULL if none could be found.
     867 * @param   pBlkMap         The block bitmap to search on.
     868 * @param   offBlockAddr    The block address to search for.
     869 */
     870static PVCIBLKRANGEDESC vciBlkMapFindByBlock(PVCIBLKMAP pBlkMap, uint64_t offBlockAddr)
     871{
     872    PVCIBLKRANGEDESC pBlk = pBlkMap->pRangesHead;
     873
     874    while (   pBlk
     875           && pBlk->offAddrStart < offBlockAddr)
     876        pBlk = pBlk->pNext;
     877
     878    return pBlk;
    685879}
    686880
     
    695889static int vciBlkMapAllocate(PVCIBLKMAP pBlkMap, uint32_t cBlocks, uint64_t *poffBlockAddr)
    696890{
     891    PVCIBLKRANGEDESC pBestFit = NULL;
     892    PVCIBLKRANGEDESC pCur = NULL;
    697893    int rc = VINF_SUCCESS;
    698894
    699895    LogFlowFunc(("pBlkMap=%#p cBlocks=%u poffBlockAddr=%#p\n",
    700896                 pBlkMap, cBlocks, poffBlockAddr));
     897
     898    pCur = pBlkMap->pRangesHead;
     899
     900    while (pCur)
     901    {
     902        if (   pCur->fFree
     903            && pCur->cBlocks >= cBlocks)
     904        {
     905            if (   !pBestFit
     906                || pCur->cBlocks < pBestFit->cBlocks)
     907            {
     908                pBestFit = pCur;
     909                /* Stop searching if the size is matching exactly. */
     910                if (pBestFit->cBlocks == cBlocks)
     911                    break;
     912            }
     913        }
     914        pCur = pCur->pNext;
     915    }
     916
     917    Assert(!pBestFit || pBestFit->fFree);
     918
     919    if (pBestFit)
     920    {
     921        pBestFit->fFree = false;
     922
     923        if (pBestFit->cBlocks > cBlocks)
     924        {
     925            /* Create a new free block. */
     926            PVCIBLKRANGEDESC pFree = (PVCIBLKRANGEDESC)RTMemAllocZ(sizeof(VCIBLKRANGEDESC));
     927
     928            if (pFree)
     929            {
     930                pFree->fFree = true;
     931                pFree->cBlocks = pBestFit->cBlocks - cBlocks;
     932                pFree->offAddrStart = pBestFit->offAddrStart + cBlocks;
     933
     934                /* Link into the list. */
     935                pFree->pNext = pBestFit->pNext;
     936                pBestFit->pNext = pFree;
     937                pFree->pPrev    = pBestFit;
     938                if (!pFree->pNext)
     939                    pBlkMap->pRangesTail = pFree;
     940
     941                *poffBlockAddr = pBestFit->offAddrStart;
     942            }
     943            else
     944            {
     945                rc = VERR_NO_MEMORY;
     946                pBestFit->fFree = true;
     947            }
     948        }
     949    }
     950    else
     951        rc = VERR_VCI_NO_BLOCKS_FREE;
    701952
    702953    LogFlowFunc(("returns rc=%Rrc offBlockAddr=%llu\n", rc, *poffBlockAddr));
     
    721972                 pBlkMap, cBlocksNew, offBlockAddrOld, poffBlockAddr));
    722973
     974    AssertMsgFailed(("Implement\n"));
     975
    723976    LogFlowFunc(("returns rc=%Rrc offBlockAddr=%llu\n", rc, *poffBlockAddr));
    724977    return rc;
     
    735988static void vciBlkMapFree(PVCIBLKMAP pBlkMap, uint64_t offBlockAddr, uint32_t cBlocks)
    736989{
     990    PVCIBLKRANGEDESC pBlk;
     991
    737992    LogFlowFunc(("pBlkMap=%#p offBlockAddr=%llu cBlocks=%u\n",
    738993                 pBlkMap, offBlockAddr, cBlocks));
    739994
     995    while (cBlocks)
     996    {
     997        pBlk = vciBlkMapFindByBlock(pBlkMap, offBlockAddr);
     998        AssertPtr(pBlk);
     999
     1000        /* Easy case, the whole block is freed. */
     1001        if (   pBlk->offAddrStart == offBlockAddr
     1002            && pBlk->cBlocks <= cBlocks)
     1003        {
     1004            pBlk->fFree = true;
     1005            cBlocks      -= pBlk->cBlocks;
     1006            offBlockAddr += pBlk->cBlocks;
     1007
     1008            /* Check if it is possible to merge free blocks. */
     1009            if (   pBlk->pPrev
     1010                && pBlk->pPrev->fFree)
     1011            {
     1012                PVCIBLKRANGEDESC pBlkPrev = pBlk->pPrev;
     1013
     1014                Assert(pBlkPrev->offAddrStart + pBlkPrev->cBlocks == pBlk->offAddrStart);
     1015                pBlkPrev->cBlocks += pBlk->cBlocks;
     1016                pBlkPrev->pNext = pBlk->pNext;
     1017                if (pBlk->pNext)
     1018                    pBlk->pNext->pPrev = pBlkPrev;
     1019                else
     1020                    pBlkMap->pRangesTail = pBlkPrev;
     1021
     1022                RTMemFree(pBlk);
     1023                pBlk = pBlkPrev;
     1024            }
     1025
     1026            /* Now the one to the right. */
     1027            if (   pBlk->pNext
     1028                && pBlk->pNext->fFree)
     1029            {
     1030                PVCIBLKRANGEDESC pBlkNext = pBlk->pNext;
     1031
     1032                Assert(pBlk->offAddrStart + pBlk->cBlocks == pBlkNext->offAddrStart);
     1033                pBlk->cBlocks += pBlkNext->cBlocks;
     1034                pBlk->pNext = pBlkNext->pNext;
     1035                if (pBlkNext->pNext)
     1036                    pBlkNext->pNext->pPrev = pBlk;
     1037                else
     1038                    pBlkMap->pRangesTail = pBlk;
     1039
     1040                RTMemFree(pBlkNext);
     1041            }
     1042        }
     1043        else
     1044        {
     1045            /* The block is intersecting. */
     1046            AssertMsgFailed(("TODO\n"));
     1047        }
     1048    }
     1049
    7401050    LogFlowFunc(("returns\n"));
    7411051}
    7421052
    7431053/**
     1054 * Converts a tree node from the image to the in memory structure.
     1055 *
     1056 * @returns Pointer to the in memory tree node.
     1057 * @param   offBlockAddrNode    Block address of the node.
     1058 * @param   pNodeImage          Pointer to the image representation of the node.
     1059 */
     1060static PVCITREENODE vciTreeNodeImage2Host(uint64_t offBlockAddrNode, PVciTreeNode pNodeImage)
     1061{
     1062    PVCITREENODE pNode = NULL;
     1063
     1064    if (pNodeImage->u8Type == VCI_TREE_NODE_TYPE_LEAF)
     1065    {
     1066        PVCITREENODELEAF pLeaf = (PVCITREENODELEAF)RTMemAllocZ(sizeof(VCITREENODELEAF));
     1067
     1068        if (pLeaf)
     1069        {
     1070            PVciCacheExtent pExtent = (PVciCacheExtent)&pNodeImage->au8Data[0];
     1071
     1072            pLeaf->Core.u8Type = VCI_TREE_NODE_TYPE_LEAF;
     1073
     1074            for (unsigned idx = 0; idx < RT_ELEMENTS(pLeaf->aExtents); idx++)
     1075            {
     1076                pLeaf->aExtents[idx].u64BlockOffset = RT_LE2H_U64(pExtent->u64BlockOffset);
     1077                pLeaf->aExtents[idx].u32Blocks      = RT_LE2H_U32(pExtent->u32Blocks);
     1078                pLeaf->aExtents[idx].u64BlockAddr   = RT_LE2H_U64(pExtent->u64BlockAddr);
     1079                pExtent++;
     1080
     1081                if (   pLeaf->aExtents[idx].u32Blocks
     1082                    && pLeaf->aExtents[idx].u64BlockAddr)
     1083                    pLeaf->cUsedNodes++;
     1084            }
     1085
     1086            pNode = &pLeaf->Core;
     1087        }
     1088    }
     1089    else if (pNodeImage->u8Type == VCI_TREE_NODE_TYPE_INTERNAL)
     1090    {
     1091        PVCITREENODEINT pInt = (PVCITREENODEINT)RTMemAllocZ(sizeof(VCITREENODEINT));
     1092
     1093        if (pInt)
     1094        {
     1095            PVciTreeNodeInternal pIntImage = (PVciTreeNodeInternal)&pNodeImage->au8Data[0];
     1096
     1097            pInt->Core.u8Type = VCI_TREE_NODE_TYPE_INTERNAL;
     1098
     1099            for (unsigned idx = 0; idx < RT_ELEMENTS(pInt->aIntNodes); idx++)
     1100            {
     1101                pInt->aIntNodes[idx].u64BlockOffset              = RT_LE2H_U64(pIntImage->u64BlockOffset);
     1102                pInt->aIntNodes[idx].u32Blocks                   = RT_LE2H_U32(pIntImage->u32Blocks);
     1103                pInt->aIntNodes[idx].PtrChild.fInMemory          = false;
     1104                pInt->aIntNodes[idx].PtrChild.u.offAddrBlockNode = RT_LE2H_U64(pIntImage->u64ChildAddr);
     1105                pIntImage++;
     1106
     1107                if (   pInt->aIntNodes[idx].u32Blocks
     1108                    && pInt->aIntNodes[idx].PtrChild.u.offAddrBlockNode)
     1109                    pInt->cUsedNodes++;
     1110            }
     1111
     1112            pNode = &pInt->Core;
     1113        }
     1114    }
     1115    else
     1116        AssertMsgFailed(("Invalid node type %d\n", pNodeImage->u8Type));
     1117
     1118    if (pNode)
     1119        pNode->u64BlockAddr = offBlockAddrNode;
     1120
     1121    return pNode;
     1122}
     1123
     1124/**
     1125 * Looks up the cache extent for the given virtual block address.
     1126 *
     1127 * @returns Pointer to the cache extent or NULL if none could be found.
     1128 * @param   pCache         The cache image instance.
     1129 * @param   offBlockOffset The block offset to search for.
     1130 */
     1131static PVCICACHEEXTENT vciCacheExtentLookup(PVCICACHE pCache, uint64_t offBlockOffset)
     1132{
     1133    int rc = VINF_SUCCESS;
     1134    PVCICACHEEXTENT pExtent = NULL;
     1135    PVCITREENODE pNodeCur = pCache->pRoot;
     1136
     1137    while (   RT_SUCCESS(rc)
     1138           && pNodeCur
     1139           && pNodeCur->u8Type != VCI_TREE_NODE_TYPE_LEAF)
     1140    {
     1141        PVCITREENODEINT pNodeInt = (PVCITREENODEINT)pNodeCur;
     1142
     1143        Assert(pNodeCur->u8Type == VCI_TREE_NODE_TYPE_INTERNAL);
     1144
     1145        /* Search for the correct internal node. */
     1146        unsigned idxMin = 0;
     1147        unsigned idxMax = pNodeInt->cUsedNodes;
     1148        unsigned idxCur = pNodeInt->cUsedNodes / 2;
     1149
     1150        while (idxMin < idxMax)
     1151        {
     1152            PVCINODEINTERNAL pInt = &pNodeInt->aIntNodes[idxCur];
     1153
     1154            /* Determine the search direction. */
     1155            if (offBlockOffset < pInt->u64BlockOffset)
     1156            {
     1157                /* Search left from the current extent. */
     1158                idxMax = idxCur;
     1159            }
     1160            else if (offBlockOffset >= pInt->u64BlockOffset + pInt->u32Blocks)
     1161            {
     1162                /* Search right from the current extent. */
     1163                idxMin = idxCur;
     1164            }
     1165            else
     1166            {
     1167                /* The block lies in the node, stop searching. */
     1168                if (pInt->PtrChild.fInMemory)
     1169                    pNodeCur = pInt->PtrChild.u.pNode;
     1170                else
     1171                {
     1172                    PVCITREENODE pNodeNew;
     1173                    VciTreeNode NodeTree;
     1174
     1175                    /* Read from disk and add to the tree. */
     1176                    rc = vciFileReadSync(pCache, VCI_BLOCK2BYTE(pInt->PtrChild.u.offAddrBlockNode),
     1177                                         &NodeTree, sizeof(NodeTree));
     1178                    AssertRC(rc);
     1179
     1180                    pNodeNew = vciTreeNodeImage2Host(pInt->PtrChild.u.offAddrBlockNode, &NodeTree);
     1181                    if (pNodeNew)
     1182                    {
     1183                        /* Link to the parent. */
     1184                        pInt->PtrChild.fInMemory = true;
     1185                        pInt->PtrChild.u.pNode = pNodeNew;
     1186                        pNodeNew->pParent = pNodeCur;
     1187                        pNodeCur = pNodeNew;
     1188                    }
     1189                    else
     1190                        rc = VERR_NO_MEMORY;
     1191                }
     1192                break;
     1193            }
     1194
     1195            idxCur = idxMin + (idxMax - idxMin) / 2;
     1196        }
     1197    }
     1198
     1199    if (   RT_SUCCESS(rc)
     1200        && pNodeCur)
     1201    {
     1202        PVCITREENODELEAF pLeaf = (PVCITREENODELEAF)pNodeCur;
     1203        Assert(pNodeCur->u8Type == VCI_TREE_NODE_TYPE_LEAF);
     1204
     1205        /* Search the range. */
     1206        unsigned idxMin = 0;
     1207        unsigned idxMax = pLeaf->cUsedNodes;
     1208        unsigned idxCur = pLeaf->cUsedNodes / 2;
     1209
     1210        while (idxMin < idxMax)
     1211        {
     1212            PVCICACHEEXTENT pExtentCur = &pLeaf->aExtents[idxCur];
     1213
     1214            /* Determine the search direction. */
     1215            if (offBlockOffset < pExtentCur->u64BlockOffset)
     1216            {
     1217                /* Search left from the current extent. */
     1218                idxMax = idxCur;
     1219            }
     1220            else if (offBlockOffset >= pExtentCur->u64BlockOffset + pExtentCur->u32Blocks)
     1221            {
     1222                /* Search right from the current extent. */
     1223                idxMin = idxCur;
     1224            }
     1225            else
     1226            {
     1227                /* We found the extent, stop searching. */
     1228                pExtent = pExtentCur;
     1229                break;
     1230            }
     1231
     1232            idxCur = idxMin + (idxMax - idxMin) / 2;
     1233        }
     1234    }
     1235
     1236    return pExtent;
     1237}
     1238
     1239/**
    7441240 * Internal: Open an image, constructing all necessary data structures.
    7451241 */
    746 static int vciOpenImage(PVCICACHE pImage, unsigned uOpenFlags)
    747 {
     1242static int vciOpenImage(PVCICACHE pCache, unsigned uOpenFlags)
     1243{
     1244    VciHdr Hdr;
     1245    uint64_t cbFile;
    7481246    int rc;
    7491247
    750     pImage->uOpenFlags = uOpenFlags;
    751 
    752     pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR);
    753     if (pImage->pInterfaceError)
    754         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
     1248    pCache->uOpenFlags = uOpenFlags;
     1249
     1250    pCache->pInterfaceError = VDInterfaceGet(pCache->pVDIfsDisk, VDINTERFACETYPE_ERROR);
     1251    if (pCache->pInterfaceError)
     1252        pCache->pInterfaceErrorCallbacks = VDGetInterfaceError(pCache->pInterfaceError);
    7551253
    7561254    /* Get I/O interface. */
    757     pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsImage, VDINTERFACETYPE_IOINT);
    758     AssertPtrReturn(pImage->pInterfaceIO, VERR_INVALID_PARAMETER);
    759     pImage->pInterfaceIOCallbacks = VDGetInterfaceIOInt(pImage->pInterfaceIO);
    760     AssertPtrReturn(pImage->pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
     1255    pCache->pInterfaceIO = VDInterfaceGet(pCache->pVDIfsImage, VDINTERFACETYPE_IOINT);
     1256    AssertPtrReturn(pCache->pInterfaceIO, VERR_INVALID_PARAMETER);
     1257    pCache->pInterfaceIOCallbacks = VDGetInterfaceIOInt(pCache->pInterfaceIO);
     1258    AssertPtrReturn(pCache->pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
    7611259
    7621260    /*
    7631261     * Open the image.
    7641262     */
    765     rc = vciFileOpen(pImage, pImage->pszFilename,
     1263    rc = vciFileOpen(pCache, pCache->pszFilename,
    7661264                     VDOpenFlagsToFileOpenFlags(uOpenFlags,
    7671265                                                false /* fCreate */));
     
    7731271    }
    7741272
    775     rc = vciFileGetSize(pImage, &pImage->cbSize);
     1273    rc = vciFileGetSize(pCache, &cbFile);
     1274    if (RT_FAILURE(rc) || cbFile < sizeof(VciHdr))
     1275    {
     1276        rc = VERR_VD_GEN_INVALID_HEADER;
     1277        goto out;
     1278    }
     1279
     1280    rc = vciFileReadSync(pCache, 0, &Hdr, sizeof(Hdr));
    7761281    if (RT_FAILURE(rc))
     1282    {
     1283        rc = VERR_VD_GEN_INVALID_HEADER;
    7771284        goto out;
    778     if (pImage->cbSize % 512)
    779     {
    780         rc = VERR_VD_RAW_INVALID_HEADER;
    781         goto out;
    782     }
    783     pImage->uImageFlags |= VD_IMAGE_FLAGS_FIXED;
     1285    }
     1286
     1287    Hdr.u32Signature = RT_LE2H_U32(Hdr.u32Signature);
     1288    Hdr.u32Version   = RT_LE2H_U32(Hdr.u32Version);
     1289    Hdr.cBlocksCache = RT_LE2H_U64(Hdr.cBlocksCache);
     1290    Hdr.u32CacheType = RT_LE2H_U32(Hdr.u32CacheType);
     1291    Hdr.offTreeRoot  = RT_LE2H_U64(Hdr.offTreeRoot);
     1292    Hdr.offBlkMap    = RT_LE2H_U64(Hdr.offBlkMap);
     1293    Hdr.cBlkMap      = RT_LE2H_U64(Hdr.cBlkMap);
     1294
     1295    if (   Hdr.u32Signature == VCI_HDR_SIGNATURE
     1296        && Hdr.u32Version == VCI_HDR_VERSION)
     1297    {
     1298        pCache->offTreeRoot   = Hdr.offTreeRoot;
     1299        pCache->offBlksBitmap = Hdr.offBlkMap;
     1300
     1301        /* Load the block map. */
     1302        rc = vciBlkMapLoad(pCache, VCI_BLOCK2BYTE(pCache->offBlksBitmap), Hdr.cBlkMap, &pCache->pBlkMap);
     1303        if (RT_SUCCESS(rc))
     1304        {
     1305            /* Load the first tree node. */
     1306            VciTreeNode RootNode;
     1307
     1308            rc = vciFileReadSync(pCache, VCI_BLOCK2BYTE(pCache->offTreeRoot), &RootNode, sizeof(VciTreeNode));
     1309            if (RT_SUCCESS(rc))
     1310            {
     1311                pCache->pRoot = vciTreeNodeImage2Host(pCache->offTreeRoot, &RootNode);
     1312                if (!pCache->pRoot)
     1313                    rc = VERR_NO_MEMORY;
     1314            }
     1315        }
     1316    }
     1317    else
     1318        rc = VERR_VD_GEN_INVALID_HEADER;
    7841319
    7851320out:
    7861321    if (RT_FAILURE(rc))
    787         vciFreeImage(pImage, false);
     1322        vciFreeImage(pCache, false);
    7881323    return rc;
    7891324}
     
    7921327 * Internal: Create a vci image.
    7931328 */
    794 static int vciCreateImage(PVCICACHE pImage, uint64_t cbSize,
     1329static int vciCreateImage(PVCICACHE pCache, uint64_t cbSize,
    7951330                          unsigned uImageFlags, const char *pszComment,
    7961331                          unsigned uOpenFlags, PFNVDPROGRESS pfnProgress,
     
    8051340    if (uImageFlags & VD_IMAGE_FLAGS_DIFF)
    8061341    {
    807         rc = vciError(pImage, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("VCI: cannot create diff image '%s'"), pImage->pszFilename);
     1342        rc = vciError(pCache, VERR_VD_RAW_INVALID_TYPE, RT_SRC_POS, N_("VCI: cannot create diff image '%s'"), pCache->pszFilename);
    8081343        return rc;
    8091344    }
    8101345
    811     pImage->uImageFlags = uImageFlags;
    812 
    813     pImage->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY;
    814 
    815     pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR);
    816     if (pImage->pInterfaceError)
    817         pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError);
    818 
    819     pImage->pInterfaceIO = VDInterfaceGet(pImage->pVDIfsImage, VDINTERFACETYPE_IOINT);
    820     AssertPtrReturn(pImage->pInterfaceIO, VERR_INVALID_PARAMETER);
    821     pImage->pInterfaceIOCallbacks = VDGetInterfaceIOInt(pImage->pInterfaceIO);
    822     AssertPtrReturn(pImage->pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
     1346    pCache->uImageFlags = uImageFlags;
     1347
     1348    pCache->uOpenFlags = uOpenFlags & ~VD_OPEN_FLAGS_READONLY;
     1349
     1350    pCache->pInterfaceError = VDInterfaceGet(pCache->pVDIfsDisk, VDINTERFACETYPE_ERROR);
     1351    if (pCache->pInterfaceError)
     1352        pCache->pInterfaceErrorCallbacks = VDGetInterfaceError(pCache->pInterfaceError);
     1353
     1354    pCache->pInterfaceIO = VDInterfaceGet(pCache->pVDIfsImage, VDINTERFACETYPE_IOINT);
     1355    AssertPtrReturn(pCache->pInterfaceIO, VERR_INVALID_PARAMETER);
     1356    pCache->pInterfaceIOCallbacks = VDGetInterfaceIOInt(pCache->pInterfaceIO);
     1357    AssertPtrReturn(pCache->pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
    8231358
    8241359    do
    8251360    {
    8261361        /* Create image file. */
    827         rc = vciFileOpen(pImage, pImage->pszFilename,
     1362        rc = vciFileOpen(pCache, pCache->pszFilename,
    8281363                         VDOpenFlagsToFileOpenFlags(uOpenFlags & ~VD_OPEN_FLAGS_READONLY,
    8291364                                                    true /* fCreate */));
    8301365        if (RT_FAILURE(rc))
    8311366        {
    832             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot create image '%s'"), pImage->pszFilename);
     1367            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot create image '%s'"), pCache->pszFilename);
    8331368            break;
    8341369        }
     
    8361371        /* Allocate block bitmap. */
    8371372        uint32_t cBlkMap = 0;
    838         rc = vciBlkMapCreate(cBlocks, &pImage->pBlkMap, &cBlkMap);
     1373        rc = vciBlkMapCreate(cBlocks, &pCache->pBlkMap, &cBlkMap);
    8391374        if (RT_FAILURE(rc))
    8401375        {
    841             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot create block bitmap '%s'"), pImage->pszFilename);
     1376            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot create block bitmap '%s'"), pCache->pszFilename);
    8421377            break;
    8431378        }
     
    8481383         */
    8491384        uint64_t offHdr = 0;
    850         rc = vciBlkMapAllocate(pImage->pBlkMap, VCI_BYTE2BLOCK(sizeof(VciHdr)), &offHdr);
     1385        rc = vciBlkMapAllocate(pCache->pBlkMap, VCI_BYTE2BLOCK(sizeof(VciHdr)), &offHdr);
    8511386        if (RT_FAILURE(rc))
    8521387        {
    853             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot allocate space for header in block bitmap '%s'"), pImage->pszFilename);
     1388            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot allocate space for header in block bitmap '%s'"), pCache->pszFilename);
    8541389            break;
    8551390        }
     
    8611396         */
    8621397        uint64_t offBlkMap = 0;
    863         rc = vciBlkMapAllocate(pImage->pBlkMap, cBlkMap, &offBlkMap);
     1398        rc = vciBlkMapAllocate(pCache->pBlkMap, cBlkMap, &offBlkMap);
    8641399        if (RT_FAILURE(rc))
    8651400        {
    866             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot allocate space for block map in block map '%s'"), pImage->pszFilename);
     1401            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot allocate space for block map in block map '%s'"), pCache->pszFilename);
    8671402            break;
    8681403        }
     
    8721407         */
    8731408        uint64_t offTreeRoot = 0;
    874         rc = vciBlkMapAllocate(pImage->pBlkMap, VCI_BYTE2BLOCK(sizeof(VciTreeNode)), &offTreeRoot);
     1409        rc = vciBlkMapAllocate(pCache->pBlkMap, VCI_BYTE2BLOCK(sizeof(VciTreeNode)), &offTreeRoot);
    8751410        if (RT_FAILURE(rc))
    8761411        {
    877             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot allocate space for block map in block map '%s'"), pImage->pszFilename);
     1412            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot allocate space for block map in block map '%s'"), pCache->pszFilename);
    8781413            break;
    8791414        }
     1415
     1416        /*
     1417         * Allocate the in memory root node.
     1418         */
     1419        pCache->pRoot = (PVCITREENODE)RTMemAllocZ(sizeof(VCITREENODELEAF));
     1420        if (!pCache->pRoot)
     1421        {
     1422            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot allocate B+-Tree root pointer '%s'"), pCache->pszFilename);
     1423            break;
     1424        }
     1425
     1426        pCache->pRoot->u8Type = VCI_TREE_NODE_TYPE_LEAF;
     1427        /* Rest remains 0 as the tree is still empty. */
    8801428
    8811429        /*
     
    8971445        Hdr.cBlkMap          = RT_H2LE_U64(cBlkMap);
    8981446
    899         rc = vciFileWriteSync(pImage, offHdr, &Hdr, VCI_BYTE2BLOCK(sizeof(VciHdr)));
     1447        rc = vciFileWriteSync(pCache, offHdr, &Hdr, VCI_BYTE2BLOCK(sizeof(VciHdr)));
    9001448        if (RT_FAILURE(rc))
    9011449        {
    902             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot write header '%s'"), pImage->pszFilename);
     1450            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot write header '%s'"), pCache->pszFilename);
    9031451            break;
    9041452        }
    9051453
    906         rc = vciBlkMapSave(pImage->pBlkMap, pImage, offBlkMap, cBlkMap);
     1454        rc = vciBlkMapSave(pCache->pBlkMap, pCache, offBlkMap, cBlkMap);
    9071455        if (RT_FAILURE(rc))
    9081456        {
    909             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot write block map '%s'"), pImage->pszFilename);
     1457            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot write block map '%s'"), pCache->pszFilename);
    9101458            break;
    9111459        }
     
    9131461        /* Setup the root tree. */
    9141462        memset(&NodeRoot, 0, sizeof(VciTreeNode));
    915         NodeRoot.u8Type = RT_H2LE_U32(VCI_TREE_NODE_TYPE_ROOT);
    916 
    917         rc = vciFileWriteSync(pImage, offTreeRoot, &NodeRoot, VCI_BYTE2BLOCK(sizeof(VciTreeNode)));
     1463        NodeRoot.u8Type = RT_H2LE_U32(VCI_TREE_NODE_TYPE_LEAF);
     1464
     1465        rc = vciFileWriteSync(pCache, offTreeRoot, &NodeRoot, VCI_BYTE2BLOCK(sizeof(VciTreeNode)));
    9181466        if (RT_FAILURE(rc))
    9191467        {
    920             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot write root node '%s'"), pImage->pszFilename);
     1468            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot write root node '%s'"), pCache->pszFilename);
    9211469            break;
    9221470        }
    9231471
    924         rc = vciFlushImage(pImage);
     1472        rc = vciFlushImage(pCache);
    9251473        if (RT_FAILURE(rc))
    9261474        {
    927             rc = vciError(pImage, rc, RT_SRC_POS, N_("VCI: cannot flush '%s'"), pImage->pszFilename);
     1475            rc = vciError(pCache, rc, RT_SRC_POS, N_("VCI: cannot flush '%s'"), pCache->pszFilename);
    9281476            break;
    9291477        }
    9301478
    931         pImage->cbSize = cbSize;
     1479        pCache->cbSize = cbSize;
    9321480
    9331481    } while (0);
     
    9371485
    9381486    if (RT_FAILURE(rc))
    939         vciFreeImage(pImage, rc != VERR_ALREADY_EXISTS);
     1487        vciFreeImage(pCache, rc != VERR_ALREADY_EXISTS);
    9401488    return rc;
    9411489}
     
    9451493                    PVDINTERFACE pVDIfsImage)
    9461494{
     1495    VciHdr Hdr;
     1496    PVDIOSTORAGE pStorage;
     1497    uint64_t cbFile;
     1498    int rc = VINF_SUCCESS;
     1499
    9471500    LogFlowFunc(("pszFilename=\"%s\"\n", pszFilename));
    948     int rc = VINF_SUCCESS;
    949 
    950     if (   !VALID_PTR(pszFilename)
    951         || !*pszFilename)
    952     {
    953         rc = VERR_INVALID_PARAMETER;
     1501
     1502    /* Get I/O interface. */
     1503    PVDINTERFACE pInterfaceIO = VDInterfaceGet(pVDIfsImage, VDINTERFACETYPE_IOINT);
     1504    AssertPtrReturn(pInterfaceIO, VERR_INVALID_PARAMETER);
     1505    PVDINTERFACEIOINT pInterfaceIOCallbacks = VDGetInterfaceIOInt(pInterfaceIO);
     1506    AssertPtrReturn(pInterfaceIOCallbacks, VERR_INVALID_PARAMETER);
     1507
     1508    rc = pInterfaceIOCallbacks->pfnOpen(pInterfaceIO->pvUser, pszFilename,
     1509                                        VDOpenFlagsToFileOpenFlags(VD_OPEN_FLAGS_READONLY,
     1510                                                                   false /* fCreate */),
     1511                                        &pStorage);
     1512    if (RT_FAILURE(rc))
    9541513        goto out;
    955     }
     1514
     1515    rc = pInterfaceIOCallbacks->pfnGetSize(pInterfaceIO->pvUser, pStorage, &cbFile);
     1516    if (RT_FAILURE(rc) || cbFile < sizeof(VciHdr))
     1517    {
     1518        pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage);
     1519        rc = VERR_VD_GEN_INVALID_HEADER;
     1520        goto out;
     1521    }
     1522
     1523    rc = pInterfaceIOCallbacks->pfnReadSync(pInterfaceIO->pvUser, pStorage, 0, &Hdr, sizeof(Hdr), NULL);
     1524    if (RT_FAILURE(rc))
     1525    {
     1526        pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage);
     1527        rc = VERR_VD_GEN_INVALID_HEADER;
     1528        goto out;
     1529    }
     1530
     1531    Hdr.u32Signature = RT_LE2H_U32(Hdr.u32Signature);
     1532    Hdr.u32Version   = RT_LE2H_U32(Hdr.u32Version);
     1533    Hdr.cBlocksCache = RT_LE2H_U64(Hdr.cBlocksCache);
     1534    Hdr.u32CacheType = RT_LE2H_U32(Hdr.u32CacheType);
     1535    Hdr.offTreeRoot  = RT_LE2H_U64(Hdr.offTreeRoot);
     1536    Hdr.offBlkMap    = RT_LE2H_U64(Hdr.offBlkMap);
     1537    Hdr.cBlkMap      = RT_LE2H_U64(Hdr.cBlkMap);
     1538
     1539    if (   Hdr.u32Signature == VCI_HDR_SIGNATURE
     1540        && Hdr.u32Version == VCI_HDR_VERSION)
     1541        rc = VINF_SUCCESS;
     1542    else
     1543        rc = VERR_VD_GEN_INVALID_HEADER;
     1544
     1545    pInterfaceIOCallbacks->pfnClose(pInterfaceIO->pvUser, pStorage);
    9561546
    9571547out:
     
    9671557    LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, ppBackendData));
    9681558    int rc;
    969     PVCICACHE pImage;
     1559    PVCICACHE pCache;
    9701560
    9711561    /* Check open flags. All valid flags are supported. */
     
    9851575
    9861576
    987     pImage = (PVCICACHE)RTMemAllocZ(sizeof(VCICACHE));
    988     if (!pImage)
     1577    pCache = (PVCICACHE)RTMemAllocZ(sizeof(VCICACHE));
     1578    if (!pCache)
    9891579    {
    9901580        rc = VERR_NO_MEMORY;
    9911581        goto out;
    9921582    }
    993     pImage->pszFilename = pszFilename;
    994     pImage->pStorage = NULL;
    995     pImage->pVDIfsDisk = pVDIfsDisk;
    996     pImage->pVDIfsImage = pVDIfsImage;
    997 
    998     rc = vciOpenImage(pImage, uOpenFlags);
     1583    pCache->pszFilename = pszFilename;
     1584    pCache->pStorage = NULL;
     1585    pCache->pVDIfsDisk = pVDIfsDisk;
     1586    pCache->pVDIfsImage = pVDIfsImage;
     1587
     1588    rc = vciOpenImage(pCache, uOpenFlags);
    9991589    if (RT_SUCCESS(rc))
    1000         *ppBackendData = pImage;
     1590        *ppBackendData = pCache;
    10011591    else
    1002         RTMemFree(pImage);
     1592        RTMemFree(pCache);
    10031593
    10041594out:
     
    10181608                 pszFilename, cbSize, uImageFlags, pszComment, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData));
    10191609    int rc;
    1020     PVCICACHE pImage;
     1610    PVCICACHE pCache;
    10211611
    10221612    PFNVDPROGRESS pfnProgress = NULL;
     
    10481638    }
    10491639
    1050     pImage = (PVCICACHE)RTMemAllocZ(sizeof(VCICACHE));
    1051     if (!pImage)
     1640    pCache = (PVCICACHE)RTMemAllocZ(sizeof(VCICACHE));
     1641    if (!pCache)
    10521642    {
    10531643        rc = VERR_NO_MEMORY;
    10541644        goto out;
    10551645    }
    1056     pImage->pszFilename = pszFilename;
    1057     pImage->pStorage = NULL;
    1058     pImage->pVDIfsDisk = pVDIfsDisk;
    1059     pImage->pVDIfsImage = pVDIfsImage;
    1060 
    1061     rc = vciCreateImage(pImage, cbSize, uImageFlags, pszComment, uOpenFlags,
     1646    pCache->pszFilename = pszFilename;
     1647    pCache->pStorage = NULL;
     1648    pCache->pVDIfsDisk = pVDIfsDisk;
     1649    pCache->pVDIfsImage = pVDIfsImage;
     1650
     1651    rc = vciCreateImage(pCache, cbSize, uImageFlags, pszComment, uOpenFlags,
    10621652                        pfnProgress, pvUser, uPercentStart, uPercentSpan);
    10631653    if (RT_SUCCESS(rc))
     
    10671657        if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
    10681658        {
    1069             vciFreeImage(pImage, false);
    1070             rc = vciOpenImage(pImage, uOpenFlags);
     1659            vciFreeImage(pCache, false);
     1660            rc = vciOpenImage(pCache, uOpenFlags);
    10711661            if (RT_FAILURE(rc))
    10721662            {
    1073                 RTMemFree(pImage);
     1663                RTMemFree(pCache);
    10741664                goto out;
    10751665            }
    10761666        }
    1077         *ppBackendData = pImage;
     1667        *ppBackendData = pCache;
    10781668    }
    10791669    else
    1080         RTMemFree(pImage);
     1670        RTMemFree(pCache);
    10811671
    10821672out:
     
    10891679{
    10901680    LogFlowFunc(("pBackendData=%#p fDelete=%d\n", pBackendData, fDelete));
    1091     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1681    PVCICACHE pCache = (PVCICACHE)pBackendData;
    10921682    int rc;
    10931683
    1094     rc = vciFreeImage(pImage, fDelete);
    1095     RTMemFree(pImage);
     1684    rc = vciFreeImage(pCache, fDelete);
     1685    RTMemFree(pCache);
    10961686
    10971687    LogFlowFunc(("returns %Rrc\n", rc));
     
    11041694{
    11051695    LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToRead=%zu pcbActuallyRead=%#p\n", pBackendData, uOffset, pvBuf, cbToRead, pcbActuallyRead));
    1106     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1696    PVCICACHE pCache = (PVCICACHE)pBackendData;
    11071697    int rc = VINF_SUCCESS;
    1108 
    1109     AssertPtr(pImage);
     1698    PVCICACHEEXTENT pExtent;
     1699
     1700    AssertPtr(pCache);
    11101701    Assert(uOffset % 512 == 0);
    11111702    Assert(cbToRead % 512 == 0);
     1703
     1704
     1705    pExtent = vciCacheExtentLookup(pCache, VCI_BYTE2BLOCK(uOffset));
     1706    if (pExtent)
     1707    {
     1708        uint64_t offRead = uOffset - VCI_BLOCK2BYTE(pExtent->u64BlockOffset);
     1709        cbToRead = RT_MIN(cbToRead, VCI_BLOCK2BYTE(pExtent->u32Blocks) - offRead);
     1710
     1711        rc = vciFileReadSync(pCache, VCI_BLOCK2BYTE(pExtent->u64BlockAddr) + offRead,
     1712                             pvBuf, cbToRead);
     1713    }
     1714    else
     1715    {
     1716        /** @todo Best fit to check whether we have cached data later and set
     1717         * pcbActuallyRead accordingly. */
     1718        rc = VERR_VD_BLOCK_FREE;
     1719    }
     1720
     1721    if (pcbActuallyRead)
     1722        *pcbActuallyRead = cbToRead;
    11121723
    11131724out:
     
    11221733    LogFlowFunc(("pBackendData=%#p uOffset=%llu pvBuf=%#p cbToWrite=%zu pcbWriteProcess=%#p\n",
    11231734                 pBackendData, uOffset, pvBuf, cbToWrite, pcbWriteProcess));
    1124     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1735    PVCICACHE pCache = (PVCICACHE)pBackendData;
    11251736    int rc = VINF_SUCCESS;
    11261737
    1127     AssertPtr(pImage);
     1738    AssertPtr(pCache);
    11281739    Assert(uOffset % 512 == 0);
    11291740    Assert(cbToWrite % 512 == 0);
     
    11381749{
    11391750    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    1140     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1751    PVCICACHE pCache = (PVCICACHE)pBackendData;
    11411752    int rc = VINF_SUCCESS;
    11421753
    1143     rc = vciFlushImage(pImage);
     1754    rc = vciFlushImage(pCache);
    11441755    LogFlowFunc(("returns %Rrc\n", rc));
    11451756    return rc;
     
    11501761{
    11511762    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    1152     PVCICACHE pImage = (PVCICACHE)pBackendData;
    1153 
    1154     AssertPtr(pImage);
    1155 
    1156     if (pImage)
     1763    PVCICACHE pCache = (PVCICACHE)pBackendData;
     1764
     1765    AssertPtr(pCache);
     1766
     1767    if (pCache)
    11571768        return 1;
    11581769    else
     
    11641775{
    11651776    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    1166     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1777    PVCICACHE pCache = (PVCICACHE)pBackendData;
    11671778    uint64_t cb = 0;
    11681779
    1169     AssertPtr(pImage);
    1170 
    1171     if (pImage && pImage->pStorage)
    1172         cb = pImage->cbSize;
     1780    AssertPtr(pCache);
     1781
     1782    if (pCache && pCache->pStorage)
     1783        cb = pCache->cbSize;
    11731784
    11741785    LogFlowFunc(("returns %llu\n", cb));
     
    11801791{
    11811792    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    1182     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1793    PVCICACHE pCache = (PVCICACHE)pBackendData;
    11831794    uint64_t cb = 0;
    11841795
    1185     AssertPtr(pImage);
    1186 
    1187     if (pImage)
     1796    AssertPtr(pCache);
     1797
     1798    if (pCache)
    11881799    {
    11891800        uint64_t cbFile;
    1190         if (pImage->pStorage)
    1191         {
    1192             int rc = vciFileGetSize(pImage, &cbFile);
     1801        if (pCache->pStorage)
     1802        {
     1803            int rc = vciFileGetSize(pCache, &cbFile);
    11931804            if (RT_SUCCESS(rc))
    11941805                cb = cbFile;
     
    12041815{
    12051816    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    1206     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1817    PVCICACHE pCache = (PVCICACHE)pBackendData;
    12071818    unsigned uImageFlags;
    12081819
    1209     AssertPtr(pImage);
    1210 
    1211     if (pImage)
    1212         uImageFlags = pImage->uImageFlags;
     1820    AssertPtr(pCache);
     1821
     1822    if (pCache)
     1823        uImageFlags = pCache->uImageFlags;
    12131824    else
    12141825        uImageFlags = 0;
     
    12221833{
    12231834    LogFlowFunc(("pBackendData=%#p\n", pBackendData));
    1224     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1835    PVCICACHE pCache = (PVCICACHE)pBackendData;
    12251836    unsigned uOpenFlags;
    12261837
    1227     AssertPtr(pImage);
    1228 
    1229     if (pImage)
    1230         uOpenFlags = pImage->uOpenFlags;
     1838    AssertPtr(pCache);
     1839
     1840    if (pCache)
     1841        uOpenFlags = pCache->uOpenFlags;
    12311842    else
    12321843        uOpenFlags = 0;
     
    12401851{
    12411852    LogFlowFunc(("pBackendData=%#p\n uOpenFlags=%#x", pBackendData, uOpenFlags));
    1242     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1853    PVCICACHE pCache = (PVCICACHE)pBackendData;
    12431854    int rc;
    12441855
    12451856    /* Image must be opened and the new flags must be valid. Just readonly and
    12461857     * info flags are supported. */
    1247     if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO)))
     1858    if (!pCache || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO)))
    12481859    {
    12491860        rc = VERR_INVALID_PARAMETER;
     
    12521863
    12531864    /* Implement this operation via reopening the image. */
    1254     rc = vciFreeImage(pImage, false);
     1865    rc = vciFreeImage(pCache, false);
    12551866    if (RT_FAILURE(rc))
    12561867        goto out;
    1257     rc = vciOpenImage(pImage, uOpenFlags);
     1868    rc = vciOpenImage(pCache, uOpenFlags);
    12581869
    12591870out:
     
    12671878{
    12681879    LogFlowFunc(("pBackendData=%#p pszComment=%#p cbComment=%zu\n", pBackendData, pszComment, cbComment));
    1269     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1880    PVCICACHE pCache = (PVCICACHE)pBackendData;
    12701881    int rc;
    12711882
    1272     AssertPtr(pImage);
    1273 
    1274     if (pImage)
     1883    AssertPtr(pCache);
     1884
     1885    if (pCache)
    12751886        rc = VERR_NOT_SUPPORTED;
    12761887    else
     
    12851896{
    12861897    LogFlowFunc(("pBackendData=%#p pszComment=\"%s\"\n", pBackendData, pszComment));
    1287     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1898    PVCICACHE pCache = (PVCICACHE)pBackendData;
    12881899    int rc;
    12891900
    1290     AssertPtr(pImage);
    1291 
    1292     if (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)
     1901    AssertPtr(pCache);
     1902
     1903    if (pCache->uOpenFlags & VD_OPEN_FLAGS_READONLY)
    12931904    {
    12941905        rc = VERR_VD_IMAGE_READ_ONLY;
     
    12961907    }
    12971908
    1298     if (pImage)
     1909    if (pCache)
    12991910        rc = VERR_NOT_SUPPORTED;
    13001911    else
     
    13101921{
    13111922    LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
    1312     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1923    PVCICACHE pCache = (PVCICACHE)pBackendData;
    13131924    int rc;
    13141925
    1315     AssertPtr(pImage);
    1316 
    1317     if (pImage)
     1926    AssertPtr(pCache);
     1927
     1928    if (pCache)
    13181929        rc = VERR_NOT_SUPPORTED;
    13191930    else
     
    13281939{
    13291940    LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
    1330     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1941    PVCICACHE pCache = (PVCICACHE)pBackendData;
    13311942    int rc;
    13321943
    13331944    LogFlowFunc(("%RTuuid\n", pUuid));
    1334     AssertPtr(pImage);
    1335 
    1336     if (pImage)
    1337     {
    1338         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1945    AssertPtr(pCache);
     1946
     1947    if (pCache)
     1948    {
     1949        if (!(pCache->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    13391950            rc = VERR_NOT_SUPPORTED;
    13401951        else
     
    13521963{
    13531964    LogFlowFunc(("pBackendData=%#p pUuid=%#p\n", pBackendData, pUuid));
    1354     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1965    PVCICACHE pCache = (PVCICACHE)pBackendData;
    13551966    int rc;
    13561967
    1357     AssertPtr(pImage);
    1358 
    1359     if (pImage)
     1968    AssertPtr(pCache);
     1969
     1970    if (pCache)
    13601971        rc = VERR_NOT_SUPPORTED;
    13611972    else
     
    13701981{
    13711982    LogFlowFunc(("pBackendData=%#p Uuid=%RTuuid\n", pBackendData, pUuid));
    1372     PVCICACHE pImage = (PVCICACHE)pBackendData;
     1983    PVCICACHE pCache = (PVCICACHE)pBackendData;
    13731984    int rc;
    13741985
    1375     AssertPtr(pImage);
    1376 
    1377     if (pImage)
    1378     {
    1379         if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1986    AssertPtr(pCache);
     1987
     1988    if (pCache)
     1989    {
     1990        if (!(pCache->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    13801991            rc = VERR_NOT_SUPPORTED;
    13811992        else
     
    13992010                        PVDIOCTX pIoCtx, size_t *pcbActuallyRead)
    14002011{
    1401     int rc = VINF_SUCCESS;
    1402     PVCICACHE pImage = (PVCICACHE)pBackendData;
    1403 
    1404     rc = vciFileReadUserAsync(pImage, uOffset, pIoCtx, cbRead);
    1405     if (RT_SUCCESS(rc))
    1406         *pcbActuallyRead = cbRead;
     2012    int rc = VERR_NOT_SUPPORTED;
     2013    PVCICACHE pCache = (PVCICACHE)pBackendData;
    14072014
    14082015    return rc;
     
    14132020                         PVDIOCTX pIoCtx, size_t *pcbWriteProcess)
    14142021{
    1415     int rc = VINF_SUCCESS;
    1416     PVCICACHE pImage = (PVCICACHE)pBackendData;
    1417 
    1418     rc = vciFileWriteUserAsync(pImage, uOffset, pIoCtx, cbWrite, NULL, NULL);
    1419     if (RT_SUCCESS(rc))
    1420         *pcbWriteProcess = cbWrite;
     2022    int rc = VERR_NOT_SUPPORTED;
     2023    PVCICACHE pCache = (PVCICACHE)pBackendData;
    14212024
    14222025    return rc;
     
    14262029static int vciAsyncFlush(void *pBackendData, PVDIOCTX pIoCtx)
    14272030{
    1428     int rc = VINF_SUCCESS;
    1429     PVCICACHE pImage = (PVCICACHE)pBackendData;
    1430 
    1431     if (!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY))
    1432         rc = vciFileFlushAsync(pImage, pIoCtx, NULL, NULL);
     2031    int rc = VERR_NOT_SUPPORTED;
     2032    PVCICACHE pCache = (PVCICACHE)pBackendData;
    14332033
    14342034    return rc;
     
    14432043    sizeof(VDCACHEBACKEND),
    14442044    /* uBackendCaps */
    1445     VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC | VD_CAP_FILE | VD_CAP_ASYNC,
     2045    VD_CAP_CREATE_FIXED | VD_CAP_CREATE_DYNAMIC | VD_CAP_FILE | VD_CAP_VFS,
    14462046    /* papszFileExtensions */
    14472047    s_apszVciFileExtensions,
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