VirtualBox

Ignore:
Timestamp:
Aug 19, 2023 2:57:05 AM (18 months ago)
Author:
vboxsync
Message:

IPRT,Storage,Puel: Changed the pfnRead and pfnWrite VFS methods and the RTVfsIoStrmSgRead, RTVfsIoStrmSgWrite, RTVfsFileSgRead and RTVfsFileSgWrite APIs to advance pSgBuf and respect the incoming position just like RTFileSgRead & RTFileSgWrite.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp

    r98103 r100908  
    246246 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
    247247 */
    248 static DECLCALLBACK(int) rtDvmVfsFile_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
    249 {
    250     PRTVFSDVMFILE pThis = (PRTVFSDVMFILE)pvThis;
    251     int rc = VINF_SUCCESS;
     248static DECLCALLBACK(int) rtDvmVfsFile_Read(void *pvThis, RTFOFF off, PRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
     249{
     250    PRTVFSDVMFILE const pThis = (PRTVFSDVMFILE)pvThis;
    252251
    253252    Assert(pSgBuf->cSegs == 1);
     
    257256     * Find the current position and check if it's within the volume.
    258257     */
     258    uint64_t const cbVol = RTDvmVolumeGetSize(pThis->hVol);
    259259    uint64_t offUnsigned = off < 0 ? pThis->offCurPos : (uint64_t)off;
    260     if (offUnsigned >= RTDvmVolumeGetSize(pThis->hVol))
     260    if (offUnsigned >= cbVol)
    261261    {
    262262        if (pcbRead)
     
    269269    }
    270270
    271     size_t cbLeftToRead;
    272     if (offUnsigned + pSgBuf->paSegs[0].cbSeg > RTDvmVolumeGetSize(pThis->hVol))
    273     {
    274         if (!pcbRead)
    275             return VERR_EOF;
    276         *pcbRead = cbLeftToRead = (size_t)(RTDvmVolumeGetSize(pThis->hVol) - offUnsigned);
     271    size_t       cbSeg = 0;
     272    void * const pvSeg = RTSgBufGetCurrentSegment(pSgBuf, ~(size_t)0, &cbSeg);
     273
     274    int    rcRet = VINF_SUCCESS;
     275    size_t cbToRead;
     276    if (cbSeg <= cbVol - offUnsigned)
     277        cbToRead = cbSeg;
     278    else if (pcbRead)
     279    {
     280        rcRet    = VINF_EOF;
     281        cbToRead = (size_t)(cbVol - offUnsigned);
    277282    }
    278283    else
    279     {
    280         cbLeftToRead = pSgBuf->paSegs[0].cbSeg;
    281         if (pcbRead)
    282             *pcbRead = cbLeftToRead;
    283     }
     284        return VERR_EOF;
    284285
    285286    /*
    286287     * Ok, we've got a valid stretch within the file.  Do the reading.
    287288     */
    288     if (cbLeftToRead > 0)
    289     {
    290         rc = RTDvmVolumeRead(pThis->hVol, offUnsigned, pSgBuf->paSegs[0].pvSeg, cbLeftToRead);
    291         if (RT_SUCCESS(rc))
    292             offUnsigned += cbLeftToRead;
     289    if (cbToRead > 0)
     290    {
     291        int rc2 = RTDvmVolumeRead(pThis->hVol, offUnsigned, pvSeg, cbToRead);
     292        if (RT_SUCCESS(rc2))
     293        {
     294            offUnsigned += cbToRead;
     295            RTSgBufAdvance(pSgBuf, cbToRead);
     296        }
     297        else
     298        {
     299            cbToRead = 0;
     300            rcRet = rc2;
     301        }
    293302    }
    294303
    295304    pThis->offCurPos = offUnsigned;
    296     return rc;
     305    if (pcbRead)
     306        *pcbRead = cbToRead;
     307    return rcRet;
    297308}
    298309
     
    301312 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
    302313 */
    303 static DECLCALLBACK(int) rtDvmVfsFile_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
    304 {
    305     PRTVFSDVMFILE pThis = (PRTVFSDVMFILE)pvThis;
    306     int rc = VINF_SUCCESS;
     314static DECLCALLBACK(int) rtDvmVfsFile_Write(void *pvThis, RTFOFF off, PRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
     315{
     316    PRTVFSDVMFILE const pThis = (PRTVFSDVMFILE)pvThis;
    307317
    308318    Assert(pSgBuf->cSegs == 1);
     
    313323     * Writing beyond the end of a volume is not supported.
    314324     */
     325    uint64_t const cbVol = RTDvmVolumeGetSize(pThis->hVol);
    315326    uint64_t offUnsigned = off < 0 ? pThis->offCurPos : (uint64_t)off;
    316     if (offUnsigned >= RTDvmVolumeGetSize(pThis->hVol))
     327    if (offUnsigned >= cbVol)
    317328    {
    318329        if (pcbWritten)
     
    321332            pThis->offCurPos = offUnsigned;
    322333        }
    323         return VERR_NOT_SUPPORTED;
    324     }
    325 
    326     size_t cbLeftToWrite;
    327     if (offUnsigned + pSgBuf->paSegs[0].cbSeg > RTDvmVolumeGetSize(pThis->hVol))
    328     {
    329         if (!pcbWritten)
    330             return VERR_EOF;
    331         *pcbWritten = cbLeftToWrite = (size_t)(RTDvmVolumeGetSize(pThis->hVol) - offUnsigned);
    332     }
     334        return VERR_DISK_FULL; /** @todo VERR_DISK_FULL is not the best status code. */
     335    }
     336
     337    size_t       cbSeg = 0;
     338    void * const pvSeg = RTSgBufGetCurrentSegment(pSgBuf, ~(size_t)0, &cbSeg);
     339
     340    size_t cbToWrite;
     341    if (cbSeg <= cbVol - offUnsigned)
     342        cbToWrite = cbSeg;
     343    else if (pcbWritten)
     344        cbToWrite = (size_t)(cbVol - offUnsigned);
    333345    else
    334     {
    335         cbLeftToWrite = pSgBuf->paSegs[0].cbSeg;
    336         if (pcbWritten)
    337             *pcbWritten = cbLeftToWrite;
    338     }
     346        return VERR_EOF; /** @todo status to use above? or rather use VERR_DISK_FULL? */
    339347
    340348    /*
    341349     * Ok, we've got a valid stretch within the file.  Do the reading.
    342350     */
    343     if (cbLeftToWrite > 0)
    344     {
    345         rc = RTDvmVolumeWrite(pThis->hVol, offUnsigned, pSgBuf->paSegs[0].pvSeg, cbLeftToWrite);
     351    int rc = VINF_SUCCESS;
     352    if (cbToWrite > 0)
     353    {
     354        rc = RTDvmVolumeWrite(pThis->hVol, offUnsigned, pvSeg, cbToWrite);
    346355        if (RT_SUCCESS(rc))
    347             offUnsigned += cbLeftToWrite;
     356        {
     357            offUnsigned += cbToWrite;
     358            RTSgBufAdvance(pSgBuf, cbToWrite);
     359        }
     360        else
     361            cbToWrite = 0;
    348362    }
    349363
    350364    pThis->offCurPos = offUnsigned;
     365    if (pcbWritten)
     366        *pcbWritten = cbToWrite;
    351367    return rc;
    352368}
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