From d9e14a08129cc70a3baca67c2c1adb8aba5945a2 Mon Sep 17 00:00:00 2001 From: Rod Widdowson Date: Sun, 4 May 2014 14:33:11 -0400 Subject: [PATCH] Windows: Adjust Last Write time handling for -1 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 Reviewed-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp | 25 ++++++++++++++++-------- src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp | 18 ++++++++++++++++- src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp | 11 ++++------- src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h | 4 ++-- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp index 5fa79a3..3361a9b 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp @@ -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 diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp index 43e895b..478d546 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp @@ -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 { diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp index 1376d06..57c38f4 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp @@ -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); } } diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h index 9e25bc1..3547e8c 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h @@ -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 -- 1.9.4