VirtualBox

Ignore:
Timestamp:
Nov 7, 2017 6:59:38 PM (7 years ago)
Author:
vboxsync
Message:

iprt/dvm: Some API adjusting to VFS - work in progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dvm/dvm.cpp

    r69111 r69609  
    101101 * Supported volume formats.
    102102 */
    103 static PCRTDVMFMTOPS g_aDvmFmts[] =
     103static PCRTDVMFMTOPS const g_aDvmFmts[] =
    104104{
    105105    &g_rtDvmFmtMbr,
     
    113113 * This is indexed by RTDVMVOLTYPE.
    114114 */
    115 static const char * g_apcszDvmVolTypes[] =
     115static const char * const g_apszDvmVolTypes[] =
    116116{
    117117    "Invalid",
     
    130130    "Solaris"
    131131};
     132AssertCompile(RT_ELEMENTS(g_apszDvmVolTypes) == RTDVMVOLTYPE_END);
     133
    132134
    133135/**
     
    139141 * @param   phVol    Where to store the generic volume handle on success.
    140142 */
    141 static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
    142                              PRTDVMVOLUME phVol)
    143 {
    144     int rc = VINF_SUCCESS;
    145     PRTDVMVOLUMEINTERNAL pVol = NULL;
    146 
    147     pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
     143static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUME phVol)
     144{
     145    PRTDVMVOLUMEINTERNAL pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
    148146    if (pVol)
    149147    {
     
    154152
    155153        *phVol = pVol;
    156     }
    157     else
    158         rc = VERR_NO_MEMORY;
    159 
    160     return rc;
     154        return VINF_SUCCESS;
     155    }
     156    return VERR_NO_MEMORY;
    161157}
    162158
     
    184180}
    185181
    186 RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
    187                         PFNDVMWRITE pfnWrite, uint64_t cbDisk,
    188                         uint64_t cbSector, uint32_t fFlags, void *pvUser)
    189 {
    190     int rc = VINF_SUCCESS;
    191     PRTDVMINTERNAL pThis;
    192 
    193     AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK),
    194                     ("Invalid flags given %#x\n", fFlags),
    195                     VERR_INVALID_PARAMETER);
    196 
    197     pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
    198     if (pThis)
    199     {
    200         pThis->u32Magic         = RTDVM_MAGIC;
    201         pThis->DvmDisk.cbDisk   = cbDisk;
    202         pThis->DvmDisk.cbSector = cbSector;
    203         pThis->DvmDisk.pvUser   = pvUser;
    204         pThis->DvmDisk.pfnRead  = pfnRead;
    205         pThis->DvmDisk.pfnWrite = pfnWrite;
    206         pThis->pDvmFmtOps       = NULL;
    207         pThis->hVolMgrFmt       = NIL_RTDVMFMT;
    208         pThis->fFlags           = fFlags;
    209         pThis->cRefs            = 1;
    210         RTListInit(&pThis->VolumeList);
    211         *phVolMgr = pThis;
    212     }
    213     else
     182
     183RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, RTVFSFILE hVfsFile, uint32_t cbSector, uint32_t fFlags)
     184{
     185    AssertMsgReturn(!(fFlags & ~DVM_FLAGS_VALID_MASK), ("Invalid flags given %#x\n", fFlags), VERR_INVALID_FLAGS);
     186    uint32_t cRefs = RTVfsFileRetain(hVfsFile);
     187    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     188
     189    uint64_t cbDisk;
     190    int rc = RTVfsFileGetSize(hVfsFile, &cbDisk);
     191    if (RT_SUCCESS(rc))
     192    {
     193        PRTDVMINTERNAL pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
     194        if (pThis)
     195        {
     196            pThis->u32Magic         = RTDVM_MAGIC;
     197            pThis->DvmDisk.cbDisk   = cbDisk;
     198            pThis->DvmDisk.cbSector = cbSector;
     199            pThis->DvmDisk.hVfsFile = hVfsFile;
     200
     201            pThis->pDvmFmtOps       = NULL;
     202            pThis->hVolMgrFmt       = NIL_RTDVMFMT;
     203            pThis->fFlags           = fFlags;
     204            pThis->cRefs            = 1;
     205            RTListInit(&pThis->VolumeList);
     206
     207            *phVolMgr = pThis;
     208            return VINF_SUCCESS;
     209        }
    214210        rc = VERR_NO_MEMORY;
    215 
     211    }
     212    RTVfsFileRelease(hVfsFile);
    216213    return rc;
    217214}
     215
    218216
    219217RTDECL(uint32_t) RTDvmRetain(RTDVM hVolMgr)
     
    235233static void rtDvmDestroy(PRTDVMINTERNAL pThis)
    236234{
     235    pThis->u32Magic = RTDVM_MAGIC_DEAD;
     236
    237237    if (pThis->hVolMgrFmt != NIL_RTDVMFMT)
    238238    {
     
    242242        pThis->pDvmFmtOps->pfnClose(pThis->hVolMgrFmt);
    243243        pThis->hVolMgrFmt = NIL_RTDVMFMT;
    244     }
    245 
    246     pThis->DvmDisk.cbDisk   = 0;
    247     pThis->DvmDisk.pvUser   = NULL;
    248     pThis->DvmDisk.pfnRead  = NULL;
    249     pThis->DvmDisk.pfnWrite = NULL;
    250     pThis->u32Magic         = RTDVM_MAGIC_DEAD;
     244        pThis->pDvmFmtOps = NULL;
     245    }
     246
     247    pThis->DvmDisk.cbDisk = 0;
     248    pThis->DvmDisk.cbSector = 0;
     249    if (pThis->DvmDisk.hVfsFile != NIL_RTVFSFILE)
     250    {
     251        RTVfsFileRelease(pThis->DvmDisk.hVfsFile);
     252        pThis->DvmDisk.hVfsFile = NIL_RTVFSFILE;
     253    }
    251254    RTMemFree(pThis);
    252255}
     
    269272RTDECL(int) RTDvmMapOpen(RTDVM hVolMgr)
    270273{
    271     int            rc = VINF_SUCCESS;
    272     uint32_t       uScoreMax = RTDVM_MATCH_SCORE_UNSUPPORTED;
     274    PRTDVMINTERNAL pThis = hVolMgr;
     275    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     276    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
     277    AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_WRONG_ORDER);
     278
     279    Assert(!pThis->pDvmFmtOps);
     280
     281    /*
     282     * Let each format backend have a go at the disk, pick the one which scores the highest.
     283     */
     284    int            rc              = VINF_SUCCESS;
     285    uint32_t       uScoreMax       = RTDVM_MATCH_SCORE_UNSUPPORTED;
    273286    PCRTDVMFMTOPS  pDvmFmtOpsMatch = NULL;
    274     PRTDVMINTERNAL pThis = hVolMgr;
    275     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    276     AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
    277     AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
    278 
    279     Assert(!pThis->pDvmFmtOps);
    280 
    281287    for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
    282288    {
    283         uint32_t uScore;
     289        uint32_t uScore = 0;
    284290        PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
    285291
    286292        rc = pDvmFmtOps->pfnProbe(&pThis->DvmDisk, &uScore);
    287         if (   RT_SUCCESS(rc)
    288             && uScore > uScoreMax)
     293        if (RT_SUCCESS(rc))
    289294        {
    290             pDvmFmtOpsMatch = pDvmFmtOps;
    291             uScoreMax       = uScore;
    292         }
    293         else if (RT_FAILURE(rc))
    294             break;
    295     }
    296 
    297     if (RT_SUCCESS(rc))
    298     {
    299         if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
    300         {
    301             AssertPtr(pDvmFmtOpsMatch);
    302 
    303             /* Open the format. */
    304             rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
    305             if (RT_SUCCESS(rc))
     295            if (uScore > uScoreMax)
    306296            {
    307                 uint32_t cVols;
    308 
    309                 pThis->pDvmFmtOps = pDvmFmtOpsMatch;
    310 
    311                 cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
    312 
    313                 /* Construct volume list. */
    314                 if (cVols)
    315                 {
    316                     PRTDVMVOLUMEINTERNAL pVol = NULL;
    317                     RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
    318 
    319                     rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
    320                     if (RT_SUCCESS(rc))
    321                     {
    322                         rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
    323                         if (RT_FAILURE(rc))
    324                             pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
    325                     }
    326 
    327                     if (RT_SUCCESS(rc))
    328                     {
    329                         cVols--;
    330                         RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
    331 
    332                         while (   cVols > 0
    333                                && RT_SUCCESS(rc))
    334                         {
    335                             rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
    336                             if (RT_SUCCESS(rc))
    337                             {
    338                                 rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
    339                                 if (RT_FAILURE(rc))
    340                                     pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
    341                                 else
    342                                     RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
    343                                 cVols--;
    344                             }
    345                         }
    346                     }
    347 
    348                     if (RT_FAILURE(rc))
    349                     {
    350                         /* Remove all entries. */
    351                         PRTDVMVOLUMEINTERNAL pItNext, pIt;
    352                         RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
    353                         {
    354                             RTListNodeRemove(&pIt->VolumeNode);
    355                             rtDvmVolumeDestroy(pIt);
    356                         }
    357                     }
    358                 }
     297                pDvmFmtOpsMatch = pDvmFmtOps;
     298                uScoreMax       = uScore;
    359299            }
    360300        }
    361301        else
    362             rc = VERR_NOT_SUPPORTED;
    363     }
    364 
     302            return rc;
     303    }
     304    if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
     305    {
     306        AssertPtr(pDvmFmtOpsMatch);
     307
     308        /*
     309         * Open the format.
     310         */
     311        rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
     312        if (RT_SUCCESS(rc))
     313        {
     314            pThis->pDvmFmtOps = pDvmFmtOpsMatch;
     315
     316            /*
     317             * Construct volume list (we're done if none).
     318             */
     319            uint32_t cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
     320            if (cVols == 0)
     321                return VINF_SUCCESS;
     322
     323            /* First volume. */
     324            RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
     325            rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
     326            if (RT_SUCCESS(rc))
     327            {
     328                for (;;)
     329                {
     330                    PRTDVMVOLUMEINTERNAL pVol = NULL;
     331                    rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
     332                    if (RT_FAILURE(rc))
     333                    {
     334                        pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
     335                        break;
     336                    }
     337                    RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
     338
     339                    /* Done?*/
     340                    cVols--;
     341                    if (cVols < 1)
     342                        return VINF_SUCCESS;
     343
     344                    /* Next volume. */
     345                    rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
     346                    if (RT_FAILURE(rc))
     347                        break;
     348                }
     349
     350                /* Bail out. */
     351                PRTDVMVOLUMEINTERNAL pItNext, pIt;
     352                RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
     353                {
     354                    RTListNodeRemove(&pIt->VolumeNode);
     355                    rtDvmVolumeDestroy(pIt);
     356                }
     357            }
     358
     359            /** @todo shouldn't we close the format too here?  */
     360        }
     361    }
     362    else
     363        rc = VERR_NOT_SUPPORTED;
    365364    return rc;
    366365}
     
    368367RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
    369368{
    370     int rc = VERR_NOT_SUPPORTED;
    371369    PRTDVMINTERNAL pThis = hVolMgr;
    372370    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    373371    AssertPtrReturn(pszFmt, VERR_INVALID_POINTER);
    374372    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
    375     AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
     373    AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_WRONG_ORDER);
    376374
    377375    for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
    378376    {
    379377        PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
    380 
    381378        if (!RTStrCmp(pDvmFmtOps->pcszFmt, pszFmt))
    382379        {
    383             rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
     380            int rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
    384381            if (RT_SUCCESS(rc))
    385382                pThis->pDvmFmtOps = pDvmFmtOps;
    386 
    387             break;
     383            return rc;
    388384        }
    389385    }
    390 
    391     return rc;
     386    return VERR_NOT_SUPPORTED;
    392387}
    393388
     
    444439RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
    445440{
    446     int rc = VERR_DVM_MAP_NO_VOLUME;
    447441    PRTDVMINTERNAL       pThis = hVolMgr;
    448442    PRTDVMVOLUMEINTERNAL pVol = hVol;
     
    454448    AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
    455449
    456     PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol,
    457                                                   RTDVMVOLUMEINTERNAL, VolumeNode);
     450    int rc = VERR_DVM_MAP_NO_VOLUME;
     451    PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode);
    458452    if (pVolNext)
    459453    {
     
    466460}
    467461
    468 RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
    469                                      bool *pfAllocated)
    470 {
    471     int rc = VINF_SUCCESS;
    472     PRTDVMINTERNAL       pThis = hVolMgr;
     462RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb, bool *pfAllocated)
     463{
     464    PRTDVMINTERNAL pThis = hVolMgr;
    473465    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    474466    AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER);
    475467    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);
     468    AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_WRONG_ORDER);
     469    AssertMsgReturn(   off      <= pThis->DvmDisk.cbDisk
     470                    || cb       <= pThis->DvmDisk.cbDisk
     471                    || off + cb <= pThis->DvmDisk.cbDisk,
     472                    ("off=%#RX64 cb=%#RX64 cbDisk=%#RX64\n", off, cb, pThis->DvmDisk.cbDisk),
     473                    VERR_OUT_OF_RANGE);
    479474
    480475    /* Check whether the range is inuse by the volume manager metadata first. */
    481     rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated);
     476    int rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated);
    482477    if (RT_FAILURE(rc))
    483478        return rc;
     
    513508                    {
    514509                        bool fVolAllocated = true;
    515 
    516                         rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
    517                                                        &fVolAllocated);
     510                        rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, &fVolAllocated);
    518511                        if (RT_FAILURE(rc))
    519512                            break;
    520                         else if (fVolAllocated)
     513                        if (fVolAllocated)
    521514                        {
    522515                            fAllocated = true;
     
    657650    AssertReturn(enmVolType >= RTDVMVOLTYPE_INVALID && enmVolType < RTDVMVOLTYPE_END, NULL);
    658651
    659     return g_apcszDvmVolTypes[enmVolType];
    660 }
     652    return g_apszDvmVolTypes[enmVolType];
     653}
     654
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