Windows: Update ValidDataLength on all nonPagingIo
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 7 Apr 2013 12:26:18 +0000 (08:26 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 9 Apr 2013 17:38:28 +0000 (10:38 -0700)
Instead of updating the Fcb->Header.ValidDataLength only when
processing cached writes, update it for all non-PagingIo extending writes.
This ensures that a file that is extended by a mixture of cached and
non-cached (NO_INTERMEDIATE_BUFFERING) writes will properly trigger a
page fault when the Windows cache manager does not have a complete page
cached.

Change-Id: I255bb667e33fadd07eb8961901d33707812a8406
Reviewed-on: http://gerrit.openafs.org/9742
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Peter Scott <pscott@kerneldrivers.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp

index d58e534..e7e3ed9 100644 (file)
@@ -120,6 +120,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
     BOOLEAN            bReleaseSectionObject = FALSE;
     BOOLEAN            bReleasePaging = FALSE;
     BOOLEAN            bExtendingWrite = FALSE;
+    BOOLEAN            bSynchronousFo = FALSE;
     BOOLEAN            bCompleteIrp = TRUE;
     BOOLEAN            bForceFlush = FALSE;
     BOOLEAN            bLockOK;
@@ -177,6 +178,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
         bPagingIo      = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
         bNonCachedIo   = BooleanFlagOn( Irp->Flags, IRP_NOCACHE);
         ulByteCount    = pIrpSp->Parameters.Write.Length;
+        bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
 
         if( pFcb->Header.NodeTypeCode != AFS_IOCTL_FCB &&
             pFcb->Header.NodeTypeCode != AFS_FILE_FCB  &&
@@ -664,7 +666,6 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
                           bRetry ? " RETRY" : ""));
 
             ntStatus = AFSCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount, bForceFlush);
-
         }
         else
         {
@@ -696,6 +697,37 @@ try_exit:
                       Irp,
                       ntStatus));
 
+        if ( NT_SUCCESS( ntStatus))
+        {
+            if ( !bPagingIo)
+            {
+
+                if( bSynchronousFo)
+                {
+
+                    pFileObject->CurrentByteOffset.QuadPart = liStartingByte.QuadPart + ulByteCount;
+                }
+
+                //
+                // If this extended the Vdl, then update it accordingly
+                //
+
+                if( liStartingByte.QuadPart + ulByteCount > pFcb->Header.ValidDataLength.QuadPart)
+                {
+
+                    pFcb->Header.ValidDataLength.QuadPart = liStartingByte.QuadPart + ulByteCount;
+                }
+
+                if( !BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME))
+                {
+
+                    SetFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME);
+
+                    KeQuerySystemTime( &pFcb->ObjectInformation->LastWriteTime);
+                }
+            }
+        }
+
         ObDereferenceObject(pFileObject);
 
         if( bReleaseSectionObject)
@@ -1859,22 +1891,6 @@ try_exit:
 
             Irp->IoStatus.Information = ByteCount;
 
-            if( bSynchronousFo)
-            {
-
-                pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
-            }
-
-            //
-            // If this extended the Vdl, then update it accordingly
-            //
-
-            if( StartingByte.QuadPart + ByteCount > pFcb->Header.ValidDataLength.QuadPart)
-            {
-
-                pFcb->Header.ValidDataLength.QuadPart = StartingByte.QuadPart + ByteCount;
-            }
-
             if ( ForceFlush ||
                  BooleanFlagOn(pFileObject->Flags, (FO_NO_INTERMEDIATE_BUFFERING + FO_WRITE_THROUGH)))
             {
@@ -1884,14 +1900,6 @@ try_exit:
                 //
                 pFcb->Specific.File.LastServerFlush.QuadPart = 0;
             }
-
-            if( !BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME))
-            {
-
-                SetFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME);
-
-                KeQuerySystemTime( &pFcb->ObjectInformation->LastWriteTime);
-            }
         }
 
         AFSCompleteRequest( Irp,