VirtualBox

Ignore:
Timestamp:
May 2, 2019 9:49:04 PM (6 years ago)
Author:
vboxsync
Message:

winnt/vboxsf: Try keep the FCB file sizes (in FSRTL_COMMON_FCB_HEADER) up to date when we have relevant info handy. For now that means setting information, querying information and reading. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/file.cpp

    r78363 r78365  
    227227static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
    228228{
    229     NTSTATUS Status = STATUS_SUCCESS;
    230229    VBSFTRANSFERCTX ctx;
    231230
     
    240239
    241240    PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
    242     uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
    243     RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
    244241
    245242    PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
    246 
    247     int vrc;
    248243
    249244#ifdef LOG_ENABLED
     
    258253         pbUserBuffer, BufferMdl));
    259254    Log(("VBOXSF: vbsfReadInternal: ByteCount 0x%X, ByteOffset 0x%RX64, FileSize 0x%RX64\n",
    260          ByteCount, ByteOffset, FileSize));
     255         LowIoContext->ParamsFor.ReadWrite.ByteCount, LowIoContext->ParamsFor.ReadWrite.ByteOffset, FileSize));
    261256
    262257    AssertReturn(BufferMdl, STATUS_INVALID_PARAMETER);
    263     Assert(ByteCount > 0); /* ASSUME this is taken care of elsewhere already. */
     258    Assert(LowIoContext->ParamsFor.ReadWrite.ByteCount > 0); /* ASSUME this is taken care of elsewhere already. */
    264259
    265260    ctx.pClient = &g_SfClient;
    266261    ctx.pMap    = &pNetRootExtension->map;
    267262    ctx.hFile   = pVBoxFobx->hFile;
    268     ctx.offset  = (uint64_t)ByteOffset;
    269     ctx.cbData  = ByteCount;
     263    ctx.offset  = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
     264    ctx.cbData  = LowIoContext->ParamsFor.ReadWrite.ByteCount;
    270265    ctx.pMdl    = BufferMdl;
    271266    ctx.pBuffer = (uint8_t *)pbUserBuffer;
     
    274269    ctx.pfnTransferPages = vbsfTransferPagesRead;
    275270
    276     vrc = vbsfTransferCommon(&ctx);
    277 
    278     ByteCount = ctx.cbData;
    279 
    280     Status = vbsfNtVBoxStatusToNt(vrc);
    281 
    282     if (Status == STATUS_SUCCESS)
     271    int vrc = vbsfTransferCommon(&ctx);
     272
     273    NTSTATUS Status;
     274    if (RT_SUCCESS(vrc))
    283275    {
    284276        pVBoxFobx->fTimestampsImplicitlyUpdated |= VBOX_FOBX_F_INFO_LASTACCESS_TIME;
    285277        if (pVBoxFcbx->pFobxLastAccessTime != pVBoxFobx)
    286278            pVBoxFcbx->pFobxLastAccessTime = NULL;
     279        Status = STATUS_SUCCESS;
     280
     281        /*
     282         * See if we've reached the EOF early or read beyond what we thought were the EOF.
     283         *
     284         * Note! We don't dare do this (yet) if we're in paging I/O as we then hold the
     285         *       PagingIoResource in shared mode and would probably deadlock in the
     286         *       updating code when taking the lock in exclusive mode.
     287         */
     288        if (RxContext->LowIoContext.Resource != capFcb->Header.PagingIoResource)
     289        {
     290            LONGLONG const offEndOfRead = LowIoContext->ParamsFor.ReadWrite.ByteOffset + ctx.cbData;
     291            LONGLONG       cbFileRdbss;
     292            RxGetFileSizeWithLock((PFCB)capFcb, &cbFileRdbss);
     293            if (   offEndOfRead < cbFileRdbss
     294                && ctx.cbData < LowIoContext->ParamsFor.ReadWrite.ByteCount /* hit EOF */)
     295                vbsfNtUpdateFcbSize(RxContext->pFobx->AssociatedFileObject, capFcb, pVBoxFobx, offEndOfRead, cbFileRdbss, -1);
     296            else if (offEndOfRead > cbFileRdbss)
     297                vbsfNtQueryAndUpdateFcbSize(pNetRootExtension, RxContext->pFobx->AssociatedFileObject, pVBoxFobx, capFcb, pVBoxFcbx);
     298        }
    287299    }
    288300    else
    289         ByteCount = 0; /* Nothing read. */
    290 
    291     RxContext->InformationToReturn = ByteCount;
    292 
    293 /** @todo if we read past the end-of-file as we know it, or if we reached
    294  * end-of-file earlier than we though, update the file size.  The
    295  * RxLowIoReadShellCompletion() routine does not seem to do this for is and
    296  * I (bird) couldn't find anyone else doing it either. */
     301    {
     302        ctx.cbData = 0; /* Nothing read. */
     303        Status = vbsfNtVBoxStatusToNt(vrc);
     304    }
     305
     306    RxContext->InformationToReturn = ctx.cbData;
    297307
    298308    Log(("VBOXSF: vbsfReadInternal: Status = 0x%08X, ByteCount = 0x%X\n",
    299          Status, ByteCount));
     309         Status, ctx.cbData));
    300310
    301311    return Status;
     
    317327}
    318328
     329/**
     330 * Read stuff from a file.
     331 *
     332 * Prior to calling us, RDBSS will have:
     333 *  - Called CcFlushCache() for uncached accesses.
     334 *  - For non-paging access the Fcb.Header.Resource lock in shared mode in one
     335 *    way or another (ExAcquireResourceSharedLite,
     336 *    ExAcquireSharedWaitForExclusive).
     337 *  - For paging the FCB isn't, but the Fcb.Header.PagingResource is taken
     338 *    in shared mode (ExAcquireResourceSharedLite).
     339 *
     340 * Upon completion, it will update the file pointer if applicable.  There are no
     341 * EOF checks and corresponding file size updating like in the write case, so
     342 * that's something we have to do ourselves it seems since the library relies on
     343 * the size information to be accurate in a few places (set EOF, cached reads).
     344 */
    319345NTSTATUS VBoxMRxRead(IN PRX_CONTEXT RxContext)
    320346{
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