Windows Asynchronous purging of file content after a DV change
authorPeter Scott <pscott@kerneldrivers.com>
Thu, 19 Jan 2012 01:42:19 +0000 (18:42 -0700)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 20 Jan 2012 07:07:03 +0000 (23:07 -0800)
Purge all regions of the file surrounding the extents which are to be
purged. If a failure occurs on the purge due to an existing mapping, flag
for purge during handle close

Change-Id: Id8ef81afaa614ea08e03bbd55ec2cdded0d7139f
Reviewed-on: http://gerrit.openafs.org/6573
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

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

index 5f5be09..af8c180 100644 (file)
@@ -636,6 +636,15 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
 
                 AFSReleaseResource( &pFcb->NPFcb->Resource);
 
+                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE))
+                {
+                    InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                    ClearFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+                    AFSPerformObjectInvalidate( pObjectInfo,
+                                                AFS_INVALIDATE_DATA_VERSION);
+                }
+
                 lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
index ca071ed..59a47e7 100644 (file)
@@ -8565,6 +8565,10 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
             case AFS_INVALIDATE_DATA_VERSION:
             {
 
+                LARGE_INTEGER liCurrentOffset = {0,0};
+                LARGE_INTEGER liFlushLength = {0,0};
+                ULONG ulFlushLength = 0;
+
                 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
                     ObjectInfo->Fcb != NULL)
                 {
@@ -8583,20 +8587,69 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
                         ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
 
-                        while( ulProcessCount < ulCount)
+                        if( ulCount > 0)
                         {
                             pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
 
-                            if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                            while( ulProcessCount < ulCount)
                             {
-                                CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                     &pEntry->FileOffset,
-                                                     pEntry->Size,
-                                                     FALSE);
+                                pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                                if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                                {
+                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                              &pEntry->FileOffset,
+                                                              pEntry->Size,
+                                                              FALSE))
+                                    {
+                                        SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                    }
+                                }
+
+                                if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+                                {
+
+                                    liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+
+                                    while( liFlushLength.QuadPart > 0)
+                                    {
+
+                                        if( liFlushLength.QuadPart > 512 * 1024000)
+                                        {
+                                            ulFlushLength = 512 * 1024000;
+                                        }
+                                        else
+                                        {
+                                            ulFlushLength = liFlushLength.LowPart;
+                                        }
+
+                                        if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                  &liCurrentOffset,
+                                                                  ulFlushLength,
+                                                                  FALSE))
+                                        {
+                                            SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                        }
+
+                                        liFlushLength.QuadPart -= ulFlushLength;
+                                    }
+                                }
+
+                                liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+
+                                ulProcessCount++;
+                                le = le->Flink;
+                            }
+                        }
+                        else
+                        {
+                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                      NULL,
+                                                      0,
+                                                      FALSE))
+                            {
+                                SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                             }
-
-                            ulProcessCount++;
-                            le = le->Flink;
                         }
                     }
                     __except( EXCEPTION_EXECUTE_HANDLER)
index d7c102e..c08e688 100644 (file)
@@ -136,6 +136,7 @@ NTSTATUS
 #define AFS_FCB_FLAG_UPDATE_ACCESS_TIME                      0x00000010
 #define AFS_FCB_FLAG_UPDATE_CREATE_TIME                      0x00000020
 #define AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME                  0x00000040
+#define AFS_FCB_FLAG_PURGE_ON_CLOSE                          0x00000080
 
 //
 // Object information flags