VirtualBox

Changeset 34224 in vbox for trunk


Ignore:
Timestamp:
Nov 21, 2010 11:52:04 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
67969
Message:

DrvVD: Block cache integration, work in progress

File:
1 edited

Legend:

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

    r34217 r34224  
    2424#include <VBox/pdmdrv.h>
    2525#include <VBox/pdmasynccompletion.h>
     26#include <VBox/pdmblkcache.h>
    2627#include <iprt/asm.h>
    2728#include <iprt/alloc.h>
     
    193194    /** Interface list for the cache image. */
    194195    PVDINTERFACE        pVDIfsCache;
     196
     197    /** The block cache handle if configured. */
     198    PPDMBLKCACHE        pBlkCache;
    195199} VBOXDISK, *PVBOXDISK;
    196200
     
    16871691    PVBOXDISK pThis = (PVBOXDISK)pvUser1;
    16881692
    1689     int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,
    1690                                                                   pvUser2, rcReq);
    1691     AssertRC(rc);
     1693    if (!pThis->pBlkCache)
     1694    {
     1695        int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,
     1696                                                                      pvUser2, rcReq);
     1697        AssertRC(rc);
     1698    }
     1699    else
     1700        PDMR3BlkCacheIoXferComplete(pThis->pBlkCache, (PPDMBLKCACHEIOXFER)pvUser2, rcReq);
    16921701}
    16931702
     
    16961705                                        size_t cbRead, void *pvUser)
    16971706{
    1698     LogFlowFunc(("uOffset=%#llx paSeg=%#p cSeg=%u cbRead=%d\n pvUser=%#p",
     1707    LogFlowFunc(("uOffset=%#llx paSeg=%#p cSeg=%u cbRead=%d pvUser=%#p\n",
    16991708                 uOffset, paSeg, cSeg, cbRead, pvUser));
     1709    int rc = VINF_SUCCESS;
    17001710    PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
    17011711
     
    17041714    RTSGBUF SgBuf;
    17051715    RTSgBufInit(&SgBuf, paSeg, cSeg);
    1706     int rc = VDAsyncRead(pThis->pDisk, uOffset, cbRead, &SgBuf,
     1716    if (!pThis->pBlkCache)
     1717        rc = VDAsyncRead(pThis->pDisk, uOffset, cbRead, &SgBuf,
    17071718                         drvvdAsyncReqComplete, pThis, pvUser);
     1719    else
     1720    {
     1721        rc = PDMR3BlkCacheRead(pThis->pBlkCache, uOffset, &SgBuf, cbRead, pvUser);
     1722        if (rc == VINF_AIO_TASK_PENDING)
     1723            rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     1724        else if (rc == VINF_SUCCESS)
     1725            rc = VINF_VD_ASYNC_IO_FINISHED;
     1726    }
     1727
    17081728    LogFlowFunc(("returns %Rrc\n", rc));
    17091729    return rc;
     
    17161736    LogFlowFunc(("uOffset=%#llx paSeg=%#p cSeg=%u cbWrite=%d pvUser=%#p\n",
    17171737                 uOffset, paSeg, cSeg, cbWrite, pvUser));
     1738    int rc = VINF_SUCCESS;
    17181739    PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
    17191740
     
    17221743    RTSGBUF SgBuf;
    17231744    RTSgBufInit(&SgBuf, paSeg, cSeg);
    1724     int rc = VDAsyncWrite(pThis->pDisk, uOffset, cbWrite, &SgBuf,
     1745
     1746    if (!pThis->pBlkCache)
     1747        rc = VDAsyncWrite(pThis->pDisk, uOffset, cbWrite, &SgBuf,
    17251748                          drvvdAsyncReqComplete, pThis, pvUser);
     1749    else
     1750    {
     1751        rc = PDMR3BlkCacheWrite(pThis->pBlkCache, uOffset, &SgBuf, cbWrite, pvUser);
     1752        if (rc == VINF_AIO_TASK_PENDING)
     1753            rc = VERR_VD_ASYNC_IO_IN_PROGRESS;
     1754        else if (rc == VINF_SUCCESS)
     1755            rc = VINF_VD_ASYNC_IO_FINISHED;
     1756    }
     1757
    17261758    LogFlowFunc(("returns %Rrc\n", rc));
    17271759    return rc;
     
    17311763{
    17321764    LogFlowFunc(("pvUser=%#p\n", pvUser));
     1765    int rc = VINF_SUCCESS;
    17331766    PVBOXDISK pThis = PDMIMEDIAASYNC_2_VBOXDISK(pInterface);
    1734     int rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, pvUser);
     1767
     1768    if (!pThis->pBlkCache)
     1769        rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, pvUser);
     1770    else
     1771    {
     1772        rc = PDMR3BlkCacheFlush(pThis->pBlkCache, pvUser);
     1773    }
    17351774    LogFlowFunc(("returns %Rrc\n", rc));
    17361775    return rc;
    17371776}
    17381777
     1778/** @copydoc FNPDMBLKCACHEXFERCOMPLETEDRV */
     1779static void drvvdBlkCacheXferComplete(PPDMDRVINS pDrvIns, void *pvUser, int rcReq)
     1780{
     1781    PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
     1782
     1783    int rc = pThis->pDrvMediaAsyncPort->pfnTransferCompleteNotify(pThis->pDrvMediaAsyncPort,
     1784                                                                  pvUser, rcReq);
     1785    AssertRC(rc);
     1786}
     1787
     1788/** @copydoc FNPDMBLKCACHEXFERENQUEUEDRV */
     1789static int drvvdBlkCacheXferEnqueue(PPDMDRVINS pDrvIns,
     1790                                    PDMBLKCACHEXFERDIR enmXferDir,
     1791                                    uint64_t off, size_t cbXfer,
     1792                                    PCRTSGBUF pcSgBuf, PPDMBLKCACHEIOXFER hIoXfer)
     1793{
     1794    int rc = VINF_SUCCESS;
     1795    PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
     1796
     1797    switch (enmXferDir)
     1798    {
     1799        case PDMBLKCACHEXFERDIR_READ:
     1800            rc = VDAsyncRead(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdAsyncReqComplete,
     1801                             pThis, hIoXfer);
     1802            break;
     1803        case PDMBLKCACHEXFERDIR_WRITE:
     1804            rc = VDAsyncWrite(pThis->pDisk, off, cbXfer, pcSgBuf, drvvdAsyncReqComplete,
     1805                              pThis, hIoXfer);
     1806            break;
     1807        case PDMBLKCACHEXFERDIR_FLUSH:
     1808            rc = VDAsyncFlush(pThis->pDisk, drvvdAsyncReqComplete, pThis, hIoXfer);
     1809            break;
     1810        default:
     1811            AssertMsgFailed(("Invalid transfer type %d\n", enmXferDir));
     1812            rc = VERR_INVALID_PARAMETER;
     1813    }
     1814
     1815    if (rc == VINF_VD_ASYNC_IO_FINISHED)
     1816        PDMR3BlkCacheIoXferComplete(pThis->pBlkCache, hIoXfer, VINF_SUCCESS);
     1817    else if (RT_FAILURE(rc) && rc != VERR_VD_ASYNC_IO_IN_PROGRESS)
     1818        PDMR3BlkCacheIoXferComplete(pThis->pBlkCache, hIoXfer, rc);
     1819
     1820    return VINF_SUCCESS;
     1821}
    17391822
    17401823/*******************************************************************************
     
    19061989    }
    19071990
     1991    if (VALID_PTR(pThis->pBlkCache))
     1992    {
     1993        PDMR3BlkCacheRelease(pThis->pBlkCache);
     1994        pThis->pBlkCache = NULL;
     1995    }
     1996
    19081997    if (VALID_PTR(pThis->pDisk))
    19091998    {
     
    20132102    bool        fHostIP = false;
    20142103    bool        fUseNewIo = false;
     2104    bool        fUseBlockCache = false;
    20152105    unsigned    iLevel = 0;
    20162106    PCFGMNODE   pCurNode = pCfg;
     
    20292119                                          "ReadOnly\0MaybeReadOnly\0TempReadOnly\0Shareable\0HonorZeroWrites\0"
    20302120                                          "HostIPStack\0UseNewIo\0BootAcceleration\0BootAccelerationBuffer\0"
    2031                                           "SetupMerge\0MergeSource\0MergeTarget\0BwGroup\0Type\0"
     2121                                          "SetupMerge\0MergeSource\0MergeTarget\0BwGroup\0Type\0BlockCache\0"
    20322122                                          "CachePath\0CacheFormat\0");
    20332123        }
     
    21362226                break;
    21372227            }
     2228            rc = CFGMR3QueryBoolDef(pCurNode, "BlockCache", &fUseBlockCache, false);
     2229            if (RT_FAILURE(rc))
     2230            {
     2231                rc = PDMDRV_SET_ERROR(pDrvIns, rc,
     2232                                      N_("DrvVD: Configuration error: Querying \"BlockCache\" as boolean failed"));
     2233                break;
     2234            }
    21382235            rc = CFGMR3QueryStringAlloc(pCurNode, "BwGroup", &pThis->pszBwGroup);
    21392236            if (RT_FAILURE(rc) && rc != VERR_CFGM_VALUE_NOT_FOUND)
     
    25222619        rc = PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRIVER_INVALID_PROPERTIES,
    25232620                              N_("DrvVD: Configuration error: Inconsistent image merge data"));
     2621    }
     2622
     2623    /* Create the block cache if enabled. */
     2624    if (   fUseBlockCache
     2625        && RT_SUCCESS(rc))
     2626    {
     2627        /* Create a unique ID from the UUID of the last image in the chain. */
     2628        char achUuid[RTUUID_STR_LENGTH + 1];
     2629        RTUUID Uuid;
     2630
     2631        /** @todo: Images without UUIDs. */
     2632        rc = VDGetUuid(pThis->pDisk, VDGetCount(pThis->pDisk) - 1, &Uuid);
     2633        AssertRC(rc);
     2634
     2635        memset(achUuid, 0, sizeof(achUuid));
     2636        rc = RTUuidToStr(&Uuid, achUuid, RTUUID_STR_LENGTH);
     2637        AssertRC(rc);
     2638
     2639        rc = PDMDrvHlpBlkCacheRetain(pDrvIns, &pThis->pBlkCache,
     2640                                     drvvdBlkCacheXferComplete,
     2641                                     drvvdBlkCacheXferEnqueue,
     2642                                     achUuid);
     2643        if (rc == VERR_NOT_SUPPORTED)
     2644        {
     2645            LogRel(("VD: Block cache is not supported\n"));
     2646            rc = VINF_SUCCESS;
     2647        }
     2648        else
     2649            AssertRC(rc);
    25242650    }
    25252651
Note: See TracChangeset for help on using the changeset viewer.

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