VirtualBox

Changeset 11444

Show
Ignore:
Timestamp:
08/15/08 16:33:02 (3 months ago)
Author:
vboxsync
Message:

Storage/VBoxHDD-new: introduced VD interfaces per image and per operation, completely unifying callback handling.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/VBoxHDD-new.h

    r11435 r11444  
    237237    /** First valid interface. */ 
    238238    VDINTERFACETYPE_FIRST = 0, 
    239     /** Interface to pass error message to upper layers. */ 
     239    /** Interface to pass error message to upper layers. Per-disk. */ 
    240240    VDINTERFACETYPE_ERROR = VDINTERFACETYPE_FIRST, 
    241     /** Interface for asynchronous I/O operations. */ 
     241    /** Interface for asynchronous I/O operations. Per-disk. */ 
    242242    VDINTERFACETYPE_ASYNCIO, 
    243     /** Interface for progress notification. */ 
     243    /** Interface for progress notification. Per-operation. */ 
    244244    VDINTERFACETYPE_PROGRESS, 
    245     /** Interface for configuration information. */ 
     245    /** Interface for configuration information. Per-image. */ 
    246246    VDINTERFACETYPE_CONFIG, 
    247247    /** invalid interface. */ 
     
    274274/** 
    275275 * Helper functions to handle interface lists. 
     276 * 
     277 * @note These interface lists are used consistently to pass per-disk, 
     278 * per-image and/or per-operation callbacks. Those three purposes are strictly 
     279 * separate. See the individual interface declarations for what context they 
     280 * apply to. The caller is responsible for ensuring that the lifetime of the 
     281 * interface descriptors is appropriate for the category of interface. 
    276282 */ 
    277283 
     
    349355/** 
    350356 * Interface to deliver error messages to upper layers. 
     357 * 
     358 * Per disk interface. Optional, but think twice if you want to miss the 
     359 * opportunity of reporting better human-readable error messages. 
    351360 */ 
    352361typedef struct VDINTERFACEERROR 
     
    401410 * Completion callback which is called by the interface owner 
    402411 * to inform the backend that a task finished. 
    403  *  
     412 * 
    404413 * @return  VBox status code. 
    405414 * @param   pvUser          Opaque user data which is passed on request submission. 
     
    412421/** 
    413422 * Support interface for asynchronous I/O 
     423 * 
     424 * Per-disk. Optional. 
    414425 */ 
    415426typedef struct VDINTERFACEASYNCIO 
     
    551562/** 
    552563 * Progress notification interface 
     564 *  
     565 * Per-operation. Optional. 
    553566 */ 
    554567typedef struct VDINTERFACEPROGRESS 
     
    614627/** 
    615628 * Configuration information interface 
     629 * 
     630 * Per-image. Optional for most backends, but mandatory for images which do 
     631 * not operate on files (including standard block or character devices). 
    616632 */ 
    617633typedef struct VDINTERFACECONFIG 
     
    902918 * 
    903919 * @return  VBox status code. 
    904  * @param   pVDIfs          Pointer to the VD interface list. 
     920 * @param   pVDIfsDisk      Pointer to the per-disk VD interface list. 
    905921 * @param   ppDisk          Where to store the reference to HDD container. 
    906922 */ 
    907 VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pVDIfs, PVBOXHDD *ppDisk); 
     923VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pVDIfsDisk, PVBOXHDD *ppDisk); 
    908924 
    909925/** 
     
    943959 * @param   pszFilename     Name of the image file to open. 
    944960 * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
     961 * @param   pVDIfsImage     Pointer to the per-image VD interface list. 
    945962 */ 
    946963VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend, 
    947                          const char *pszFilename, unsigned uOpenFlags); 
     964                         const char *pszFilename, unsigned uOpenFlags, 
     965                         PVDINTERFACE pVDIfsImage); 
    948966 
    949967/** 
     
    962980 * @param   pUuid           New UUID of the image. If NULL, a new UUID is created. 
    963981 * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
    964  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used
    965  * @param   pvUser          User argument for the progress callback
     982 * @param   pVDIfsImage     Pointer to the per-image VD interface list
     983 * @param   pVDIfsOperation Pointer to the per-operation VD interface list
    966984 */ 
    967985VBOXDDU_DECL(int) VDCreateBase(PVBOXHDD pDisk, const char *pszBackend, 
     
    972990                               PCPDMMEDIAGEOMETRY pLCHSGeometry, 
    973991                               PCRTUUID pUuid, unsigned uOpenFlags, 
    974                                PFNVMPROGRESS pfnProgress, void *pvUser); 
     992                               PVDINTERFACE pVDIfsImage, 
     993                               PVDINTERFACE pVDIfsOperation); 
    975994 
    976995/** 
     
    9861005 * @param   pUuid           New UUID of the image. If NULL, a new UUID is created. 
    9871006 * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
    988  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used
    989  * @param   pvUser          User argument for the progress callback
     1007 * @param   pVDIfsImage     Pointer to the per-image VD interface list
     1008 * @param   pVDIfsOperation Pointer to the per-operation VD interface list
    9901009 */ 
    9911010VBOXDDU_DECL(int) VDCreateDiff(PVBOXHDD pDisk, const char *pszBackend, 
    9921011                               const char *pszFilename, unsigned uImageFlags, 
    9931012                               const char *pszComment, PCRTUUID pUuid, 
    994                                unsigned uOpenFlags, PFNVMPROGRESS pfnProgress
    995                                void *pvUser); 
     1013                               unsigned uOpenFlags, PVDINTERFACE pVDIfsImage
     1014                               PVDINTERFACE pVDIfsOperation); 
    9961015 
    9971016/** 
     
    10061025 * @param   nImageFrom      Name of the image file to merge from. 
    10071026 * @param   nImageTo        Name of the image file to merge to. 
    1008  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used. 
    1009  * @param   pvUser          User argument for the progress callback. 
     1027 * @param   pVDIfsOperation Pointer to the per-operation VD interface list. 
    10101028 */ 
    10111029VBOXDDU_DECL(int) VDMerge(PVBOXHDD pDisk, unsigned nImageFrom, 
    1012                           unsigned nImageTo, PFNVMPROGRESS pfnProgress, 
    1013                           void *pvUser); 
     1030                          unsigned nImageTo, PVDINTERFACE pVDIfsOperation); 
    10141031 
    10151032/** 
     
    10321049 * @param   fMoveByRename   If true, attempt to perform a move by renaming (if successful the new size is ignored). 
    10331050 * @param   cbSize          New image size (0 means leave unchanged). 
    1034  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used. 
    1035  * @param   pvUser          User argument for the progress callback. 
     1051 * @param   pVDIfsOperation Pointer to the per-operation VD interface list. 
     1052 * @param   pDstVDIfsImage  Pointer to the per-image VD interface list, for the 
     1053 *                          destination image. 
     1054 * @param   pDstVDIfsOperation Pointer to the per-operation VD interface list, 
     1055 *                          for the destination operation. 
    10361056 */ 
    10371057VBOXDDU_DECL(int) VDCopy(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo, 
    10381058                         const char *pszBackend, const char *pszFilename, 
    10391059                         bool fMoveByRename, uint64_t cbSize, 
    1040                          PFNVMPROGRESS pfnProgress, void *pvUser); 
     1060                         PVDINTERFACE pVDIfsOperation, 
     1061                         PVDINTERFACE pDstVDIfsImage, 
     1062                         PVDINTERFACE pDstVDIfsOperation); 
    10411063 
    10421064/** 
  • trunk/src/VBox/Devices/Storage/DrvVD.cpp

    r11435 r11444  
    7777 
    7878/** 
     79 * VBox disk container, image information, private part. 
     80 */ 
     81 
     82typedef struct VBOXIMAGE 
     83{ 
     84    /** Pointer to next image. */ 
     85    struct VBOXIMAGE    *pNext; 
     86    /** Pointer to list of VD interfaces. Per-image. */ 
     87    PVDINTERFACE       pVDIfsImage; 
     88    /** Common structure for the configuration information interface. */ 
     89    VDINTERFACE        VDIConfig; 
     90} VBOXIMAGE, *PVBOXIMAGE; 
     91 
     92/** 
    7993 * VBox disk container media main structure, private part. 
    8094 */ 
     
    89103    /** Flag whether suspend has changed image open mode to read only. */ 
    90104    bool               fTempReadOnly; 
    91     /** Pointer to list of VD interfaces. */ 
    92     PVDINTERFACE       pVDIfs
     105    /** Pointer to list of VD interfaces. Per-disk. */ 
     106    PVDINTERFACE       pVDIfsDisk
    93107    /** Common structure for the supported error interface. */ 
    94108    VDINTERFACE        VDIError; 
     
    99113    /** Callback table for async I/O interface. */ 
    100114    VDINTERFACEASYNCIO VDIAsyncIOCallbacks; 
    101     /** Common structure for the configuration information interface. */ 
    102     VDINTERFACE        VDIConfig; 
    103115    /** Callback table for the configuration information interface. */ 
    104116    VDINTERFACECONFIG  VDIConfigCallbacks; 
     
    115127    /** Our cache to reduce allocation overhead. */ 
    116128    PRTOBJCACHE              pCache; 
     129    /** Pointer to the list of data we need to keep per image. */ 
     130    PVBOXIMAGE               pImages; 
    117131} VBOXDISK, *PVBOXDISK; 
    118132 
     
    126140    PPDMDRVINS pDrvIns = (PPDMDRVINS)pvUser; 
    127141    pDrvIns->pDrvHlp->pfnVMSetErrorV(pDrvIns, rc, RT_SRC_POS_ARGS, pszFormat, va); 
     142} 
     143 
     144 
     145/** 
     146 * Internal: allocate new image descriptor and put it in the list 
     147 */ 
     148static PVBOXIMAGE drvvdNewImage(PVBOXDISK pThis) 
     149{ 
     150    AssertPtr(pThis); 
     151    PVBOXIMAGE pImage = (PVBOXIMAGE)RTMemAllocZ(sizeof(VBOXIMAGE)); 
     152    if (pImage) 
     153    { 
     154        pImage->pVDIfsImage = NULL; 
     155        PVBOXIMAGE *pp = &pThis->pImages; 
     156        while (*pp != NULL) 
     157            pp = &(*pp)->pNext; 
     158        *pp = pImage; 
     159        pImage->pNext = NULL; 
     160    } 
     161 
     162    return pImage; 
     163} 
     164 
     165/** 
     166 * Internal: free the list of images descriptors. 
     167 */ 
     168static void drvvdFreeImages(PVBOXDISK pThis) 
     169{ 
     170    while (pThis->pImages != NULL) 
     171    { 
     172        PVBOXIMAGE p = pThis->pImages; 
     173        pThis->pImages = pThis->pImages->pNext; 
     174        RTMemFree(p); 
     175    } 
    128176} 
    129177 
     
    537585 
    538586    /* Initialize supported VD interfaces. */ 
    539     pThis->pVDIfs = NULL; 
     587    pThis->pVDIfsDisk = NULL; 
    540588 
    541589    pThis->VDIErrorCallbacks.cbSize       = sizeof(VDINTERFACEERROR); 
     
    544592 
    545593    rc = VDInterfaceAdd(&pThis->VDIError, "DrvVD_VDIError", VDINTERFACETYPE_ERROR, 
    546                         &pThis->VDIErrorCallbacks, pDrvIns, &pThis->pVDIfs); 
     594                        &pThis->VDIErrorCallbacks, pDrvIns, &pThis->pVDIfsDisk); 
    547595    AssertRC(rc); 
    548596 
     
    559607 
    560608    rc = VDInterfaceAdd(&pThis->VDIAsyncIO, "DrvVD_AsyncIO", VDINTERFACETYPE_ASYNCIO, 
    561                         &pThis->VDIAsyncIOCallbacks, pThis, &pThis->pVDIfs); 
     609                        &pThis->VDIAsyncIOCallbacks, pThis, &pThis->pVDIfsDisk); 
    562610    AssertRC(rc); 
    563611 
     612    /* This is just prepared here, the actual interface is per-image, so it's 
     613     * added later. No need to have separate callback tables. */ 
    564614    pThis->VDIConfigCallbacks.cbSize                = sizeof(VDINTERFACECONFIG); 
    565615    pThis->VDIConfigCallbacks.enmInterface          = VDINTERFACETYPE_CONFIG; 
     
    573623    pThis->VDIConfigCallbacks.pfnQueryBytes         = drvvdCfgQueryBytes; 
    574624 
    575     /** @todo TEMP! this isn't really correct - this needs to be made per image, 
    576      * as CFGM needs access to the right configuration node for each image. 
    577      * At the moment this is harmless, as iSCSI can only be used as a base 
    578      * image, and no other backend uses the private data for these callbacks. */ 
    579     rc = VDInterfaceAdd(&pThis->VDIConfig, "DrvVD_Config", VDINTERFACETYPE_CONFIG, 
    580                         &pThis->VDIConfigCallbacks, NULL /**< @todo TEMP */, &pThis->pVDIfs); 
    581     AssertRC(rc); 
     625    /* List of images is empty now. */ 
     626    pThis->pImages = NULL; 
    582627 
    583628    /* Try to attach async media port interface above.*/ 
     
    662707    if (RT_SUCCESS(rc)) 
    663708    { 
    664         /** @todo TEMP! later the iSCSI config callbacks won't be included here */ 
    665         rc = VDCreate(&pThis->VDIConfig, &pThis->pDisk); 
     709        rc = VDCreate(pThis->pVDIfsDisk, &pThis->pDisk); 
    666710        /* Error message is already set correctly. */ 
    667711    } 
    668712 
    669     unsigned cImages = iLevel; 
    670713    while (pCurNode && RT_SUCCESS(rc)) 
    671714    { 
     715        /* Allocate per-image data. */ 
     716        PVBOXIMAGE pImage = drvvdNewImage(pThis); 
     717        if (!pImage) 
     718        { 
     719            rc = VERR_NO_MEMORY; 
     720            break; 
     721        } 
     722 
    672723        /* 
    673724         * Read the image configuration. 
     
    717768        } 
    718769 
    719         /** @todo TEMP! Later this needs to be done for each image. */ 
    720         if (iLevel == cImages) 
    721         { 
    722             PCFGMNODE pCfg = CFGMR3GetChild(pCurNode, "VDConfig"); 
    723             pThis->VDIConfig.pvUser = pCfg; /**< @todo TEMP! */ 
    724         } 
     770        PCFGMNODE pCfg = CFGMR3GetChild(pCurNode, "VDConfig"); 
     771        rc = VDInterfaceAdd(&pImage->VDIConfig, "DrvVD_Config", VDINTERFACETYPE_CONFIG, 
     772                            &pThis->VDIConfigCallbacks, pCfg, &pImage->pVDIfsImage); 
     773        AssertRC(rc); 
    725774 
    726775        /* 
     
    738787 
    739788        /** Try to open backend in asyc I/O mode first. */ 
    740         rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags); 
     789        rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage); 
    741790        if (rc == VERR_NOT_SUPPORTED) 
    742791        { 
    743792            /* Seems async I/O is not supported by the backend, open in normal mode. */ 
    744793            uOpenFlags &= ~VD_OPEN_FLAGS_ASYNC_IO; 
    745             rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags); 
     794            rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage); 
    746795        } 
    747796 
     
    774823            pThis->pDisk = NULL; 
    775824        } 
     825        drvvdFreeImages(pThis); 
    776826        if (VALID_PTR(pszName)) 
    777827            MMR3HeapFree(pszName); 
     
    841891    LogFlow(("%s:\n", __FUNCTION__)); 
    842892 
     893    drvvdFreeImages(pThis); 
    843894    if (pThis->pCache) 
    844895    { 
  • trunk/src/VBox/Devices/Storage/RawHDDCore.cpp

    r11435 r11444  
    4747    RTFILE          File; 
    4848 
    49     /** Pointer to list of VD interfaces. */ 
    50     PVDINTERFACE      pVDIfs; 
     49    /** Pointer to the per-disk VD interface list. */ 
     50    PVDINTERFACE      pVDIfsDisk; 
     51 
    5152    /** Error callback. */ 
    5253    PVDINTERFACE      pInterfaceError; 
     
    118119    pImage->uOpenFlags = uOpenFlags; 
    119120 
    120     pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfs, VDINTERFACETYPE_ERROR); 
     121    pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR); 
    121122    if (pImage->pInterfaceError) 
    122123        pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 
     
    182183    pImage->LCHSGeometry = *pLCHSGeometry; 
    183184 
    184     pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfs, VDINTERFACETYPE_ERROR); 
     185    pImage->pInterfaceError = VDInterfaceGet(pImage->pVDIfsDisk, VDINTERFACETYPE_ERROR); 
    185186    if (pImage->pInterfaceError) 
    186187        pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); 
     
    330331/** @copydoc VBOXHDDBACKEND::pfnOpen */ 
    331332static int rawOpen(const char *pszFilename, unsigned uOpenFlags, 
    332                    PVDINTERFACE pVDIfs, void **ppBackendData) 
    333 
    334     LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x ppBackendData=%#p\n", pszFilename, uOpenFlags, ppBackendData)); 
     333                   PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, 
     334                   void **ppBackendData) 
     335
     336    LogFlowFunc(("pszFilename=\"%s\" uOpenFlags=%#x pVDIfsDisk=%#p pVDIfsImage=%#p ppBackendData=%#p\n", pszFilename, uOpenFlags, pVDIfsDisk, pVDIfsImage, ppBackendData)); 
    335337    int rc; 
    336338    PRAWIMAGE pImage; 
     
    360362    pImage->pszFilename = pszFilename; 
    361363    pImage->File = NIL_RTFILE; 
    362     pImage->pInterfaceError = NULL; 
    363     pImage->pInterfaceErrorCallbacks = NULL; 
    364     pImage->pVDIfs = pVDIfs; 
     364    pImage->pVDIfsDisk = pVDIfsDisk; 
    365365 
    366366    rc = rawOpenImage(pImage, uOpenFlags); 
     
    379379                     PCPDMMEDIAGEOMETRY pPCHSGeometry, 
    380380                     PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid, 
    381                      unsigned uOpenFlags, PFNVMPROGRESS pfnProgress
    382                      void *pvUser, unsigned uPercentStart
    383                      unsigned uPercentSpan, PVDINTERFACE pVDIfs
     381                     unsigned uOpenFlags, unsigned uPercentStart
     382                     unsigned uPercentSpan, PVDINTERFACE pVDIfsDisk
     383                     PVDINTERFACE pVDIfsImage, PVDINTERFACE pVDIfsOperation
    384384                     void **ppBackendData) 
    385385{ 
    386     LogFlowFunc(("pszFilename=\"%s\" enmType=%d cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x pfnProgress=%#p pvUser=%#p uPercentStart=%u uPercentSpan=%u pVDIfs=%#p ppBackendData=%#p", pszFilename, enmType, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, pfnProgress, pvUser, uPercentStart, uPercentSpan, pVDIfs, ppBackendData)); 
     386    LogFlowFunc(("pszFilename=\"%s\" enmType=%d cbSize=%llu uImageFlags=%#x pszComment=\"%s\" pPCHSGeometry=%#p pLCHSGeometry=%#p Uuid=%RTuuid uOpenFlags=%#x uPercentStart=%u uPercentSpan=%u pVDIfsDisk=%#p pVDIfsImage=%#p pVDIfsOperation=%#p ppBackendData=%#p", pszFilename, enmType, cbSize, uImageFlags, pszComment, pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, uPercentStart, uPercentSpan, pVDIfsDisk, pVDIfsImage, pVDIfsOperation, ppBackendData)); 
    387387    int rc; 
    388388    PRAWIMAGE pImage; 
     389 
     390    PFNVMPROGRESS pfnProgress = NULL; 
     391    void *pvUser = NULL; 
     392    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation, 
     393                                              VDINTERFACETYPE_PROGRESS); 
     394    PVDINTERFACEPROGRESS pCbProgress = NULL; 
     395    if (pIfProgress) 
     396    { 
     397        pCbProgress = VDGetInterfaceProgress(pIfProgress); 
     398        pfnProgress = pCbProgress->pfnProgress; 
     399        pvUser = pIfProgress->pvUser; 
     400    } 
    389401 
    390402    /* Check open flags. All valid flags are supported. */ 
     
    414426    pImage->pszFilename = pszFilename; 
    415427    pImage->File = NIL_RTFILE; 
    416     pImage->pVDIfs = pVDIfs
     428    pImage->pVDIfsDisk = pVDIfsDisk
    417429 
    418430    rc = rawCreateImage(pImage, enmType, cbSize, uImageFlags, pszComment, 
  • trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp

    r11435 r11444  
    7070    /** Function pointers for the various backend methods. */ 
    7171    PCVBOXHDDBACKEND    Backend; 
     72 
     73    /** Pointer to list of VD interfaces, per-image. */ 
     74    PVDINTERFACE        pVDIfsImage; 
    7275} VDIMAGE, *PVDIMAGE; 
    7376 
     
    108111    PDMMEDIAGEOMETRY    LCHSGeometry; 
    109112 
    110     /** List of interfaces the caller supports. */ 
    111     PVDINTERFACE        pInterfaces
     113    /** Pointer to list of VD interfaces, per-disk. */ 
     114    PVDINTERFACE        pVDIfsDisk
    112115    /** Pointer to the common interface structure for error reporting. */ 
    113116    PVDINTERFACE        pInterfaceError; 
     
    785788 * 
    786789 * @returns VBox status code. 
    787  * @param   pInterfaces     Pointer to the first supported interface
     790 * @param   pVDIfsDisk      Pointer to the per-disk VD interface list
    788791 * @param   ppDisk          Where to store the reference to HDD container. 
    789792 */ 
    790 VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pInterfaces, PVBOXHDD *ppDisk) 
     793VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pVDIfsDisk, PVBOXHDD *ppDisk) 
    791794{ 
    792795    int rc = VINF_SUCCESS; 
    793796    PVBOXHDD pDisk = NULL; 
    794797 
    795     LogFlowFunc(("pInterfaces=%#p\n", pInterfaces)); 
     798    LogFlowFunc(("pVDIfsDisk=%#p\n", pVDIfsDisk)); 
    796799    do 
    797800    { 
     
    815818            pDisk->LCHSGeometry.cHeads     = 0; 
    816819            pDisk->LCHSGeometry.cSectors   = 0; 
    817             pDisk->pInterfaces  = pInterfaces
     820            pDisk->pVDIfsDisk  = pVDIfsDisk
    818821            pDisk->pInterfaceError = NULL; 
    819822            pDisk->pInterfaceErrorCallbacks = NULL; 
    820823 
    821             pDisk->pInterfaceError = VDInterfaceGet(pInterfaces, VDINTERFACETYPE_ERROR); 
     824            pDisk->pInterfaceError = VDInterfaceGet(pVDIfsDisk, VDINTERFACETYPE_ERROR); 
    822825            if (pDisk->pInterfaceError) 
    823826                pDisk->pInterfaceErrorCallbacks = VDGetInterfaceError(pDisk->pInterfaceError); 
     
    10431046 * @param   pszFilename     Name of the image file to open. 
    10441047 * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
     1048 * @param   pVDIfsImage     Pointer to the per-image VD interface list. 
    10451049 */ 
    10461050VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend, 
    1047                          const char *pszFilename, unsigned uOpenFlags) 
     1051                         const char *pszFilename, unsigned uOpenFlags, 
     1052                         PVDINTERFACE pVDIfsImage) 
    10481053{ 
    10491054    int rc = VINF_SUCCESS; 
    10501055    PVDIMAGE pImage = NULL; 
    10511056 
    1052     LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" uOpenFlags=%#x\n", 
    1053                  pDisk, pszBackend, pszFilename, uOpenFlags)); 
     1057    LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" uOpenFlags=%#x\n, pVDIfsImage=%#p", 
     1058                 pDisk, pszBackend, pszFilename, uOpenFlags, pVDIfsImage)); 
    10541059    do 
    10551060    { 
     
    10821087            break; 
    10831088        } 
     1089        pImage->pVDIfsImage = pVDIfsImage; 
    10841090 
    10851091        rc = vdFindBackend(pszBackend, &pImage->Backend, &pImage->hPlugin); 
     
    10961102        rc = pImage->Backend->pfnOpen(pImage->pszFilename, 
    10971103                                      uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME, 
    1098                                       pDisk->pInterfaces, 
     1104                                      pDisk->pVDIfsDisk, 
     1105                                      pImage->pVDIfsImage, 
    10991106                                      &pImage->pvBackendData); 
    11001107        /* If the open in read-write mode failed, retry in read-only mode. */ 
     
    11101117                                                (uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME) 
    11111118                                               | VD_OPEN_FLAGS_READONLY, 
    1112                                                pDisk->pInterfaces, 
     1119                                               pDisk->pVDIfsDisk, 
     1120                                               pImage->pVDIfsImage, 
    11131121                                               &pImage->pvBackendData); 
    11141122            if (RT_FAILURE(rc)) 
     
    12611269 * @param   pUuid           New UUID of the image. If NULL, a new UUID is created. 
    12621270 * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
    1263  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used
    1264  * @param   pvUser          User argument for the progress callback
     1271 * @param   pVDIfsImage     Pointer to the per-image VD interface list
     1272 * @param   pVDIfsOperation Pointer to the per-operation VD interface list
    12651273 */ 
    12661274VBOXDDU_DECL(int) VDCreateBase(PVBOXHDD pDisk, const char *pszBackend, 
     
    12711279                               PCPDMMEDIAGEOMETRY pLCHSGeometry, 
    12721280                               PCRTUUID pUuid, unsigned uOpenFlags, 
    1273                                PFNVMPROGRESS pfnProgress, void *pvUser) 
     1281                               PVDINTERFACE pVDIfsImage, 
     1282                               PVDINTERFACE pVDIfsOperation) 
    12741283{ 
    12751284    int rc = VINF_SUCCESS; 
     
    12771286    RTUUID uuid; 
    12781287 
    1279     LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" enmType=%#x cbSize=%llu uImageFlags=%#x pszComment=\"%s\" PCHS=%u/%u/%u LCHS=%u/%u/%u Uuid=%RTuuid uOpenFlags=%#x pfnProgress=%#p pvUser=%#p\n", 
     1288    LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" enmType=%#x cbSize=%llu uImageFlags=%#x pszComment=\"%s\" PCHS=%u/%u/%u LCHS=%u/%u/%u Uuid=%RTuuid uOpenFlags=%#x pVDIfsImage=%#p pVDIfsOperation=%#p\n", 
    12801289                 pDisk, pszBackend, pszFilename, enmType, cbSize, uImageFlags, pszComment, 
    12811290                 pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, 
    12821291                 pPCHSGeometry->cSectors, pLCHSGeometry->cCylinders, 
    12831292                 pLCHSGeometry->cHeads, pLCHSGeometry->cSectors, pUuid, 
    1284                  uOpenFlags, pfnProgress, pvUser)); 
     1293                 uOpenFlags, pVDIfsImage, pVDIfsOperation)); 
     1294 
     1295    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation, 
     1296                                              VDINTERFACETYPE_PROGRESS); 
     1297    PVDINTERFACEPROGRESS pCbProgress = NULL; 
     1298    if (pIfProgress) 
     1299        pCbProgress = VDGetInterfaceProgress(pIfProgress); 
     1300 
    12851301    do 
    12861302    { 
     
    13491365            break; 
    13501366        } 
     1367        pImage->pVDIfsImage = pVDIfsImage; 
    13511368 
    13521369        rc = vdFindBackend(pszBackend, &pImage->Backend, &pImage->hPlugin); 
     
    13791396                                        pLCHSGeometry, pUuid, 
    13801397                                        uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME, 
    1381                                         pfnProgress, pvUser, 0, 99, 
    1382                                         pDisk->pInterfaces, 
     1398                                        0, 99, 
     1399                                        pDisk->pVDIfsDisk, 
     1400                                        pImage->pVDIfsImage, 
     1401                                        pVDIfsOperation, 
    13831402                                        &pImage->pvBackendData); 
    13841403 
     
    14641483    } 
    14651484 
    1466     if (RT_SUCCESS(rc) && pfnProgress) 
    1467         pfnProgress(NULL /* WARNING! pVM=NULL  */, 100, pvUser); 
     1485    if (RT_SUCCESS(rc) && pCbProgress->pfnProgress) 
     1486        pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100, 
     1487                                 pIfProgress->pvUser); 
    14681488 
    14691489    LogFlowFunc(("returns %Rrc\n", rc)); 
     
    14831503 * @param   pUuid           New UUID of the image. If NULL, a new UUID is created. 
    14841504 * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
    1485  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used
    1486  * @param   pvUser          User argument for the progress callback
     1505 * @param   pVDIfsImage     Pointer to the per-image VD interface list
     1506 * @param   pVDIfsOperation Pointer to the per-operation VD interface list
    14871507 */ 
    14881508VBOXDDU_DECL(int) VDCreateDiff(PVBOXHDD pDisk, const char *pszBackend, 
    14891509                               const char *pszFilename, unsigned uImageFlags, 
    14901510                               const char *pszComment, PCRTUUID pUuid, 
    1491                                unsigned uOpenFlags, PFNVMPROGRESS pfnProgress
    1492                                void *pvUser
     1511                               unsigned uOpenFlags, PVDINTERFACE pVDIfsImage
     1512                               PVDINTERFACE pVDIfsOperation
    14931513{ 
    14941514    int rc = VINF_SUCCESS; 
     
    14961516    RTUUID uuid; 
    14971517 
    1498     LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" uImageFlags=%#x pszComment=\"%s\" Uuid=%RTuuid uOpenFlags=%#x pfnProgress=%#p pvUser=%#p\n", 
     1518    LogFlowFunc(("pDisk=%#p pszBackend=\"%s\" pszFilename=\"%s\" uImageFlags=%#x pszComment=\"%s\" Uuid=%RTuuid uOpenFlags=%#x pVDIfsImage=%#p pVDIfsOperation=%#p\n", 
    14991519                 pDisk, pszBackend, pszFilename, uImageFlags, pszComment, pUuid, uOpenFlags, 
    1500                  pfnProgress, pvUser)); 
     1520                 pVDIfsImage, pVDIfsOperation)); 
     1521 
     1522    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation, 
     1523                                              VDINTERFACETYPE_PROGRESS); 
     1524    PVDINTERFACEPROGRESS pCbProgress = NULL; 
     1525    if (pIfProgress) 
     1526        pCbProgress = VDGetInterfaceProgress(pIfProgress); 
     1527 
    15011528    do 
    15021529    { 
     
    15731600                                        &pDisk->LCHSGeometry, pUuid, 
    15741601                                        uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME, 
    1575                                         pfnProgress, pvUser, 0, 99, 
    1576                                         pDisk->pInterfaces, 
     1602                                        0, 99, 
     1603                                        pDisk->pVDIfsDisk, 
     1604                                        pImage->pVDIfsImage, 
     1605                                        pVDIfsOperation, 
    15771606                                        &pImage->pvBackendData); 
    15781607 
     
    16491678    } 
    16501679 
    1651     if (RT_SUCCESS(rc) && pfnProgress) 
    1652         pfnProgress(NULL /* WARNING! pVM=NULL  */, 100, pvUser); 
     1680    if (RT_SUCCESS(rc) && pCbProgress->pfnProgress) 
     1681        pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100, 
     1682                                 pIfProgress->pvUser); 
    16531683 
    16541684    LogFlowFunc(("returns %Rrc\n", rc)); 
     
    16671697 * @param   nImageFrom      Name of the image file to merge from. 
    16681698 * @param   nImageTo        Name of the image file to merge to. 
    1669  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used. 
    1670  * @param   pvUser          User argument for the progress callback. 
     1699 * @param   pVDIfsOperation Pointer to the per-operation VD interface list. 
    16711700 */ 
    16721701VBOXDDU_DECL(int) VDMerge(PVBOXHDD pDisk, unsigned nImageFrom, 
    1673                           unsigned nImageTo, PFNVMPROGRESS pfnProgress, 
    1674                           void *pvUser) 
     1702                          unsigned nImageTo, PVDINTERFACE pVDIfsOperation) 
    16751703{ 
    16761704    int rc = VINF_SUCCESS; 
    16771705    void *pvBuf = NULL; 
    16781706 
    1679     LogFlowFunc(("pDisk=%#p nImageFrom=%u nImageTo=%u pfnProgress=%#p pvUser=%#p\n", 
    1680                  pDisk, nImageFrom, nImageTo, pfnProgress, pvUser)); 
     1707    LogFlowFunc(("pDisk=%#p nImageFrom=%u nImageTo=%u pVDIfsOperation=%#p\n", 
     1708                 pDisk, nImageFrom, nImageTo, pVDIfsOperation)); 
     1709 
     1710    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation, 
     1711                                              VDINTERFACETYPE_PROGRESS); 
     1712    PVDINTERFACEPROGRESS pCbProgress = NULL; 
     1713    if (pIfProgress) 
     1714        pCbProgress = VDGetInterfaceProgress(pIfProgress); 
     1715 
    16811716    do 
    16821717    { 
     
    17681803                uOffset += cbThisRead; 
    17691804                cbRemaining -= cbThisRead; 
     1805 
     1806                if (pCbProgress->pfnProgress) 
     1807                { 
     1808                    rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 
     1809                                                  uOffset * 99 / cbSize, 
     1810                                                  pIfProgress->pvUser); 
     1811                    if (RT_FAILURE(rc)) 
     1812                        break; 
     1813                } 
    17701814            } while (uOffset < cbSize); 
    17711815        } 
     
    18081852                uOffset += cbThisRead; 
    18091853                cbRemaining -= cbThisRead; 
     1854 
     1855                if (pCbProgress->pfnProgress) 
     1856                { 
     1857                    rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 
     1858                                                  uOffset * 99 / cbSize, 
     1859                                                  pIfProgress->pvUser); 
     1860                    if (RT_FAILURE(rc)) 
     1861                        break; 
     1862                } 
    18101863            } while (uOffset < cbSize); 
    18111864        } 
     
    18681921        RTMemTmpFree(pvBuf); 
    18691922 
    1870     if (RT_SUCCESS(rc) && pfnProgress) 
    1871         pfnProgress(NULL /* WARNING! pVM=NULL */, 100, pvUser); 
     1923    if (RT_SUCCESS(rc) && pCbProgress->pfnProgress) 
     1924        pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100, 
     1925                                 pIfProgress->pvUser); 
    18721926 
    18731927    LogFlowFunc(("returns %Rrc\n", rc)); 
     
    18941948 * @param   fMoveByRename   If true, attempt to perform a move by renaming (if successful the new size is ignored). 
    18951949 * @param   cbSize          New image size (0 means leave unchanged). 
    1896  * @param   pfnProgress     Progress callback. Optional. NULL if not to be used. 
    1897  * @param   pvUser          User argument for the progress callback. 
     1950 * @param   pVDIfsOperation Pointer to the per-operation VD interface list. 
     1951 * @param   pDstVDIfsImage  Pointer to the per-image VD interface list, for the 
     1952 *                          destination image. 
     1953 * @param   pDstVDIfsOperation Pointer to the per-image VD interface list, 
     1954 *                          for the destination image. 
    18981955 */ 
    18991956VBOXDDU_DECL(int) VDCopy(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo, 
    19001957                         const char *pszBackend, const char *pszFilename, 
    19011958                         bool fMoveByRename, uint64_t cbSize, 
    1902                          PFNVMPROGRESS pfnProgress, void *pvUser) 
     1959                         PVDINTERFACE pVDIfsOperation, 
     1960                         PVDINTERFACE pDstVDIfsImage, 
     1961                         PVDINTERFACE pDstVDIfsOperation) 
    19031962{ 
    19041963    int rc, rc2 = VINF_SUCCESS; 
     
    19061965    PVDIMAGE pImageTo = NULL; 
    19071966 
    1908     LogFlowFunc(("pDiskFrom=%#p nImage=%u pDiskTo=%#p pszBackend=\"%s\" pszFilename=\"%s\" fMoveByRename=%d cbSize=%llu pfnProgress=%#p pvUser=%#p\n", 
    1909                  pDiskFrom, nImage, pDiskTo, pszBackend, pszFilename, fMoveByRename, cbSize, pfnProgress, pvUser)); 
     1967    LogFlowFunc(("pDiskFrom=%#p nImage=%u pDiskTo=%#p pszBackend=\"%s\" pszFilename=\"%s\" fMoveByRename=%d cbSize=%llu pVDIfsOperation=%#p pDstVDIfsImage=%#p pDstVDIfsOperation=%#p\n", 
     1968                 pDiskFrom, nImage, pDiskTo, pszBackend, pszFilename, fMoveByRename, cbSize, pVDIfsOperation, pDstVDIfsImage, pDstVDIfsOperation)); 
     1969 
     1970    PVDINTERFACE pIfProgress = VDInterfaceGet(pVDIfsOperation, 
     1971                                              VDINTERFACETYPE_PROGRESS); 
     1972    PVDINTERFACEPROGRESS pCbProgress = NULL; 
     1973    if (pIfProgress) 
     1974        pCbProgress = VDGetInterfaceProgress(pIfProgress); 
     1975 
     1976    PVDINTERFACE pDstIfProgress = VDInterfaceGet(pDstVDIfsOperation, 
     1977                                                 VDINTERFACETYPE_PROGRESS); 
     1978    PVDINTERFACEPROGRESS pDstCbProgress = NULL; 
     1979    if (pDstIfProgress) 
     1980        pDstCbProgress = VDGetInterfaceProgress(pDstIfProgress); 
    19101981 
    19111982    do { 
     
    19422013 
    19432014            /* Open the source image in the destination container. */ 
    1944             rc = VDOpen(pDiskTo, pImageFrom->Backend->pszBackendName, pImageFrom->pszFilename, pImageFrom->uOpenFlags); 
     2015            rc = VDOpen(pDiskTo, pImageFrom->Backend->pszBackendName, pImageFrom->pszFilename, pImageFrom->uOpenFlags, pDstVDIfsImage); 
    19452016            if (RT_FAILURE(rc)) 
    19462017                goto movefail; 
     
    19682039movefail: 
    19692040            /* In case of failure, re-open the source image in the source container. */ 
    1970             rc2 = VDOpen(pDiskFrom, pImageFrom->Backend->pszBackendName, pImageFrom->pszFilename, pImageFrom->uOpenFlags); 
     2041            rc2 = VDOpen(pDiskFrom, pImageFrom->Backend->pszBackendName, pImageFrom->pszFilename, pImageFrom->uOpenFlags, pImageFrom->pVDIfsImage); 
    19712042            if (RT_FAILURE(rc2)) 
    19722043                /** @todo Uncertain what to do on error. If this happens pImageFrom and pImageTo are both closed. */ 
     
    20532124            uOffset += cbThisRead; 
    20542125            cbRemaining -= cbThisRead; 
    2055             if (pfnProgress) 
     2126 
     2127            if (pCbProgress->pfnProgress) 
    20562128            { 
    2057                 rc = pfnProgress(NULL /* WARNING! pVM=NULL  */, 
    2058                                  ((cbSize - cbRemaining) * 100) / cbSize, 
    2059                                  pvUser); 
     2129                rc = pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 
     2130                                              uOffset * 99 / cbSize, 
     2131                                              pIfProgress->pvUser); 
     2132                if (RT_FAILURE(rc)) 
     2133                    break; 
     2134            } 
     2135            if (pDstCbProgress->pfnProgress) 
     2136            { 
     2137                rc = pDstCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 
     2138                                                 uOffset * 99 / cbSize, 
     2139                                                 pDstIfProgress->pvUser); 
    20602140                if (RT_FAILURE(rc)) 
    20612141                    break; 
     
    21082188        RTMemTmpFree(pvBuf); 
    21092189 
    2110     if (RT_SUCCESS(rc) && pfnProgress) 
    2111         pfnProgress(NULL /* WARNING! pVM=NULL  */, 100, pvUser); 
     2190    if (RT_SUCCESS(rc)) 
     2191    { 
     2192        if (pCbProgress->pfnProgress) 
     2193            pCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100, 
     2194                                     pIfProgress->pvUser); 
     2195        if (pDstCbProgress->pfnProgress) 
     2196            pDstCbProgress->pfnProgress(NULL /* WARNING! pVM=NULL */, 100, 
     2197                                        pDstIfProgress->pvUser); 
     2198    } 
    21122199 
    21132200    LogFlowFunc(("returns %Rrc\n", rc)); 
  • trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h

    r11421 r11444  
    7878     *                          unchanged during the lifetime of this image. 
    7979     * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants. 
    80      * @param   pInterfaces     Pointer to the first element of supported interfaces of the caller. 
     80     * @param   pVDIfsDisk      Pointer to the per-disk VD interface list. 
     81     * @param   pVDIfsImage     Pointer to the per-image VD interface list. 
    8182     * @param   ppvBackendData  Opaque state data for this image. 
    8283     */