Windows: Adjust Last Write time handling for -1
authorRod Widdowson <rdw@your-file-system.com>
Sun, 4 May 2014 18:33:11 +0000 (14:33 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Mon, 5 May 2014 12:49:47 +0000 (08:49 -0400)
The "what date/time gets changed when and by whom" in Windows is badly
defined, but all filesystems support the semantic that if a date is set
using a specific file object (or the timestamp is set to the magic number
-1)
then other changes provoked by that file object will be ignored.

AFS redirector timestamp handling does not support this behavior.
For the LastWrite timestamp (other timestamps are pretty much advisory and
maintained on a best effort basis) the timestamp would be updated by a
write operation even after -1 is set via the file handle.

This patchset implements the -1 behavior for LastWrite.  It also follows
the standard Windows practice of setting the LastWrite timestamp to be the
time of close of the handle that performed the write, not the time of the
write itself.

Finally, it should be noted that since RX*FS_StoreXXX operations update
the last write time on the server the client must restore the LastWrite
timestamp at handle close if -1 was specified.

Change-Id: Ica0c566fabb6b3046eb51f827402d622190daea8
Reviewed-on: http://gerrit.openafs.org/11110
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp
src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp
src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h

index 5fa79a3..3361a9b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Kernel Drivers, LLC.
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 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
@@ -382,6 +382,21 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;
 
+               //
+               // If the file has been modified set the last write time in ObjectInfo to 'now'
+               // unless the last write time was set via this File Object.  Then tell the
+               // following code to write the time.
+               //
+               if ( BooleanFlagOn( pFileObject->Flags, FO_FILE_MODIFIED) &&
+                    !BooleanFlagOn( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET)) {
+
+                   SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+
+                   SetFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
+
+                   KeQuerySystemTime(&pFcb->ObjectInformation->LastWriteTime);
+               }
+
                 if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                 {
 
@@ -418,16 +433,10 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                         stFileCleanup.LastWriteTime = pObjectInfo->LastWriteTime;
 
-                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME | AFS_FCB_FLAG_UPDATE_WRITE_TIME);
+                       ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
                     }
                 }
 
-                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME))
-                {
-
-                    stFileCleanup.LastWriteTime = pObjectInfo->LastWriteTime;
-                }
-
                 //
                 // If the count has dropped to one and there is a pending delete
                 // then delete the node.  The final count will be decremented just
index 43e895b..478d546 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, 2014 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -2063,6 +2063,12 @@ AFSSetBasicInfo( IN PIRP Irp,
             ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
 
             SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
+
+           SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
+
+       } else if ( pBuffer->LastWriteTime.QuadPart == (ULONGLONG)-1) {
+
+           SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
         }
 
         pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
@@ -3904,6 +3910,11 @@ AFSSetAllocationInfo( IN PIRP Irp,
             CcSetFileSizes( pFileObject,
                             (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
         }
+
+       //
+       // Mark the file as modified so as to reflect the change into the last write on close.
+       //
+       SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
     }
     else
     {
@@ -4138,6 +4149,11 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                 AFSTrimExtents( pFcb,
                                 &pFcb->Header.FileSize);
             }
+
+           //
+           // Mark the file as modified so as to reflect the change into the last write on close.
+           //
+           SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
         }
         else
         {
index 1376d06..57c38f4 100644 (file)
@@ -784,13 +784,10 @@ 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);
             }
         }
 
index 9e25bc1..3547e8c 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, 2014 Your File System, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -132,7 +132,6 @@ NTSTATUS
 
 #define AFS_FCB_FLAG_FILE_MODIFIED                           0x00000001
 #define AFS_FCB_FILE_CLOSED                                  0x00000002
-#define AFS_FCB_FLAG_UPDATE_WRITE_TIME                       0x00000004
 #define AFS_FCB_FLAG_UPDATE_CHANGE_TIME                      0x00000008
 #define AFS_FCB_FLAG_UPDATE_ACCESS_TIME                      0x00000010
 #define AFS_FCB_FLAG_UPDATE_CREATE_TIME                      0x00000020
@@ -267,6 +266,7 @@ NTSTATUS
 #define CCB_FLAG_MASK_OPENED_REPARSE_POINT  0x00000080
 #define CCB_FLAG_INSERTED_CCB_LIST          0x00000100
 #define CCB_FLAG_DIRECTORY_QUERY_DIRECT_QUERY 0x00000200
+#define CCB_FLAG_LAST_WRITE_TIME_SET        0x00000800
 
 //
 // DirEntry flags