VirtualBox

Changeset 40027 in vbox for trunk


Ignore:
Timestamp:
Feb 7, 2012 11:09:31 PM (13 years ago)
Author:
vboxsync
Message:

Runtime/Dvm: Add callbacks to query the allocation status of blocks (for filesystem aware image compaction)

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/dvm.h

    r37024 r40027  
    7777} RTDVMVOLTYPE;
    7878
     79/** @defgroup grp_dvm_flags     Flags used by RTDvmCreate.
     80 * @{ */
     81/** DVM flags - Blocks are always marked as unused if the volume has
     82 *              no block status callback set.
     83 *              The default is to mark them as used. */
     84#define DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED    RT_BIT_32(0)
     85/** DVM flags - Space which is unused in the map will be marked as used
     86 *              when calling RTDvmMapQueryBlockStatus(). */
     87#define DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED            RT_BIT_32(1)
     88/** Mask of all valid flags. */
     89#define DVM_FLAGS_MASK (DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED | DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
     90/** @}  */
     91
    7992
    8093/** @defgroup grp_dvm_vol_flags     Volume flags used by DVMVolumeGetFlags.
     
    125138/** Pointer to a read callback. */
    126139typedef FNDVMWRITE *PFNDVMWRITE;
     140
     141/**
     142 * Callback for querying the block allocation status of a volume.
     143 *
     144 * @returns IPRT status code.
     145 * @param   pvUser         Opaque user data passed when setting the callback.
     146 * @param   off            Offset relative to the start of the volume.
     147 * @param   cb             Range to check in bytes.
     148 * @param   pfAllocated    Where to store the allocation status on success.
     149 */
     150typedef DECLCALLBACK(int) FNDVMVOLUMEQUERYBLOCKSTATUS(void *pvUser, uint64_t off,
     151                                                      uint64_t cb, bool *pfAllocated);
     152/** Pointer to a query block allocation status callback. */
     153typedef FNDVMVOLUMEQUERYBLOCKSTATUS *PFNDVMVOLUMEQUERYBLOCKSTATUS;
    127154
    128155/**
     
    138165 * @param   cbDisk      Size of the underlying disk in bytes.
    139166 * @param   cbSector    Size of one sector in bytes.
     167 * @param   fFlags      Combination of RTDVM_FLAGS_*
    140168 * @param   pvUser      Opaque user data passed to the callbacks.
    141169 */
    142170RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
    143171                        PFNDVMWRITE pfnWrite, uint64_t cbDisk,
    144                         uint64_t cbSector, void *pvUser);
     172                        uint64_t cbSector, uint32_t fFlags,
     173                        void *pvUser);
    145174
    146175/**
     
    225254
    226255/**
     256 * Returns whether the given block on the disk is in use.
     257 *
     258 * @returns IPRT status code.
     259 * @param   hVolMgr         The volume manager handler.
     260 * @param   off             The start offset to check for.
     261 * @param   cb              The range in bytes to check.
     262 * @param   pfAllocated     Where to store the status on success.
     263 *
     264 * @remark This method will return true even if a part of the range is not in use.
     265 */
     266RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
     267                                     bool *pfAllocated);
     268
     269/**
    227270 * Retains a valid volume handle.
    228271 *
     
    239282 */
    240283RTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol);
     284
     285/**
     286 * Sets the callback to query the block allocation status for a volume.
     287 * This overwrites any other callback set previously.
     288 *
     289 * @returns nothing.
     290 * @param   hVol                   The volume handle.
     291 * @param   pfnQueryBlockStatus    The callback to set. Can be NULL to disable
     292 *                                 a previous callback.
     293 * @param   pvUser                 Opaque user data passed in the callback.
     294 */
     295RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol,
     296                                                    PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus,
     297                                                    void *pvUser);
    241298
    242299/**
  • trunk/include/iprt/mangling.h

    r39910 r40027  
    410410# define RTDvmMapGetValidVolumes                        RT_MANGLER(RTDvmMapGetValidVolumes)
    411411# define RTDvmMapGetMaxVolumes                          RT_MANGLER(RTDvmMapGetMaxVolumes)
     412# define RTDvmMapQueryBlockStatus                       RT_MANGLER(RTDvmMapQueryBlockStatus)
    412413# define RTDvmMapQueryFirstVolume                       RT_MANGLER(RTDvmMapQueryFirstVolume)
    413414# define RTDvmMapQueryNextVolume                        RT_MANGLER(RTDvmMapQueryNextVolume)
     
    420421# define RTDvmVolumeRead                                RT_MANGLER(RTDvmVolumeRead)
    421422# define RTDvmVolumeWrite                               RT_MANGLER(RTDvmVolumeWrite)
     423# define RTDvmVolumeSetQueryBlockStatusCallback         RT_MANGLER(RTDvmVolumeSetQueryBlockStatusCallback)
    422424# define RTDvmVolumeTypeGetDescr                        RT_MANGLER(RTDvmVolumeTypeGetDescr)
    423425# define RTEnvClone                                     RT_MANGLER(RTEnvClone)
  • trunk/src/VBox/Runtime/common/dvm/dvm.cpp

    r37270 r40027  
    3636#include <iprt/asm.h>
    3737#include <iprt/string.h>
     38#include <iprt/list.h>
    3839#include "internal/dvm.h"
    3940
     
    5556    /** The format specific volume manager data. */
    5657    RTDVMFMT          hVolMgrFmt;
     58    /** Flags passed on manager creation. */
     59    uint32_t          fFlags;
    5760    /** Reference counter. */
    5861    uint32_t volatile cRefs;
     62    /** List of recognised volumes (RTDVMVOLUMEINTERNAL). */
     63    RTLISTANCHOR      VolumeList;
    5964} RTDVMINTERNAL;
    6065/** Pointer to an internal volume manager. */
     
    6772{
    6873    /** The DVM volume magic (RTDVMVOLUME_MAGIC). */
    69     uint32_t          u32Magic;
     74    uint32_t                      u32Magic;
     75    /** Node for the volume list. */
     76    RTLISTNODE                    VolumeNode;
    7077    /** Pointer to the owning volume manager. */
    71     PRTDVMINTERNAL    pVolMgr;
     78    PRTDVMINTERNAL                pVolMgr;
    7279    /** Format specific volume data. */
    73     RTDVMVOLUMEFMT    hVolFmt;
     80    RTDVMVOLUMEFMT                hVolFmt;
     81    /** Set block status.callback */
     82    PFNDVMVOLUMEQUERYBLOCKSTATUS  pfnQueryBlockStatus;
     83    /** Opaque user data. */
     84    void                         *pvUser;
    7485    /** Reference counter. */
    75     uint32_t volatile cRefs;
     86    uint32_t volatile             cRefs;
    7687} RTDVMVOLUMEINTERNAL;
    7788/** Pointer to an internal volume. */
     
    118129};
    119130
     131/**
     132 * Creates a new volume.
     133 *
     134 * @returns IPRT status code.
     135 * @param   pThis    The DVM map instance.
     136 * @param   hVolFmt  The format specific volume handle.
     137 * @param   phVol    Where to store the generic volume handle on success.
     138 */
     139static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
     140                             PRTDVMVOLUME phVol)
     141{
     142    int rc = VINF_SUCCESS;
     143    PRTDVMVOLUMEINTERNAL pVol = NULL;
     144
     145    pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
     146    if (VALID_PTR(pVol))
     147    {
     148        pVol->u32Magic = RTDVMVOLUME_MAGIC;
     149        pVol->cRefs    = 0;
     150        pVol->pVolMgr  = pThis;
     151        pVol->hVolFmt  = hVolFmt;
     152
     153        *phVol = pVol;
     154    }
     155    else
     156        rc = VERR_NO_MEMORY;
     157
     158    return rc;
     159}
     160
     161/**
     162 * Destroys a volume handle.
     163 *
     164 * @param   pThis               The volume to destroy.
     165 */
     166static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
     167{
     168    PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
     169
     170    AssertPtr(pVolMgr);
     171
     172    /* Close the volume. */
     173    pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
     174
     175    pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
     176    pThis->pVolMgr  = NULL;
     177    pThis->hVolFmt  = NIL_RTDVMVOLUMEFMT;
     178    RTMemFree(pThis);
     179
     180    /* Release the reference of the volume manager. */
     181    RTDvmRelease(pVolMgr);
     182}
     183
    120184RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
    121185                        PFNDVMWRITE pfnWrite, uint64_t cbDisk,
    122                         uint64_t cbSector, void *pvUser)
     186                        uint64_t cbSector, uint32_t fFlags, void *pvUser)
    123187{
    124188    int rc = VINF_SUCCESS;
    125189    PRTDVMINTERNAL pThis;
     190
     191    AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK),
     192                    ("Invalid flags given %#x\n", fFlags),
     193                    VERR_INVALID_PARAMETER);
    126194
    127195    pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
     
    136204        pThis->pDvmFmtOps       = NULL;
    137205        pThis->hVolMgrFmt       = NIL_RTDVMFMT;
     206        pThis->fFlags           = fFlags;
    138207        pThis->cRefs            = 1;
     208        RTListInit(&pThis->VolumeList);
    139209        *phVolMgr = pThis;
    140210    }
     
    232302            rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
    233303            if (RT_SUCCESS(rc))
     304            {
     305                uint32_t cVols;
     306
    234307                pThis->pDvmFmtOps = pDvmFmtOpsMatch;
     308
     309                cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
     310
     311                /* Construct volume list. */
     312                if (cVols)
     313                {
     314                    PRTDVMVOLUMEINTERNAL pVol = NULL;
     315                    RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
     316
     317                    rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
     318                    if (RT_SUCCESS(rc))
     319                    {
     320                        rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
     321                        if (RT_FAILURE(rc))
     322                            pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
     323                    }
     324
     325                    if (RT_SUCCESS(rc))
     326                    {
     327                        cVols--;
     328                        RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
     329
     330                        while (   cVols > 0
     331                               && RT_SUCCESS(rc))
     332                        {
     333                            rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
     334                            if (RT_SUCCESS(rc))
     335                            {
     336                                rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
     337                                if (RT_FAILURE(rc))
     338                                    pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
     339                                else
     340                                    RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
     341                                cVols--;
     342                            }
     343                        }
     344                    }
     345
     346                    if (RT_FAILURE(rc))
     347                    {
     348                        PRTDVMVOLUMEINTERNAL pItNext, pIt;
     349
     350                        /* Remove all entries. */
     351                        RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
     352                        {
     353                            RTListNodeRemove(&pIt->VolumeNode);
     354                            rtDvmVolumeDestroy(pIt);
     355                        }
     356                    }
     357                }
     358            }
    235359        }
    236360        else
     
    243367RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
    244368{
    245     int rc = VINF_SUCCESS;
     369    int rc = VERR_NOT_SUPPORTED;
    246370    PRTDVMINTERNAL pThis = hVolMgr;
    247371    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     
    297421}
    298422
    299 static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
    300                              PRTDVMVOLUME phVol)
    301 {
    302     int rc = VINF_SUCCESS;
    303     PRTDVMVOLUMEINTERNAL pVol = NULL;
    304 
    305     pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
    306     if (VALID_PTR(pVol))
    307     {
    308         pVol->u32Magic = RTDVMVOLUME_MAGIC;
    309         pVol->cRefs    = 1;
    310         pVol->pVolMgr  = pThis;
    311         pVol->hVolFmt  = hVolFmt;
    312 
    313         /* Reference the volume manager. */
    314         RTDvmRetain(pThis);
    315         *phVol = pVol;
    316     }
    317     else
    318         rc = VERR_NO_MEMORY;
    319 
    320     return rc;
    321 }
    322 
    323423RTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol)
    324424{
    325     int rc = VINF_SUCCESS;
     425    int rc = VERR_DVM_MAP_EMPTY;
    326426    PRTDVMINTERNAL pThis = hVolMgr;
    327427    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     
    330430    AssertPtrReturn(phVol, VERR_INVALID_POINTER);
    331431
    332     RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
    333     rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
    334     if (RT_SUCCESS(rc))
    335     {
    336         rc = rtDvmVolumeCreate(pThis, hVolFmt, phVol);
    337         if (RT_FAILURE(rc))
    338             pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
     432    PRTDVMVOLUMEINTERNAL pVol = RTListGetFirst(&pThis->VolumeList, RTDVMVOLUMEINTERNAL, VolumeNode);
     433    if (pVol)
     434    {
     435        rc = VINF_SUCCESS;
     436        RTDvmVolumeRetain(pVol);
     437        *phVol = pVol;
    339438    }
    340439
     
    344443RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
    345444{
    346     int rc = VINF_SUCCESS;
     445    int rc = VERR_DVM_MAP_NO_VOLUME;
    347446    PRTDVMINTERNAL       pThis = hVolMgr;
    348447    PRTDVMVOLUMEINTERNAL pVol = hVol;
     
    354453    AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
    355454
    356     RTDVMVOLUMEFMT hVolFmtNext = NIL_RTDVMVOLUMEFMT;
    357     rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmtNext);
    358     if (RT_SUCCESS(rc))
    359     {
    360         rc = rtDvmVolumeCreate(pThis, hVolFmtNext, phVolNext);
    361         if (RT_FAILURE(rc))
    362             pThis->pDvmFmtOps->pfnVolumeClose(hVolFmtNext);
    363     }
     455    PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol,
     456                                                  RTDVMVOLUMEINTERNAL, VolumeNode);
     457    if (pVolNext)
     458    {
     459        rc = VINF_SUCCESS;
     460        RTDvmVolumeRetain(pVolNext);
     461        *phVolNext = pVolNext;
     462    }
     463
     464    return rc;
     465}
     466
     467RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
     468                                     bool *pfAllocated)
     469{
     470    int rc = VINF_SUCCESS;
     471    bool fAllocated = false;
     472    PRTDVMINTERNAL       pThis = hVolMgr;
     473    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     474    AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER);
     475    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
     476    AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
     477    AssertReturn(off + cb <= pThis->DvmDisk.cbDisk * pThis->DvmDisk.cbSector,
     478                 VERR_INVALID_PARAMETER);
     479
     480    while (   cb > 0
     481           && !fAllocated)
     482    {
     483        PRTDVMVOLUMEINTERNAL pVol;
     484        bool fVolFound = false;
     485        size_t cbIntersect;
     486        uint64_t offVol;
     487
     488        /*
     489         * Search through all volumes. It is not possible to
     490         * get all start sectors and sizes of all volumes here
     491         * because volumes can be scattered around the disk for certain formats.
     492         * Linux LVM is one example, extents of logical volumes don't need to be
     493         * contigous on the medium.
     494         */
     495        RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode)
     496        {
     497            bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off,
     498                                                                              cb, &offVol,
     499                                                                              &cbIntersect);
     500            if (fIntersect)
     501            {
     502                fVolFound = true;
     503                if (pVol->pfnQueryBlockStatus)
     504                {
     505                    bool fVolAllocated = true;
     506
     507                    rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
     508                                                   &fVolAllocated);
     509                    if (RT_FAILURE(rc))
     510                        break;
     511                }
     512                else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED))
     513                    fAllocated = true;
     514                /* else, flag is set, continue. */
     515
     516                cb  -= cbIntersect;
     517                off += cbIntersect;
     518                break;
     519            }
     520        }
     521
     522        if (!fVolFound)
     523        {
     524            if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
     525                fAllocated = true;
     526
     527            cb  -= pThis->DvmDisk.cbSector;
     528            off += pThis->DvmDisk.cbSector;
     529        }
     530    }
     531
     532    *pfAllocated = fAllocated;
    364533
    365534    return rc;
     
    373542
    374543    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
    375     AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
     544    AssertMsg(cRefs >= 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
     545    if (cRefs == 1)
     546        RTDvmRetain(pThis->pVolMgr);
    376547    return cRefs;
    377 }
    378 
    379 /**
    380  * Destroys a volume handle.
    381  *
    382  * @param   pThis               The volume to destroy.
    383  */
    384 static void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
    385 {
    386     PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
    387 
    388     AssertPtr(pVolMgr);
    389 
    390     /* Close the volume. */
    391     pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
    392 
    393     pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
    394     pThis->pVolMgr  = NULL;
    395     pThis->hVolFmt  = NIL_RTDVMVOLUMEFMT;
    396     RTMemFree(pThis);
    397 
    398     /* Release the reference of the volume manager. */
    399     RTDvmRelease(pVolMgr);
    400548}
    401549
     
    411559    AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
    412560    if (cRefs == 0)
    413         rtDvmVolumeDestroy(pThis);
     561    {
     562        /* Release the volume manager. */
     563        pThis->pfnQueryBlockStatus = NULL;
     564        RTDvmRelease(pThis->pVolMgr);
     565    }
    414566    return cRefs;
     567}
     568
     569RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol,
     570                                                    PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus,
     571                                                    void *pvUser)
     572{
     573    PRTDVMVOLUMEINTERNAL pThis = hVol;
     574    AssertPtrReturnVoid(pThis);
     575    AssertReturnVoid(pThis->u32Magic == RTDVMVOLUME_MAGIC);
     576
     577    pThis->pfnQueryBlockStatus = pfnQueryBlockStatus;
     578    pThis->pvUser = pvUser;
    415579}
    416580
  • trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp

    r39083 r40027  
    466466}
    467467
     468DECLCALLBACK(bool) rtDvmFmtBsdLblVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt,
     469                                                           uint64_t offStart, size_t cbRange,
     470                                                           uint64_t *poffVol,
     471                                                           size_t *pcbIntersect)
     472{
     473    bool fIntersect = false;
     474    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
     475
     476    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
     477    {
     478        fIntersect    = true;
     479        *poffVol      = offStart - pVol->offStart;
     480        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
     481    }
     482
     483    return fIntersect;
     484}
     485
    468486DECLCALLBACK(int) rtDvmFmtBsdLblVolumeRead(RTDVMVOLUMEFMT hVolFmt, uint64_t off, void *pvBuf, size_t cbRead)
    469487{
     
    512530    /* pfnVolumeGetFlags */
    513531    rtDvmFmtBsdLblVolumeGetFlags,
     532    /* pfnVolumeIsRangeIntersecting */
     533    rtDvmFmtBsdLblVolumeIsRangeIntersecting,
    514534    /* pfnVolumeRead */
    515535    rtDvmFmtBsdLblVolumeRead,
  • trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp

    r39083 r40027  
    482482    NOREF(hVolFmt); /* No supported flags for now. */
    483483    return 0;
     484}
     485
     486DECLCALLBACK(bool) rtDvmFmtGptVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt,
     487                                                        uint64_t offStart, size_t cbRange,
     488                                                        uint64_t *poffVol,
     489                                                        size_t *pcbIntersect)
     490{
     491    bool fIntersect = false;
     492    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
     493
     494    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
     495    {
     496        fIntersect    = true;
     497        *poffVol      = offStart - pVol->offStart;
     498        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
     499    }
     500
     501    return fIntersect;
    484502}
    485503
     
    530548    /* pfnVolumeGetFlags */
    531549    rtDvmFmtGptVolumeGetFlags,
     550    /* pfnVolumeIsRangeIntersecting */
     551    rtDvmFmtGptVolumeIsRangeIntersecting,
    532552    /* pfnVolumeRead */
    533553    rtDvmFmtGptVolumeRead,
  • trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp

    r39083 r40027  
    351351
    352352    return fFlags;
     353}
     354
     355DECLCALLBACK(bool) rtDvmFmtMbrVolumeIsRangeIntersecting(RTDVMVOLUMEFMT hVolFmt,
     356                                                        uint64_t offStart, size_t cbRange,
     357                                                        uint64_t *poffVol,
     358                                                        size_t *pcbIntersect)
     359{
     360    bool fIntersect = false;
     361    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
     362
     363    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
     364    {
     365        fIntersect    = true;
     366        *poffVol      = offStart - pVol->offStart;
     367        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
     368    }
     369
     370    return fIntersect;
    353371}
    354372
     
    399417    /* pfnVolumeGetFlags */
    400418    rtDvmFmtMbrVolumeGetFlags,
     419    /* pfnVOlumeIsRangeIntersecting */
     420    rtDvmFmtMbrVolumeIsRangeIntersecting,
    401421    /* pfnVolumeRead */
    402422    rtDvmFmtMbrVolumeRead,
  • trunk/src/VBox/Runtime/testcase/tstRTDvm.cpp

    r39632 r40027  
    9292    RTTestSubF(hTest, "Create DVM");
    9393    RTDVM hVolMgr;
    94     rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, pDisk);
     94    rc = RTDvmCreate(&hVolMgr, dvmDiskRead, dvmDiskWrite, cb, 512, 0, pDisk);
    9595    if (RT_FAILURE(rc))
    9696    {
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