Windows: Adjust Last Write time handling for -1
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSWrite.cpp
index 05a715d..57c38f4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -121,6 +121,8 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
     BOOLEAN            bReleasePaging = FALSE;
     BOOLEAN            bExtendingWrite = FALSE;
     BOOLEAN            bSynchronousFo = FALSE;
+    BOOLEAN           bWriteToEndOfFile = FALSE;
+    BOOLEAN           bWait = FALSE;
     BOOLEAN            bCompleteIrp = TRUE;
     BOOLEAN            bForceFlush = FALSE;
     BOOLEAN            bLockOK;
@@ -177,6 +179,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
         liStartingByte = pIrpSp->Parameters.Write.ByteOffset;
         bPagingIo      = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
         bNonCachedIo   = BooleanFlagOn( Irp->Flags, IRP_NOCACHE);
+       bWait          = IoIsOperationSynchronous( Irp);
         ulByteCount    = pIrpSp->Parameters.Write.Length;
         bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
 
@@ -257,7 +260,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
                           "AFSCommonWrite (%p) Request failed due to read only volume\n",
                           Irp));
 
-            try_return( ntStatus = STATUS_ACCESS_DENIED);
+            try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
         }
 
         //
@@ -386,7 +389,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
                     CcSetDirtyPageThreshold( pFileObject,
                                              AFS_DIRTY_CHUNK_THRESHOLD * pDeviceExt->Specific.RDR.MaximumRPCLength / 4096);
                 }
-               __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+               __except( EXCEPTION_EXECUTE_HANDLER)
                 {
 
                     ntStatus = GetExceptionCode();
@@ -430,7 +433,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
 
                while (!CcCanIWrite( pFileObject,
                                     ulByteCount,
-                                    FALSE,
+                                    bWait && !bRetry,
                                     bRetry))
                {
                    static const LONGLONG llWriteDelay = (LONGLONG)-100000;
@@ -450,7 +453,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
 
                if (!CcCanIWrite( pFileObject,
                                  ulByteCount,
-                                 FALSE,
+                                 bWait && !bRetry,
                                  bRetry))
                {
 
@@ -545,10 +548,12 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
             else
             {
 
-                bExtendingWrite = (((liStartingByte.QuadPart + ulByteCount) >=
-                                     pFcb->Header.FileSize.QuadPart) ||
-                                    (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
-                                      liStartingByte.HighPart == -1)) ;
+               bWriteToEndOfFile = liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
+                                   liStartingByte.HighPart == -1;
+
+               bExtendingWrite = ( bWriteToEndOfFile ||
+                                   ((liStartingByte.QuadPart + ulByteCount) >=
+                                     pFcb->Header.FileSize.QuadPart));
 
                 if( bExtendingWrite || bNonCachedIo)
                 {
@@ -585,20 +590,24 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject,
 
                     bReleaseSectionObject = TRUE;
 
-                    if (liStartingByte.LowPart == FILE_WRITE_TO_END_OF_FILE &&
-                         liStartingByte.HighPart == -1)
-                    {
-                        if (pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
-                        {
-                            liStartingByte = pFcb->Header.ValidDataLength;
-                        }
-                        else
-                        {
-                            liStartingByte = pFcb->Header.FileSize;
-                        }
-                    }
+                   if ( bWriteToEndOfFile)
+                   {
 
-                    //
+                       if (pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
+                       {
+
+                           liStartingByte = pFcb->Header.ValidDataLength;
+                       }
+                       else
+                       {
+
+                           liStartingByte = pFcb->Header.FileSize;
+                       }
+
+                       pIrpSp->Parameters.Write.ByteOffset = liStartingByte;
+                   }
+
+                   //
                     // We have the correct lock - even if we don't end up truncating
                     //
                     bLockOK = TRUE;
@@ -752,7 +761,8 @@ try_exit:
                       Irp,
                       ntStatus));
 
-        if ( NT_SUCCESS( ntStatus))
+       if ( NT_SUCCESS( ntStatus) &&
+            ntStatus != STATUS_PENDING)
         {
             if ( !bPagingIo)
             {
@@ -774,17 +784,15 @@ try_exit:
                     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);
-                }
+               //
+               // Register the File Object as having modified the file.
+               //
+               SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
             }
         }
 
-        if ( !bPagingIo && bNonCachedIo && CcIsFileCached( pFileObject) &&
+       if ( ntStatus != STATUS_PENDING &&
+            !bPagingIo && bNonCachedIo && CcIsFileCached( pFileObject) &&
              pNPFcb->SectionObjectPointers.DataSectionObject != NULL &&
              bReleaseSectionObject)
         {
@@ -829,7 +837,7 @@ try_exit:
                    SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                }
            }
-           __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+           __except( EXCEPTION_EXECUTE_HANDLER)
            {
 
                DWORD ntStatus2 = GetExceptionCode();
@@ -1848,7 +1856,7 @@ AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
 
                 ntStatus = Irp->IoStatus.Status;
             }
-           __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+           __except( EXCEPTION_EXECUTE_HANDLER)
             {
                 ntStatus = GetExceptionCode();
 
@@ -1946,7 +1954,7 @@ AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
                     try_return( ntStatus = STATUS_UNSUCCESSFUL);
                 }
             }
-           __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+           __except( EXCEPTION_EXECUTE_HANDLER)
             {
 
                 ntStatus = GetExceptionCode();
@@ -1998,7 +2006,7 @@ AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
                        try_return( ntStatus = iosbFlush.Status);
                    }
                }
-               __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+               __except( EXCEPTION_EXECUTE_HANDLER)
                 {
 
                    ntStatus = GetExceptionCode();
@@ -2143,8 +2151,6 @@ AFSShareWrite( IN PDEVICE_OBJECT DeviceObject,
     __Enter
     {
 
-        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
-
         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
 
         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
@@ -2181,6 +2187,8 @@ AFSShareWrite( IN PDEVICE_OBJECT DeviceObject,
             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
         }
 
+       pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
+
         AFSAcquireShared( &pFcb->NPFcb->Resource,
                           TRUE);