Windows: PrimaryvolumeWorker do not pause if busy fcb
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 8 Oct 2012 03:41:32 +0000 (23:41 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Fri, 19 Oct 2012 15:50:19 +0000 (08:50 -0700)
The AFSPrimaryVolumeWorkerThread should not unnecessarily block
on the FCB Resource because such blockage could be the result of
of waiiting for extents to be delivered from the service.  The
AFSPrimaryVolumeWorkerThread is the primary method by which
extents are released back to the service.

AFSCleanupFcb() is modified to return STATUS_RETRY if the Fcb
resource cannot be obtained without blocking.

The AFSPrimaryVolumeWorkerThread() does not call
AFSCleanupFcb() with 'ForceFlush' parameter set to TRUE and
remembers if STATUS_RETRY is returned.  If any Fcb was busy,
then the worker does not wait for the 5 second timer to fire.

Change-Id: If3eab06b902202483eb354362a4db6bc8167d0df
Reviewed-on: http://gerrit.openafs.org/8227
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp

index 91faa96..fc85688 100644 (file)
@@ -7148,82 +7148,89 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
               ( 0 != Fcb->Specific.File.ExtentCount &&
                 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
                 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
-                                        (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
-            AFSAcquireExcl( &Fcb->NPFcb->Resource,
-                            ForceFlush))
+                                        (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
         {
 
-            __try
+            if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush))
             {
 
-                CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
-                              NULL,
-                              0,
-                              &stIoStatus);
-
-                if( !NT_SUCCESS( stIoStatus.Status))
+                __try
                 {
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                  AFS_TRACE_LEVEL_ERROR,
-                                  "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
-                                  Fcb->ObjectInformation->FileId.Cell,
-                                  Fcb->ObjectInformation->FileId.Volume,
-                                  Fcb->ObjectInformation->FileId.Vnode,
-                                  Fcb->ObjectInformation->FileId.Unique,
-                                  stIoStatus.Status,
-                                  stIoStatus.Information);
-
-                    ntStatus = stIoStatus.Status;
-                }
-
-                if( ForceFlush)
-                {
+                    CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
+                                  NULL,
+                                  0,
+                                  &stIoStatus);
 
-                    if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
-                                               NULL,
-                                               0,
-                                               FALSE))
+                    if( !NT_SUCCESS( stIoStatus.Status))
                     {
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
-                                      AFS_TRACE_LEVEL_WARNING,
-                                      "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                       Fcb->ObjectInformation->FileId.Cell,
                                       Fcb->ObjectInformation->FileId.Volume,
                                       Fcb->ObjectInformation->FileId.Vnode,
-                                      Fcb->ObjectInformation->FileId.Unique);
+                                      Fcb->ObjectInformation->FileId.Unique,
+                                      stIoStatus.Status,
+                                      stIoStatus.Information);
 
-                        SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        ntStatus = stIoStatus.Status;
+                    }
+
+                    if( ForceFlush)
+                    {
+
+                        if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
+                                                   NULL,
+                                                   0,
+                                                   FALSE))
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+                                          AFS_TRACE_LEVEL_WARNING,
+                                          "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                          Fcb->ObjectInformation->FileId.Cell,
+                                          Fcb->ObjectInformation->FileId.Volume,
+                                          Fcb->ObjectInformation->FileId.Vnode,
+                                          Fcb->ObjectInformation->FileId.Unique);
+
+                            SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                        }
                     }
                 }
-            }
-            __except( EXCEPTION_EXECUTE_HANDLER)
-            {
+                __except( EXCEPTION_EXECUTE_HANDLER)
+                {
 
-                ntStatus = GetExceptionCode();
+                    ntStatus = GetExceptionCode();
 
-                AFSDbgLogMsg( 0,
-                              0,
-                              "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
-                              Fcb->ObjectInformation->FileId.Cell,
-                              Fcb->ObjectInformation->FileId.Volume,
-                              Fcb->ObjectInformation->FileId.Vnode,
-                              Fcb->ObjectInformation->FileId.Unique,
-                              ntStatus);
-            }
+                    AFSDbgLogMsg( 0,
+                                  0,
+                                  "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+                                  Fcb->ObjectInformation->FileId.Cell,
+                                  Fcb->ObjectInformation->FileId.Volume,
+                                  Fcb->ObjectInformation->FileId.Vnode,
+                                  Fcb->ObjectInformation->FileId.Unique,
+                                  ntStatus);
+                }
 
-            AFSReleaseResource( &Fcb->NPFcb->Resource);
+                AFSReleaseResource( &Fcb->NPFcb->Resource);
 
-            if( Fcb->OpenReferenceCount <= 0)
-            {
+                if( Fcb->OpenReferenceCount <= 0)
+                {
 
-                //
-                // Tear em down we'll not be needing them again
-                //
+                    //
+                    // Tear em down we'll not be needing them again
+                    //
 
-                AFSTearDownFcbExtents( Fcb,
-                                       NULL);
+                    AFSTearDownFcbExtents( Fcb,
+                                           NULL);
+                }
+            }
+            else
+            {
+
+                ntStatus = STATUS_RETRY;
             }
         }
 
index fc90bd7..6d649bf 100644 (file)
@@ -964,6 +964,7 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
     LONG lFileType;
     LARGE_INTEGER liCurrentTime;
     BOOLEAN bVolumeObject = FALSE;
+    BOOLEAN bFcbBusy = FALSE;
     LONG lCount;
 
     pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
@@ -1007,11 +1008,20 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
     while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
     {
 
-        KeWaitForSingleObject( &Timer,
-                               Executive,
-                               KernelMode,
-                               FALSE,
-                               NULL);
+        if ( bFcbBusy == FALSE)
+        {
+
+            KeWaitForSingleObject( &Timer,
+                                   Executive,
+                                   KernelMode,
+                                   FALSE,
+                                   NULL);
+        }
+        else
+        {
+
+            bFcbBusy = FALSE;
+        }
 
         //
         // This is the primary volume worker so it will traverse the volume list
@@ -1409,8 +1419,14 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                         // pCurrentObject->ObjectReferenceCount to change
                                         //
 
-                                        AFSCleanupFcb( pCurrentChildObject->Fcb,
-                                                       TRUE);
+                                        ntStatus = AFSCleanupFcb( pCurrentChildObject->Fcb,
+                                                                  TRUE);
+
+                                        if ( ntStatus == STATUS_RETRY)
+                                        {
+
+                                            bFcbBusy = TRUE;
+                                        }
 
                                         AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
                                                         TRUE);
@@ -1558,8 +1574,14 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                             // pCurrentObject->ObjectReferenceCount to change
                             //
 
-                            AFSCleanupFcb( pCurrentObject->Fcb,
-                                           TRUE);
+                            ntStatus = AFSCleanupFcb( pCurrentObject->Fcb,
+                                                      FALSE);
+
+                            if ( ntStatus == STATUS_RETRY)
+                            {
+
+                                bFcbBusy = TRUE;
+                            }
                         }
 
                         if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,