VirtualBox

Changeset 74355 in vbox


Ignore:
Timestamp:
Sep 18, 2018 9:54:56 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125168
Message:

Storage/VDVfs: Double buffer writes when write filters are present.

File:
1 edited

Legend:

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

    r73097 r74355  
    3232#include <VBox/vd.h>
    3333
     34#include "VDInternal.h"
     35
    3436
    3537/*********************************************************************************************************************************
     
    4345{
    4446    /** The volume the VFS file belongs to. */
    45     PVDISK         pDisk;
     47    PVDISK          pDisk;
    4648    /** Current position. */
    47     uint64_t       offCurPos;
     49    uint64_t        offCurPos;
    4850    /** Flags given during creation. */
    49     uint32_t       fFlags;
     51    uint32_t        fFlags;
    5052} VDVFSFILE;
    5153/** Pointer to a the internal data of a DVM volume file. */
     
    133135 * @param   pDisk    VD disk container.
    134136 * @param   off      Offset to start writing to.
    135  * @param   pvBuf    Pointer to the buffer to read from.
     137 * @param   pvSrc    Pointer to the buffer to read from.
    136138 * @param   cbWrite  Amount of bytes to write.
    137139 */
    138 static int vdWriteHelper(PVDISK pDisk, uint64_t off, const void *pvBuf, size_t cbWrite)
    139 {
     140static int vdWriteHelper(PVDISK pDisk, uint64_t off, const void *pvSrc, size_t cbWrite)
     141{
     142    uint8_t const *pbSrc = (uint8_t const *)pvSrc;
     143    uint8_t        abBuf[4096];
    140144    int rc;
    141145
    142     /* Take direct route if the request is sector aligned. */
     146    /*
     147     * Take direct route if the request is sector aligned.
     148     */
    143149    uint64_t const offMisalign = off & 511;
    144150    size_t   const cbMisalign  = (off + cbWrite) & 511;
    145151    if (   !offMisalign
    146152        && !cbMisalign)
    147         rc = VDWrite(pDisk, off, pvBuf, cbWrite);
     153    {
     154        if (RTListIsEmpty(&pDisk->ListFilterChainWrite))
     155            rc = VDWrite(pDisk, off, pbSrc, cbWrite);
     156        else
     157        {
     158            /* Filtered writes must be double buffered as the filter may need to modify the input buffer directly. */
     159            do
     160            {
     161                size_t cbThisWrite = RT_MIN(cbWrite, sizeof(abBuf));
     162                rc = VDWrite(pDisk, off, memcpy(abBuf, pbSrc, cbThisWrite), cbThisWrite);
     163                if (RT_SUCCESS(rc))
     164                {
     165                    pbSrc   += cbThisWrite;
     166                    off     += cbThisWrite;
     167                    cbWrite -= cbThisWrite;
     168                }
     169                else
     170                    break;
     171            } while (cbWrite > 0);
     172        }
     173    }
    148174    else
    149175    {
    150         uint8_t *pbBuf = (uint8_t *)pvBuf;
    151         uint8_t abBuf[512];
    152 
    153         /* Unaligned buffered read+write of head.  Aligns the offset. */
     176
     177        /*
     178         * Unaligned buffered read+write of head.  Aligns the offset.
     179        */
    154180        if (offMisalign)
    155181        {
     
    158184            {
    159185                size_t const cbPart = RT_MIN(512 - offMisalign, cbWrite);
    160                 memcpy(&abBuf[offMisalign], pbBuf, cbPart);
     186                memcpy(&abBuf[offMisalign], pbSrc, cbPart);
    161187                rc = VDWrite(pDisk, off - offMisalign, abBuf, 512);
    162188                if (RT_SUCCESS(rc))
    163189                {
    164                     pbBuf   += cbPart;
     190                    pbSrc   += cbPart;
    165191                    off     += cbPart;
    166192                    cbWrite -= cbPart;
     
    171197            rc = VINF_SUCCESS;
    172198
    173         /* Aligned direct write. */
     199        /*
     200         * Aligned direct write.
     201         */
    174202        if (   RT_SUCCESS(rc)
    175203            && cbWrite >= 512)
    176204        {
    177205            Assert(!(off % 512));
    178 
    179206            size_t cbPart = cbWrite - cbMisalign;
    180207            Assert(!(cbPart % 512));
    181             rc = VDWrite(pDisk, off, pbBuf, cbPart);
    182             if (RT_SUCCESS(rc))
    183             {
    184                 pbBuf   += cbPart;
    185                 off     += cbPart;
    186                 cbWrite -= cbPart;
    187             }
    188         }
    189 
    190         /* Unaligned buffered read+write of tail. */
     208
     209            if (RTListIsEmpty(&pDisk->ListFilterChainWrite))
     210            {
     211                rc = VDWrite(pDisk, off, pbSrc, cbPart);
     212                if (RT_SUCCESS(rc))
     213                {
     214                    pbSrc   += cbPart;
     215                    off     += cbPart;
     216                    cbWrite -= cbPart;
     217                }
     218            }
     219            else
     220            {
     221                /* Filtered writes must be double buffered as the filter may need to modify the input buffer directly. */
     222                do
     223                {
     224                    size_t cbThisWrite = RT_MIN(cbPart, sizeof(abBuf));
     225                    rc = VDWrite(pDisk, off, memcpy(abBuf, pbSrc, cbThisWrite), cbThisWrite);
     226                    if (RT_SUCCESS(rc))
     227                    {
     228                        pbSrc   += cbThisWrite;
     229                        off     += cbThisWrite;
     230                        cbWrite -= cbThisWrite;
     231                        cbPart  -= cbThisWrite;
     232                    }
     233                    else
     234                        break;
     235                } while (cbPart > 0);
     236            }
     237        }
     238
     239        /*
     240         * Unaligned buffered read+write of tail.
     241         */
    191242        if (   RT_SUCCESS(rc)
    192243            && cbWrite > 0)
     
    199250            if (RT_SUCCESS(rc))
    200251            {
    201                 memcpy(abBuf, pbBuf, cbWrite);
     252                memcpy(abBuf, pbSrc, cbWrite);
    202253                rc = VDWrite(pDisk, off, abBuf, 512);
    203254            }
     
    578629    if (RT_SUCCESS(rc))
    579630    {
    580         pThis->offCurPos = 0;
    581         pThis->pDisk     = pDisk;
    582         pThis->fFlags    = fFlags;
     631        pThis->offCurPos        = 0;
     632        pThis->pDisk            = pDisk;
     633        pThis->fFlags           = fFlags;
    583634
    584635        *phVfsFile = hVfsFile;
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