VirtualBox

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


Ignore:
Timestamp:
Feb 6, 2007 2:33:44 PM (18 years ago)
Author:
vboxsync
Message:

Moved and fixed zero data block write detection (could lead to write
being lost for situation with diff VDIs).

File:
1 edited

Legend:

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

    r643 r710  
    502502     */
    503503    unsigned        cbBuf;
     504
     505    /** Flag whether zero writes should be handled normally or optimized
     506     * away if possible. */
     507    bool            fHonorZeroWrites;
    504508
    505509    /** The media interface. */
     
    15841588    }
    15851589
     1590    /* This could be optimized a little (not setting it when writing zeroes
     1591     * to a zeroed block). Won't buy us much, because it's very unlikely
     1592     * that only such zero data block writes occur while the VDI is opened. */
    15861593    vdiSetModifiedFlag(pImage);
    15871594
    15881595    if (!IS_VDI_IMAGE_BLOCK_ALLOCATED(pImage->paBlocks[uBlock]))
    15891596    {
     1597        if (!pDisk->fHonorZeroWrites)
     1598        {
     1599            /* If the destination block is unallocated at this point, it's either
     1600             * a zero block or a block which hasn't been used so far (which also
     1601             * means that it's a zero block. Don't need to write anything to this
     1602             * block if the data consists of just zeroes. */
     1603            bool fBlockZeroed = true; /* Block is zeroed flag. */
     1604            for (unsigned i = 0; i < (cbToWrite >> 2); i++)
     1605                if (((uint32_t *)pvBuf)[i] != 0)
     1606                {
     1607                    /* Block is not zeroed! */
     1608                    fBlockZeroed = false;
     1609                    break;
     1610                }
     1611
     1612            if (fBlockZeroed)
     1613            {
     1614                pImage->paBlocks[uBlock] = VDI_IMAGE_BLOCK_ZERO;
     1615                return VINF_SUCCESS;
     1616            }
     1617        }
     1618
    15901619        /* need to allocate a new block in image file */
    15911620
     
    17191748
    17201749    /* loop through blocks */
    1721     int rc = VINF_SUCCESS;
     1750    int rc;
    17221751    for (;;)
    17231752    {
     
    17601789        }
    17611790
    1762         /* If the destination block is unallocated at this point, it's either
    1763          * a zero block or a block which hasn't been used so far (which also
    1764          * means that it's a zero block. Don't need to write anything to this
    1765          * block if the data consists of just zeroes. */
    1766         bool fBlockZeroed = false; /* assume data, for blocks already with data */
    1767         if (!IS_VDI_IMAGE_BLOCK_ALLOCATED(pImage->paBlocks[uBlock]))
    1768         {
    1769             /* Check block for data. */
    1770             fBlockZeroed = true;    /* Block is zeroed flag. */
    1771             for (unsigned i = 0; i < (to_write >> 2); i++)
    1772                 if (((uint32_t *)pvBuf)[i] != 0)
    1773                 {
    1774                     /* Block is not zeroed! */
    1775                     fBlockZeroed = false;
    1776                     break;
    1777                 }
    1778         }
    1779 
    17801791        /* Actually write the data into block. */
    1781         if (!fBlockZeroed)
    1782             rc = vdiWriteInBlock(pDisk, pImage, uBlock, offWrite, to_write, pvBuf);
     1792        rc = vdiWriteInBlock(pDisk, pImage, uBlock, offWrite, to_write, pvBuf);
    17831793
    17841794        cbToWrite -= to_write;
     
    31863196    pDisk->cbBlock = VDI_IMAGE_DEFAULT_BLOCK_SIZE;
    31873197    pDisk->cbBuf   = VDIDISK_DEFAULT_BUFFER_SIZE;
     3198    pDisk->fHonorZeroWrites = false;
    31883199}
    31893200
     
    42254236    char *pszName;      /**< The path of the disk image file. */
    42264237    bool fReadOnly;     /**< True if the media is readonly. */
     4238    bool fHonorZeroWrites = false;
    42274239
    42284240    /*
     
    42464258    pData->IMedia.pfnBiosSetTranslation = vdiBiosSetTranslation;
    42474259
    4248 #if 1 /** @todo someone review this! it's a shot in the dark from my side. */
    42494260    /*
    42504261     * Validate configuration and find the great to the level of umpteen grandparent.
     
    42564267    for (;;)
    42574268    {
    4258         if (!CFGMR3AreValuesValid(pCfgHandle, "Path\0ReadOnly\0"))
     4269        if (!CFGMR3AreValuesValid(pCfgHandle, "Path\0ReadOnly\0HonorZeroWrites\0"))
    42594270            return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
    42604271
     
    42884299            return PDMDRV_SET_ERROR(pDrvIns, rc,
    42894300                                    N_("VHDD: Configuration error: Querying \"ReadOnly\" as boolean failed"));
     4301        }
     4302
     4303        if (!fHonorZeroWrites)
     4304        {
     4305            rc = CFGMR3QueryBool(pCfgHandle, "HonorZeroWrites", &fHonorZeroWrites);
     4306            if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     4307                fHonorZeroWrites = false;
     4308            else if (VBOX_FAILURE(rc))
     4309            {
     4310                MMR3HeapFree(pszName);
     4311                return PDMDRV_SET_ERROR(pDrvIns, rc,
     4312                                        N_("VHDD: Configuration error: Querying \"HonorZeroWrites\" as boolean failed"));
     4313            }
    42904314        }
    42914315
     
    43074331    }
    43084332
     4333    /* If any of the images has the flag set, handle zero writes like normal. */
     4334    if (VBOX_SUCCESS(rc))
     4335        pData->fHonorZeroWrites = fHonorZeroWrites;
     4336
    43094337    /* On failure, vdiDestruct will be called, so no need to clean up here. */
    4310 
    4311 #else /* old */
    4312     /*
    4313      * Validate and read top level configuration.
    4314      */
    4315     int rc = CFGMR3QueryStringAlloc(pCfgHandle, "Path", &pszName);
    4316     if (VBOX_FAILURE(rc))
    4317         return PDMDRV_SET_ERROR(pDrvIns, rc,
    4318                                 N_("VHDD: Configuration error: Querying \"Path\" as string failed"));
    4319 
    4320     rc = CFGMR3QueryBool(pCfgHandle, "ReadOnly", &fReadOnly);
    4321     if (rc == VERR_CFGM_VALUE_NOT_FOUND)
    4322         fReadOnly = false;
    4323     else if (VBOX_FAILURE(rc))
    4324     {
    4325         MMR3HeapFree(pszName);
    4326         return PDMDRV_SET_ERROR(pDrvIns, rc,
    4327                                 N_("VHDD: Configuration error: Querying \"ReadOnly\" as boolean failed"));
    4328     }
    4329 
    4330     /*
    4331      * Open the image.
    4332      */
    4333     rc = VDIDiskOpenImage(pData, pszName, fReadOnly ? VDI_OPEN_FLAGS_READONLY
    4334                                                     : VDI_OPEN_FLAGS_NORMAL);
    4335     if (VBOX_SUCCESS(rc))
    4336         Log(("vdiConstruct: Opened '%s' in %s mode\n", pszName, VDIDiskIsReadOnly(pData) ? "read-only" : "read-write"));
    4337     else
    4338         AssertMsgFailed(("Failed to open image '%s' rc=%Vrc\n", pszName, rc));
    4339 
    4340     MMR3HeapFree(pszName);
    4341     pszName = NULL;
    4342 #endif
    43434338
    43444339    if (rc == VERR_ACCESS_DENIED)
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