VirtualBox

Changeset 7900 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Apr 11, 2008 8:13:26 AM (17 years ago)
Author:
vboxsync
Message:

Fix generic image merging code (make the appropriate images writable during the merge). Prepare for more aggressive redundant write elimination. Fix determining backends. Fix code which was broken by the VINF_VDI_BLOCK_FREE->VERR_VDI_BLOCK_FREE change. Also finally get the modification UUID handling right. Missing code and a really silly typo. Print the backend and the filename in the right place when doing a image dump.

File:
1 edited

Legend:

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

    r7824 r7900  
    343343    {
    344344        /* generate new last-modified uuid */
    345         if (!(pDisk->uModified | VD_IMAGE_MODIFIED_DISABLE_UUID_UPDATE))
     345        if (!(pDisk->uModified & VD_IMAGE_MODIFIED_DISABLE_UUID_UPDATE))
    346346        {
    347347            RTUUID Uuid;
     
    453453/**
    454454 * internal: write a complete block (only used for diff images), taking the
    455  * remaining data from parent images. This implementation optimized out writes
     455 * remaining data from parent images. This implementation optimizes out writes
    456456 * that do not change the data relative to the state as of the parent images.
    457457 * All backends which support differential/growing images support this.
     
    538538{
    539539    int rc;
     540    unsigned fWrite;
    540541    size_t cbThisWrite;
    541542    size_t cbPreRead, cbPostRead;
     
    546547        /* Try to write the possibly partial block to the last opened image.
    547548         * This works when the block is already allocated in this image or
    548          * if it is a full-block write, which automatically allocates a new
    549          * block if needed. */
     549         * if it is a full-block write (and allocation isn't suppressed below).
     550         * For image formats which don't support zero blocks, it's beneficial
     551         * to avoid unnecessarily allocating unchanged blocks. This prevents
     552         * unwanted expanding of images. VMDK is an example. */
    550553        cbThisWrite = cbWrite;
     554        fWrite =   (pImage->uOpenFlags & VD_OPEN_FLAGS_HONOR_SAME)
     555                 ? 0 : VD_WRITE_NO_ALLOC;
    551556        rc = pImage->Backend->pfnWrite(pImage->pvBackendData, uOffset, pvBuf,
    552557                                       cbThisWrite, &cbThisWrite, &cbPreRead,
    553                                        &cbPostRead, 0);
     558                                       &cbPostRead, fWrite);
    554559        if (rc == VERR_VDI_BLOCK_FREE)
    555560        {
     
    830835 *          VINF_SUCCESS if a plugin was found.
    831836 *                       ppszFormat contains the string which can be used as backend name.
    832  *          VERR_NOT_SUPPORTED if no plugin was found.
     837 *          VERR_NOT_SUPPORTED if no backend was found.
    833838 * @param   pszFilename     Name of the image file for which the backend is queried.
    834839 * @param   ppszFormat      Receives pointer of the UTF-8 string which contains the format name.
     
    873878            }
    874879        }
     880        if (fPluginFound)
     881            break;
    875882
    876883        /* Then check if plugin backends support this file format. */
     
    978985                break;
    979986        }
     987        if (rc == VERR_NO_MORE_FILES)
     988            rc = VERR_NOT_SUPPORTED;
     989
    980990        RTStrFree(pszPluginFilter);
    981991        if (pPluginDirEntry)
     
    11031113        }
    11041114
     1115        /* Force sane optimization settings. It's not worth avoiding writes
     1116         * to fixed size images. The overhead would have almost no payback. */
     1117        if (enmImageType == VD_IMAGE_TYPE_FIXED)
     1118            pImage->uOpenFlags |= VD_OPEN_FLAGS_HONOR_SAME;
     1119
    11051120        /** @todo optionally check UUIDs */
    11061121
     
    11601175            /* Image successfully opened, make it the last image. */
    11611176            vdAddImageToList(pDisk, pImage);
     1177            if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1178                pDisk->uModified = VD_IMAGE_MODIFIED_FIRST;
    11621179        }
    11631180        else
     
    12961313        }
    12971314
     1315        pImage->uOpenFlags = uOpenFlags & VD_OPEN_FLAGS_HONOR_SAME;
    12981316        rc = pImage->Backend->pfnCreate(pImage->pszFilename, enmType, cbSize,
    12991317                                        uImageFlags, pszComment, pPCHSGeometry,
    1300                                         pLCHSGeometry, uOpenFlags, pfnProgress,
    1301                                         pvUser, 0, 99, pDisk->pfnError,
    1302                                         pDisk->pvErrorUser,
     1318                                        pLCHSGeometry,
     1319                                        uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME,
     1320                                        pfnProgress, pvUser, 0, 99,
     1321                                        pDisk->pfnError, pDisk->pvErrorUser,
    13031322                                        &pImage->pvBackendData);
    13041323
    13051324        if (VBOX_SUCCESS(rc))
    13061325        {
     1326            /* Force sane optimization settings. It's not worth avoiding writes
     1327             * to fixed size images. The overhead would have almost no payback. */
     1328            if (enmType == VD_IMAGE_TYPE_FIXED)
     1329                pImage->uOpenFlags |= VD_OPEN_FLAGS_HONOR_SAME;
     1330
    13071331            /** @todo optionally check UUIDs */
    13081332
     
    13511375            /* Image successfully opened, make it the last image. */
    13521376            vdAddImageToList(pDisk, pImage);
     1377            if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1378                pDisk->uModified = VD_IMAGE_MODIFIED_FIRST;
    13531379        }
    13541380        else
     
    14561482        }
    14571483
     1484        pImage->uOpenFlags = uOpenFlags & VD_OPEN_FLAGS_HONOR_SAME;
    14581485        rc = pImage->Backend->pfnCreate(pImage->pszFilename,
    14591486                                        VD_IMAGE_TYPE_NORMAL, pDisk->cbSize,
    14601487                                        uImageFlags, pszComment,
    14611488                                        &pDisk->PCHSGeometry,
    1462                                         &pDisk->LCHSGeometry, uOpenFlags,
     1489                                        &pDisk->LCHSGeometry,
     1490                                        uOpenFlags & ~VD_OPEN_FLAGS_HONOR_SAME,
    14631491                                        pfnProgress, pvUser, 0, 99,
    14641492                                        pDisk->pfnError, pDisk->pvErrorUser,
    14651493                                        &pImage->pvBackendData);
    14661494
     1495        if (VBOX_SUCCESS(rc) && pDisk->cImages != 0)
     1496        {
     1497            /* Switch previous image to read-only mode. */
     1498            unsigned uOpenFlagsPrevImg;
     1499            uOpenFlagsPrevImg = pDisk->pLast->Backend->pfnGetOpenFlags(pDisk->pLast->pvBackendData);
     1500            if (!(uOpenFlagsPrevImg & VD_OPEN_FLAGS_READONLY))
     1501            {
     1502                uOpenFlagsPrevImg |= VD_OPEN_FLAGS_READONLY;
     1503                rc = pDisk->pLast->Backend->pfnSetOpenFlags(pDisk->pLast->pvBackendData, uOpenFlagsPrevImg);
     1504            }
     1505        }
     1506
     1507        if (VBOX_SUCCESS(rc))
     1508        {
     1509            RTUUID Uuid;
     1510            int rc2;
     1511
     1512            rc2 = pDisk->pLast->Backend->pfnGetUuid(pDisk->pLast->pvBackendData,
     1513                                                    &Uuid);
     1514            if (VBOX_SUCCESS(rc2))
     1515                pImage->Backend->pfnSetParentUuid(pImage->pvBackendData, &Uuid);
     1516            rc2 = pDisk->pLast->Backend->pfnGetModificationUuid(pDisk->pLast->pvBackendData,
     1517                                                                &Uuid);
     1518            if (VBOX_SUCCESS(rc2))
     1519                pImage->Backend->pfnSetParentModificationUuid(pImage->pvBackendData,
     1520                                                              &Uuid);
     1521        }
     1522
    14671523        if (VBOX_SUCCESS(rc))
    14681524        {
     
    14741530            /* Image successfully opened, make it the last image. */
    14751531            vdAddImageToList(pDisk, pImage);
     1532            if (!(uOpenFlags & VD_OPEN_FLAGS_READONLY))
     1533                pDisk->uModified = VD_IMAGE_MODIFIED_FIRST;
    14761534        }
    14771535        else
     
    15431601        AssertBreak(pImageFrom != pImageTo, rc = VERR_INVALID_PARAMETER);
    15441602
    1545         /* Check if destination image is writable. */
     1603        /* Make sure destination image is writable. */
    15461604        unsigned uOpenFlags = pImageTo->Backend->pfnGetOpenFlags(pImageTo->pvBackendData);
    15471605        if (uOpenFlags & VD_OPEN_FLAGS_READONLY)
    15481606        {
    1549             rc = VERR_VDI_IMAGE_READ_ONLY;
    1550             break;
     1607            uOpenFlags &= ~VD_OPEN_FLAGS_READONLY;
     1608            rc = pImageTo->Backend->pfnSetOpenFlags(pImageTo->pvBackendData,
     1609                                                    uOpenFlags);
     1610            if (VBOX_FAILURE(rc))
     1611                break;
    15511612        }
    15521613
     
    15811642                                                uOffset, pvBuf, cbThisRead,
    15821643                                                &cbThisRead);
    1583                 if (VBOX_FAILURE(rc))
    1584                     break;
    15851644                if (rc == VERR_VDI_BLOCK_FREE)
    15861645                {
     
    15981657                                                          &cbThisRead);
    15991658                    }
    1600                     if (VBOX_FAILURE(rc))
    1601                         break;
    16021659
    16031660                    if (rc != VERR_VDI_BLOCK_FREE)
    16041661                    {
     1662                        if (VBOX_FAILURE(rc))
     1663                            break;
    16051664                        rc = vdWriteHelper(pDisk, pImageTo, uOffset, pvBuf,
    16061665                                           cbThisRead);
     
    16081667                            break;
    16091668                    }
     1669                    else
     1670                        rc = VINF_SUCCESS;
    16101671                }
     1672                else if (VBOX_FAILURE(rc))
     1673                    break;
    16111674
    16121675                uOffset += cbThisRead;
     
    16241687            {
    16251688                size_t cbThisRead = RT_MIN(VD_MERGE_BUFFER_SIZE, cbRemaining);
     1689                rc = VERR_VDI_BLOCK_FREE;
    16261690                /* Search for image with allocated block. Do not attempt to
    16271691                 * read more than the previous reads marked as valid. Otherwise
     
    16361700                                                      cbThisRead, &cbThisRead);
    16371701                }
    1638                 if (VBOX_FAILURE(rc))
    1639                     break;
    16401702
    16411703                if (rc != VERR_VDI_BLOCK_FREE)
    16421704                {
     1705                    if (VBOX_FAILURE(rc))
     1706                        break;
    16431707                    rc = vdWriteHelper(pDisk, pImageTo, uOffset, pvBuf,
    16441708                                       cbThisRead);
     
    16461710                        break;
    16471711                }
     1712                else
     1713                    rc = VINF_SUCCESS;
    16481714
    16491715                uOffset += cbThisRead;
     
    16791745                AssertRC(rc);
    16801746            }
     1747        }
     1748
     1749        /* Make sure destination image is back to read only if necessary. */
     1750        if (pImageTo != pDisk->pLast && pImageFrom != pDisk->pLast)
     1751        {
     1752            uOpenFlags = pImageTo->Backend->pfnGetOpenFlags(pImageTo->pvBackendData);
     1753            uOpenFlags |= VD_OPEN_FLAGS_READONLY;
     1754            rc = pImageTo->Backend->pfnSetOpenFlags(pImageTo->pvBackendData,
     1755                                                    uOpenFlags);
     1756            if (VBOX_FAILURE(rc))
     1757                break;
    16811758        }
    16821759
     
    31853262        {
    31863263            RTLogPrintf("Dumping VD image \"%s\" (Backend=%s)\n",
    3187                         pImage->Backend->pszBackendName, pImage->pszFilename);
     3264                        pImage->pszFilename, pImage->Backend->pszBackendName);
    31883265            pImage->Backend->pfnDump(pImage->pvBackendData);
    31893266        }
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