VirtualBox

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


Ignore:
Timestamp:
Mar 19, 2010 1:10:47 PM (15 years ago)
Author:
vboxsync
Message:

VMDK: Optimize descriptor writes. Prepare the whole descriptor in a buffer and write it once instead of doing a lot of small writes to the file

File:
1 edited

Legend:

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

    r27525 r27531  
    599599    }
    600600#else
     601    unsigned uOpenFlags = 0;
     602
     603    if ((fOpen & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ)
     604        uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY;
     605    if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE)
     606        uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE;
     607
    601608    rc = pImage->pInterfaceAsyncIOCallbacks->pfnOpen(pImage->pInterfaceAsyncIO->pvUser,
    602609                                                        pszFilename,
    603                                                         pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY
    604                                                         ? VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY
    605                                                         : 0,
     610                                                        uOpenFlags,
    606611                                                        NULL,
    607612                                                        pImage->pVDIfsDisk,
     
    24552460        uOffset = VMDK_SECTOR2BYTE(pImage->pExtents[0].uDescriptorSector);
    24562461        cbLimit = VMDK_SECTOR2BYTE(pImage->pExtents[0].cDescriptorSectors);
    2457         cbLimit += uOffset;
    24582462        pDescFile = pImage->pExtents[0].pFile;
    24592463    }
     
    24612465    if (pDescFile == NULL)
    24622466        return VERR_INVALID_PARAMETER;
     2467
     2468    /*
     2469     * Allocate temporary descriptor buffer.
     2470     * In case there is no limit allocate a default
     2471     * and increase if required.
     2472     */
     2473    size_t cbDescriptor = cbLimit ? cbLimit : 4 * _1K;
     2474    char *pszDescriptor = (char *)RTMemAllocZ(cbDescriptor);
     2475    unsigned offDescriptor = 0;
     2476
     2477    if (!pszDescriptor)
     2478        return VERR_NO_MEMORY;
     2479
    24632480    for (unsigned i = 0; i < pImage->Descriptor.cLines; i++)
    24642481    {
     
    24662483        size_t cb = strlen(psz);
    24672484
    2468         if (cbLimit && uOffset + cb + 1 > cbLimit)
    2469             return vmdkError(pImage, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too long in '%s'"), pImage->pszFilename);
     2485        /*
     2486         * Increase the descriptor if there is no limit and
     2487         * there is not enough room left for this line.
     2488         */
     2489        if (offDescriptor + cb + 1 > cbDescriptor)
     2490        {
     2491            if (cbLimit)
     2492            {
     2493                rc = vmdkError(pImage, VERR_BUFFER_OVERFLOW, RT_SRC_POS, N_("VMDK: descriptor too long in '%s'"), pImage->pszFilename);
     2494                break;
     2495            }
     2496            else
     2497            {
     2498                char *pszDescriptorNew = NULL;
     2499                LogFlow(("Increasing descriptor cache\n"));
     2500
     2501                pszDescriptorNew = (char *)RTMemAllocZ(cbDescriptor + cb + 4 * _1K);
     2502                if (!pszDescriptorNew)
     2503                {
     2504                    rc = VERR_NO_MEMORY;
     2505                    break;
     2506                }
     2507                memcpy(pszDescriptorNew, pszDescriptor, cbDescriptor);
     2508                RTMemFree(pszDescriptor);
     2509                pszDescriptorNew = pszDescriptor;
     2510                cbDescriptor += cb + 4 * _1K;
     2511            }
     2512        }
    24702513
    24712514        if (cb > 0)
    24722515        {
    2473             rc = vmdkFileWriteAt(pDescFile, uOffset, psz, cb, NULL);
    2474             if (RT_FAILURE(rc))
    2475                 return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename);
    2476             uOffset += cb;
    2477         }
    2478 
    2479         rc = vmdkFileWriteAt(pDescFile, uOffset, "\n", 1, NULL);
     2516            memcpy(pszDescriptor + offDescriptor, psz, cb);
     2517            offDescriptor += cb;
     2518        }
     2519
     2520        memcpy(pszDescriptor + offDescriptor, "\n", 1);
     2521        offDescriptor++;
     2522    }
     2523
     2524    if (RT_SUCCESS(rc))
     2525    {
     2526        rc = vmdkFileWriteAt(pDescFile, uOffset, pszDescriptor, cbLimit ? cbLimit : offDescriptor, NULL);
    24802527        if (RT_FAILURE(rc))
    2481             return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename);
    2482         uOffset++;
    2483     }
    2484     if (cbLimit)
    2485     {
    2486         /* Inefficient, but simple. */
    2487         while (uOffset < cbLimit)
    2488         {
    2489             rc = vmdkFileWriteAt(pDescFile, uOffset, "", 1, NULL);
    2490             if (RT_FAILURE(rc))
    2491                 return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename);
    2492             uOffset++;
    2493         }
    2494     }
    2495     else
    2496     {
    2497         rc = vmdkFileSetSize(pDescFile, uOffset);
     2528            rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error writing descriptor in '%s'"), pImage->pszFilename);
     2529    }
     2530
     2531    if (RT_SUCCESS(rc) && !cbLimit)
     2532    {
     2533        rc = vmdkFileSetSize(pDescFile, offDescriptor);
    24982534        if (RT_FAILURE(rc))
    2499             return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error truncating descriptor in '%s'"), pImage->pszFilename);
    2500     }
    2501     pImage->Descriptor.fDirty = false;
     2535            rc = vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: error truncating descriptor in '%s'"), pImage->pszFilename);
     2536    }
     2537
     2538    if (RT_SUCCESS(rc))
     2539        pImage->Descriptor.fDirty = false;
     2540
     2541    RTMemFree(pszDescriptor);
    25022542    return rc;
    25032543}
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