VirtualBox

Changeset 38657 in vbox


Ignore:
Timestamp:
Sep 6, 2011 2:06:56 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73869
Message:

VD+VDI: Implement optimization for discard to avoid reading the complete data all the time and bug fixes

Location:
trunk/src/VBox/Storage
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Storage/VD.cpp

    r38621 r38657  
    10101010    int rc = VINF_SUCCESS;
    10111011
     1012    LogFlowFunc(("pDisk=%#p pDiscard=%#p cbDiscardingNew=%zu\n",
     1013                 pDisk, pDiscard, cbDiscardingNew));
     1014
    10121015    while (pDiscard->cbDiscarding > cbDiscardingNew)
    10131016    {
     
    10211024        size_t cbLeft = pBlock->cbDiscard;
    10221025        bool fAllocated = ASMBitTest(pBlock->pbmAllocated, idxStart);
    1023         uint32_t cSectors = pBlock->cbDiscard * 8;
     1026        uint32_t cSectors = pBlock->cbDiscard / 512;
    10241027
    10251028        while (cbLeft > 0)
     
    10731076    Assert(RT_FAILURE(rc) || pDiscard->cbDiscarding <= cbDiscardingNew);
    10741077
     1078    LogFlowFunc(("returns rc=%Rrc\n", rc));
    10751079    return rc;
    10761080}
     
    11271131            /* Clip range to remain in the current block. */
    11281132            if (pBlockAbove)
    1129                 cbThisDiscard = RT_MIN(cbDiscard, pBlockAbove->Core.Key - (offStart + cbDiscard - 1));
     1133                cbThisDiscard = RT_MIN(cbDiscard, pBlockAbove->Core.KeyLast - offStart + 1);
    11301134            else
    11311135                cbThisDiscard = cbDiscard;
    11321136
    1133             Assert(cbThisDiscard % 512 == 0);
     1137            Assert(!(cbThisDiscard % 512));
    11341138
    11351139            /* No block found, try to discard using the backend first. */
     
    11441148                if (pBlock)
    11451149                {
    1146                     pBlock->Core.Key     = offStart + cbPreAllocated;
    1147                     pBlock->Core.KeyLast = offStart + cbThisDiscard + cbPreAllocated - 1;
    1148                     pBlock->cbDiscard    = cbThisDiscard;
     1150                    pBlock->Core.Key     = offStart - cbPreAllocated;
     1151                    pBlock->Core.KeyLast = offStart + cbThisDiscard + cbPostAllocated - 1;
     1152                    pBlock->cbDiscard    = cbPreAllocated + cbThisDiscard + cbPostAllocated;
    11491153                    pBlock->pbmAllocated = pbmAllocated;
    11501154                    bool fInserted = RTAvlrU64Insert(pDiscard->pTreeBlocks, &pBlock->Core);
     
    11651169        {
    11661170            /* Range lies partly in the block, update allocation bitmap. */
    1167             cbThisDiscard = pBlock->Core.KeyLast - offStart + 1;
     1171            cbThisDiscard = RT_MIN(cbDiscard, pBlock->Core.KeyLast - offStart + 1);
    11681172            rc = VERR_VD_DISCARD_ALIGNMENT_NOT_MET;
    11691173        }
     1174
     1175        Assert(cbDiscard >= cbThisDiscard);
    11701176
    11711177        if (rc == VERR_VD_DISCARD_ALIGNMENT_NOT_MET)
     
    12121218                RTListNodeRemove(&pBlock->NodeLru);
    12131219                RTListPrepend(&pDiscard->ListLru, &pBlock->NodeLru);
     1220                rc = VINF_SUCCESS;
    12141221            }
    12151222        }
     1223
     1224        Assert(cbDiscard >= cbThisDiscard);
    12161225
    12171226        cbDiscard -= cbThisDiscard;
     
    12841293                Assert(!(cbThisRange % 512));
    12851294                Assert(!((uOffset - pBlock->Core.Key) % 512));
     1295
     1296                cbThisRange = RT_MIN(cbThisRange, pBlock->Core.KeyLast - uOffset + 1);
    12861297
    12871298                idxStart = (uOffset - pBlock->Core.Key) / 512;
     
    12951306                    cbThisRange = RT_MIN(cbThisRange, pBlock->Core.Key - uOffset);
    12961307            }
     1308
     1309            Assert(cbRange >= cbThisRange);
    12971310
    12981311            uOffset += cbThisRange;
  • trunk/src/VBox/Storage/VDI.cpp

    r38647 r38657  
    888888
    889889    return rc;
     890}
     891
     892/**
     893 * Internal: Creates a allocation bitmap from the given data.
     894 * Sectors which contain only 0 are marked as unallocated and sectors with
     895 * other data as allocated.
     896 *
     897 * @returns Pointer to the allocation bitmap or NULL on failure.
     898 * @param   pvData    The data to create the allocation bitmap for.
     899 * @param   cbData    Number of bytes in the buffer.
     900 */
     901static void *vdiAllocationBitmapCreate(void *pvData, size_t cbData)
     902{
     903    unsigned cSectors = cbData / 512;
     904    unsigned uSectorCur = 0;
     905    void *pbmAllocationBitmap = NULL;
     906
     907    Assert(!(cbData % 512));
     908    Assert(!(cSectors % 8));
     909
     910    pbmAllocationBitmap = RTMemAllocZ(cSectors / 8);
     911
     912    while (uSectorCur < cSectors)
     913    {
     914        int idxSet = ASMBitFirstSet((uint8_t *)pvData + uSectorCur * 512, cbData * 8);
     915
     916        if (idxSet != -1)
     917        {
     918            unsigned idxSectorAlloc = idxSet / 8 / 512;
     919            ASMBitSet(pbmAllocationBitmap, uSectorCur + idxSectorAlloc);
     920
     921            uSectorCur += idxSectorAlloc + 1;
     922            cbData     -= (idxSectorAlloc + 1) * 512;
     923        }
     924        else
     925            break;
     926    }
     927
     928    return pbmAllocationBitmap;
    890929}
    891930
     
    25602599    Assert(!(cbDiscard % 512));
    25612600
     2601    AssertMsgReturn(!(pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY),
     2602                    ("Image is readonly\n"), VERR_VD_IMAGE_READ_ONLY);
     2603    AssertMsgReturn(   uOffset + cbDiscard <= getImageDiskSize(&pImage->Header)
     2604                    && cbDiscard,
     2605                    ("Invalid parameters uOffset=%llu cbDiscard=%zu\n",
     2606                     uOffset, cbDiscard),
     2607                     VERR_INVALID_PARAMETER);
     2608
    25622609    do
    25632610    {
     
    26692716                rc = vdIfIoIntFileSetSize(pImage->pIfIo, pImage->pStorage, cbImage - pImage->cbTotalBlockData);
    26702717            }
    2671             else /* if (fDiscard & VD_DISCARD_MARK_UNUSED) */
     2718            else if (fDiscard & VD_DISCARD_MARK_UNUSED)
    26722719            {
    26732720                /* Write changed data to the image. */
     
    26752722                                            pbBlockData + offDiscard, cbDiscard, NULL);
    26762723            }
    2677 #if 0
    26782724            else
    26792725            {
     
    26812727                *pcbPreAllocated = cbPreAllocated;
    26822728                *pcbPostAllocated = cbPostAllocated;
    2683                 *ppbmAllocationBitmap = vdAllocationBitmapCreate(pvBlock, getImageBlockSize(&pImage->Header));
     2729                *ppbmAllocationBitmap = vdiAllocationBitmapCreate(pbBlockData, getImageBlockSize(&pImage->Header));
    26842730                if (RT_UNLIKELY(!*ppbmAllocationBitmap))
    26852731                    rc = VERR_NO_MEMORY;
     
    26872733                    rc = VERR_VD_DISCARD_ALIGNMENT_NOT_MET;
    26882734            }
    2689 #endif
    26902735        }
    26912736        /* else: nothing to do. */
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