VirtualBox

Changeset 2564 in vbox


Ignore:
Timestamp:
May 9, 2007 4:13:07 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
21031
Message:

Many VMDK block splitup fixes and the start of the create image
function.

Location:
trunk/src/VBox/Devices/Storage
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp

    r2379 r2564  
    217217    int rc;
    218218    size_t cbThisRead;
     219    PVBOXHDDIMAGEDESC pCurrImage;
    219220
    220221    /* Loop until all read. */
     
    226227        cbThisRead = cbRead;
    227228        rc = VINF_VDI_BLOCK_FREE;
    228         for (; pImage != NULL && rc == VINF_VDI_BLOCK_FREE; pImage = pImage->pPrev)
     229        for (pCurrImage = pImage; pCurrImage != NULL && rc == VINF_VDI_BLOCK_FREE; pCurrImage = pCurrImage->pPrev)
    229230        {
    230             rc = pDisk->Backend->pfnRead(pImage->pvBackendData, uOffset, pvBuf, cbThisRead, &cbThisRead);
     231            rc = pDisk->Backend->pfnRead(pCurrImage->pvBackendData, uOffset, pvBuf, cbThisRead, &cbThisRead);
    231232        }
    232233
     
    428429            rc = VERR_VDI_INVALID_TYPE;
    429430
     431        /** @todo optionally check UUIDs */
     432
    430433        if (VBOX_SUCCESS(rc))
    431434        {
     
    531534                               PFNVMPROGRESS pfnProgress, void *pvUser)
    532535{
    533     return VERR_NOT_IMPLEMENTED;
     536    int rc = VINF_SUCCESS;
     537    LogFlow(("%s: pszFilename=\"%s\" uOpenFlags=%#x\n", __FUNCTION__, pszFilename, uOpenFlags));
     538    /* sanity check */
     539    Assert(pDisk);
     540    AssertMsg(pDisk->u32Signature == VBOXHDDDISK_SIGNATURE, ("u32Signature=%08x\n", pDisk->u32Signature));
     541
     542    /* Check arguments. */
     543    if (    !pszFilename
     544        ||  *pszFilename == '\0'
     545        ||  (enmType != VD_IMAGE_TYPE_NORMAL && enmType != VD_IMAGE_TYPE_FIXED)
     546        ||  !cbSize
     547        ||  (uOpenFlags & ~VD_OPEN_FLAGS_MASK))
     548    {
     549        AssertMsgFailed(("Invalid arguments: pszFilename=%#p uOpenFlags=%#x\n", pszFilename, uOpenFlags));
     550        return VERR_INVALID_PARAMETER;
     551    }
     552
     553    /* Check state. */
     554    if (pDisk->cImages != 0)
     555    {
     556        AssertMsgFailed(("Create base image cannot be done with other images open\n"));
     557        return VERR_VDI_INVALID_STATE;
     558    }
     559
     560    /* Set up image descriptor. */
     561    PVBOXHDDIMAGEDESC pImage = (PVBOXHDDIMAGEDESC)RTMemAllocZ(sizeof(VBOXHDDIMAGEDESC));
     562    if (!pImage)
     563        return VERR_NO_MEMORY;
     564    pImage->pszFilename = RTStrDup(pszFilename);
     565    if (!pImage->pszFilename)
     566        rc = VERR_NO_MEMORY;
     567
     568    if (VBOX_SUCCESS(rc))
     569        rc = pDisk->Backend->pfnCreate(pImage->pszFilename, enmType, cbSize,
     570                                       uImageFlags, pszComment, uOpenFlags,
     571                                       pfnProgress, pvUser,
     572                                       pDisk->pfnError, pDisk->pvErrorUser,
     573                                       &pImage->pvBackendData);
     574
     575    if (VBOX_FAILURE(rc))
     576    {
     577        RTStrFree(pImage->pszFilename);
     578        RTMemFree(pImage);
     579    }
     580
     581    return rc;
    534582}
    535583
  • trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h

    r2380 r2564  
    4545
    4646    /**
     47     * Create a disk image.
     48     *
     49     * @returns VBox status code.
     50     * @param   pszFilename     Name of the image file to create. Guaranteed to be available and
     51     *                          unchanged during the lifetime of this image.
     52     * @param   penmType        Image type. Both base and diff image types are valid.
     53     * @param   cbSize          Image size in bytes.
     54     * @param   uImageFlags     Flags specifying special image features.
     55     * @param   pszComment      Pointer to image comment. NULL is ok.
     56     * @param   uOpenFlags      Image file open mode, see VD_OPEN_FLAGS_* constants.
     57     * @param   pfnProgress     Progress callback. Optional. NULL if not to be used.
     58     * @param   pvUser          User argument for the progress callback.
     59     * @param   pfnError        Callback for setting extended error information.
     60     * @param   pvErrorUser     Opaque parameter for pfnError.
     61     * @param   ppvBackendData  Opaque state data for this image.
     62     */
     63    DECLR3CALLBACKMEMBER(int, pfnCreate, (const char *pszFilename, VDIMAGETYPE penmType, uint64_t cbSize, unsigned uImageFlags, const char *pszComment, unsigned uOpenFlags, PFNVMPROGRESS pfnProgress, void *pvUser, PFNVDERROR pfnError, void *pvErrorUser, void **ppvBackendData));
     64
     65    /**
    4766     * Close a disk image.
    4867     *
     
    107126     * @returns VBox status code.
    108127     * @param   pvBackendData   Opaque state data for this image.
    109      * @param   penmImageType   Image type of this image.
    110      */
    111     DECLR3CALLBACKMEMBER(int, pfnGetImageType, (void *pvBackendData, PVDIMAGETYPE penmImageType));
     128     * @param   penmType        Image type of this image.
     129     */
     130    DECLR3CALLBACKMEMBER(int, pfnGetImageType, (void *pvBackendData, PVDIMAGETYPE penmType));
    112131
    113132    /**
  • trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp

    r2385 r2564  
    19651965}
    19661966
     1967static int vmdkCreate(const char *pszFilename, VDIMAGETYPE penmType,
     1968                      uint64_t cbSize, unsigned uImageFlags,
     1969                      const char *pszComment, unsigned uOpenFlags,
     1970                      PFNVMPROGRESS pfnProgress, void *pvUser,
     1971                      PFNVDERROR pfnError, void *pvErrorUser,
     1972                      void **ppvBackendData)
     1973{
     1974    return VERR_NOT_IMPLEMENTED;
     1975}
     1976
    19671977static int vmdkClose(void *pBackendData)
    19681978{
     
    19831993    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
    19841994    PVMDKEXTENT pExtent;
    1985     uint64_t uSectorInExtent;
    1986     uint64_t uSectorOffset;
     1995    uint64_t uSectorExtentRel;
     1996    uint64_t uSectorExtentAbs;
    19871997    int rc;
    19881998
     
    19972007
    19982008    rc = vmdkFindExtent(pImage, VMDK_BYTE2SECTOR(uOffset),
    1999                         &pExtent, &uSectorInExtent);
     2009                        &pExtent, &uSectorExtentRel);
    20002010    if (VBOX_FAILURE(rc))
    20012011        goto out;
     
    20092019
    20102020    /* Clip read range to remain in this extent. */
    2011     cbRead = RT_MIN(cbRead, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorInExtent));
     2021    cbRead = RT_MIN(cbRead, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
    20122022
    20132023    /* Handle the read according to the current extent type. */
     
    20182028        case VMDKETYPE_ESX_SPARSE:
    20192029#endif /* VBOX_WITH_VMDK_ESX */
    2020             rc = vmdkGetSector(pImage->pGTCache, pExtent, uSectorInExtent,
    2021                                &uSectorOffset);
     2030            rc = vmdkGetSector(pImage->pGTCache, pExtent, uSectorExtentRel,
     2031                               &uSectorExtentAbs);
    20222032            if (VBOX_FAILURE(rc))
    20232033                goto out;
    20242034            /* Clip read range to at most the rest of the grain. */
    2025             cbRead = RT_MIN(cbRead, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain - (uSectorOffset % pExtent->cSectorsPerGrain)));
    2026             if (uSectorOffset == 0)
     2035            cbRead = RT_MIN(cbRead, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain - uSectorExtentRel % pExtent->cSectorsPerGrain));
     2036            Assert(!(cbRead % 512));
     2037            if (uSectorExtentAbs == 0)
    20272038                rc = VINF_VDI_BLOCK_FREE;
    20282039            else
    20292040                rc = RTFileReadAt(pExtent->File,
    2030                                   VMDK_SECTOR2BYTE(uSectorOffset),
     2041                                  VMDK_SECTOR2BYTE(uSectorExtentAbs),
    20312042                                  pvBuf, cbRead, NULL);
    20322043            break;
    20332044        case VMDKETYPE_FLAT:
    2034             rc = RTFileReadAt(pExtent->File, VMDK_SECTOR2BYTE(uSectorInExtent),
     2045            rc = RTFileReadAt(pExtent->File, VMDK_SECTOR2BYTE(uSectorExtentRel),
    20352046                              pvBuf, cbRead, NULL);
    20362047            break;
     
    20492060    PVMDKIMAGE pImage = (PVMDKIMAGE)pBackendData;
    20502061    PVMDKEXTENT pExtent;
    2051     uint64_t uSectorInExtent;
    2052     uint64_t uSectorOffset;
     2062    uint64_t uSectorExtentRel;
     2063    uint64_t uSectorExtentAbs;
    20532064    int rc;
    20542065
     
    20702081
    20712082    rc = vmdkFindExtent(pImage, VMDK_BYTE2SECTOR(uOffset),
    2072                         &pExtent, &uSectorInExtent);
     2083                        &pExtent, &uSectorExtentRel);
    20732084    if (VBOX_FAILURE(rc))
    20742085        goto out;
     
    20802091        goto out;
    20812092    }
     2093
     2094    /** @todo implement suppressing of zero data writes (a bit tricky in this
     2095     * case, as VMDK has no marker for zero blocks). We somehow need to get the
     2096     * information whether the information in this area is all zeroes as of the
     2097     * parent image. Then (based on the assumption that parent images are
     2098     * immutable) the write can be ignored. */
    20822099
    20832100    /* Handle the write according to the current extent type. */
     
    20882105        case VMDKETYPE_ESX_SPARSE:
    20892106#endif /* VBOX_WITH_VMDK_ESX */
    2090             rc = vmdkGetSector(pImage->pGTCache, pExtent, uSectorInExtent,
    2091                                &uSectorOffset);
     2107            rc = vmdkGetSector(pImage->pGTCache, pExtent, uSectorExtentRel,
     2108                               &uSectorExtentAbs);
    20922109            if (VBOX_FAILURE(rc))
    20932110                goto out;
    20942111            /* Clip write range to at most the rest of the grain. */
    2095             cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain - (uSectorOffset % pExtent->cSectorsPerGrain)));
    2096             if (uSectorOffset == 0)
     2112            cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain - uSectorExtentRel % pExtent->cSectorsPerGrain));
     2113            if (uSectorExtentAbs == 0)
    20972114            {
    20982115                if (cbWrite == VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain))
     
    21012118                     * Allocate GT and find out where to store the grain. */
    21022119                    rc = vmdkAllocGrain(pImage->pGTCache, pExtent,
    2103                                         uSectorInExtent, pvBuf, cbWrite);
     2120                                        uSectorExtentRel, pvBuf, cbWrite);
    21042121                }
    21052122                else
    21062123                {
    21072124                    /* Clip write range to remain in this extent. */
    2108                     cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorInExtent));
    2109                     *pcbPreRead = VMDK_SECTOR2BYTE(uSectorInExtent % pExtent->cSectorsPerGrain);
     2125                    cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
     2126                    *pcbPreRead = VMDK_SECTOR2BYTE(uSectorExtentRel % pExtent->cSectorsPerGrain);
    21102127                    *pcbPostRead = VMDK_SECTOR2BYTE(pExtent->cSectorsPerGrain) - cbWrite - *pcbPreRead;
    21112128                    rc = VINF_VDI_BLOCK_FREE;
     
    21142131            else
    21152132                rc = RTFileWriteAt(pExtent->File,
    2116                                    VMDK_SECTOR2BYTE(uSectorOffset),
     2133                                   VMDK_SECTOR2BYTE(uSectorExtentAbs),
    21172134                                   pvBuf, cbWrite, NULL);
    21182135            break;
    21192136        case VMDKETYPE_FLAT:
    21202137            /* Clip write range to remain in this extent. */
    2121             cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorInExtent));
    2122             rc = RTFileWriteAt(pExtent->File, VMDK_SECTOR2BYTE(uSectorInExtent), pvBuf, cbWrite, NULL);
     2138            cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
     2139            rc = RTFileWriteAt(pExtent->File, VMDK_SECTOR2BYTE(uSectorExtentRel), pvBuf, cbWrite, NULL);
    21232140            break;
    21242141        case VMDKETYPE_ZERO:
    21252142            /* Clip write range to remain in this extent. */
    2126             cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorInExtent));
     2143            cbWrite = RT_MIN(cbWrite, VMDK_SECTOR2BYTE(pExtent->cNominalSectors - uSectorExtentRel));
    21272144            break;
    21282145    }
     
    24482465    /* pfnOpen */
    24492466    vmdkOpen,
     2467    /* pfnCreate */
     2468    vmdkCreate,
    24502469    /* pfnClose */
    24512470    vmdkClose,
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