VirtualBox

Changeset 70297 in vbox for trunk/src/VBox/Storage


Ignore:
Timestamp:
Dec 22, 2017 1:39:37 AM (7 years ago)
Author:
vboxsync
Message:

VDVfs.cpp: Fixed bug in vdReadHelper when handling unaligned reads, ended up with negative size. Just rewrote it a little bit. Applied the same fixes to vdWriteHelper.

File:
1 edited

Legend:

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

    r70225 r70297  
    6363static int vdReadHelper(PVDISK pDisk, uint64_t off, void *pvBuf, size_t cbRead)
    6464{
    65     int rc = VINF_SUCCESS;
    66 
    67     /* Take shortcut if possible. */
    68     if (   off % 512 == 0
    69         && cbRead % 512 == 0)
     65    int rc;
     66
     67    /* Take direct route if the request is sector aligned. */
     68    uint64_t const offMisalign = off & 511;
     69    size_t   const cbMisalign  = (off + cbRead) & 511;
     70    if (   !offMisalign
     71        && !cbMisalign)
    7072        rc = VDRead(pDisk, off, pvBuf, cbRead);
    7173    else
     
    7375        uint8_t *pbBuf = (uint8_t *)pvBuf;
    7476        uint8_t abBuf[512];
    75 
    76         /* Unaligned access, make it aligned. */
    77         if (off % 512 != 0)
    78         {
    79             uint64_t offAligned = off & ~(uint64_t)(512 - 1);
    80             size_t cbToCopy = 512 - (off - offAligned);
    81             rc = VDRead(pDisk, offAligned, abBuf, 512);
     77        rc = VINF_SUCCESS; /* Make compilers happy. */
     78
     79        /* Unaligned buffered read of head.  Aligns the offset. */
     80        if (offMisalign)
     81        {
     82            rc = VDRead(pDisk, off - offMisalign, abBuf, 512);
    8283            if (RT_SUCCESS(rc))
    8384            {
    84                 memcpy(pbBuf, &abBuf[off - offAligned], cbToCopy);
    85                 pbBuf  += cbToCopy;
    86                 off    += cbToCopy;
    87                 cbRead -= cbToCopy;
    88             }
    89         }
    90 
     85                size_t const cbPart = RT_MIN(512 - offMisalign, cbRead);
     86                memcpy(pbBuf, &abBuf[offMisalign], cbPart);
     87                pbBuf  += cbPart;
     88                off    += cbPart;
     89                cbRead -= cbPart;
     90            }
     91        }
     92
     93        /* Aligned direct read. */
    9194        if (   RT_SUCCESS(rc)
    92             && (cbRead & ~(uint64_t)(512 - 1)))
    93         {
    94             size_t cbReadAligned = cbRead & ~(uint64_t)(512 - 1);
    95 
     95            && cbRead >= 512)
     96        {
    9697            Assert(!(off % 512));
    97             rc = VDRead(pDisk, off, pbBuf, cbReadAligned);
     98
     99            size_t cbPart = cbRead - cbMisalign;
     100            rc = VDRead(pDisk, off, pbBuf, cbPart);
    98101            if (RT_SUCCESS(rc))
    99102            {
    100                 pbBuf  += cbReadAligned;
    101                 off    += cbReadAligned;
    102                 cbRead -= cbReadAligned;
    103             }
    104         }
    105 
     103                pbBuf  += cbPart;
     104                off    += cbPart;
     105                cbRead -= cbPart;
     106            }
     107        }
     108
     109        /* Unaligned buffered read of tail. */
    106110        if (   RT_SUCCESS(rc)
    107111            && cbRead)
     
    131135static int vdWriteHelper(PVDISK pDisk, uint64_t off, const void *pvBuf, size_t cbWrite)
    132136{
    133     int rc = VINF_SUCCESS;
    134 
    135     /* Take shortcut if possible. */
    136     if (   off % 512 == 0
    137         && cbWrite % 512 == 0)
     137    int rc;
     138
     139    /* Take direct route if the request is sector aligned. */
     140    uint64_t const offMisalign = off & 511;
     141    size_t   const cbMisalign  = (off + cbWrite) & 511;
     142    if (   !offMisalign
     143        && !cbMisalign)
    138144        rc = VDWrite(pDisk, off, pvBuf, cbWrite);
    139145    else
     
    141147        uint8_t *pbBuf = (uint8_t *)pvBuf;
    142148        uint8_t abBuf[512];
    143 
    144         /* Unaligned access, make it aligned. */
    145         if (off % 512 != 0)
    146         {
    147             uint64_t offAligned = off & ~(uint64_t)(512 - 1);
    148             size_t cbToCopy = 512 - (off - offAligned);
    149             rc = VDRead(pDisk, offAligned, abBuf, 512);
     149        rc = VINF_SUCCESS; /* Make compilers happy. */
     150
     151        /* Unaligned buffered read+write of head.  Aligns the offset. */
     152        if (offMisalign)
     153        {
     154            rc = VDRead(pDisk, off - offMisalign, abBuf, 512);
    150155            if (RT_SUCCESS(rc))
    151156            {
    152                 memcpy(&abBuf[off - offAligned], pbBuf, cbToCopy);
    153                 rc = VDWrite(pDisk, offAligned, abBuf, 512);
    154 
    155                 pbBuf   += cbToCopy;
    156                 off     += cbToCopy;
    157                 cbWrite -= cbToCopy;
    158             }
    159         }
    160 
     157                size_t const cbPart = RT_MIN(512 - offMisalign, cbWrite);
     158                memcpy(&abBuf[offMisalign], pbBuf, cbPart);
     159                rc = VDWrite(pDisk, off - offMisalign, abBuf, 512);
     160                if (RT_SUCCESS(rc))
     161                {
     162                    pbBuf   += cbPart;
     163                    off     += cbPart;
     164                    cbWrite -= cbPart;
     165                }
     166            }
     167        }
     168
     169        /* Aligned direct write. */
    161170        if (   RT_SUCCESS(rc)
    162             && (cbWrite & ~(uint64_t)(512 - 1)))
    163         {
    164             size_t cbWriteAligned = cbWrite & ~(uint64_t)(512 - 1);
    165 
     171            && cbWrite >= 512)
     172        {
    166173            Assert(!(off % 512));
    167             rc = VDWrite(pDisk, off, pbBuf, cbWriteAligned);
     174
     175            size_t cbPart = cbWrite - cbMisalign;
     176            rc = VDWrite(pDisk, off, pbBuf, cbPart);
    168177            if (RT_SUCCESS(rc))
    169178            {
    170                 pbBuf   += cbWriteAligned;
    171                 off     += cbWriteAligned;
    172                 cbWrite -= cbWriteAligned;
    173             }
    174         }
    175 
     179                pbBuf   += cbPart;
     180                off     += cbPart;
     181                cbWrite -= cbPart;
     182            }
     183        }
     184
     185        /* Unaligned buffered read+write of tail. */
    176186        if (   RT_SUCCESS(rc)
    177             && cbWrite)
     187            && cbMisalign)
    178188        {
    179189            Assert(cbWrite < 512);
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