Windows: non-release only worker threads can release
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 17 Nov 2011 05:30:24 +0000 (00:30 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 18 Nov 2011 06:06:52 +0000 (22:06 -0800)
There are two classes of worker threads created by the service
and donated to the afsredir as part of the reverse ioctl processing
model.  Normal workers can process any kind of ioctl and Release
Only workers that can only process release extent events.

Use a KeWaitForMultipleEvents in the normal worker case to permit
processing any type of event.  The previous implementation excluded
release extent ioctls from the normal workers.

Change-Id: I05e86f62c08e322cf7aa9bdd2fd325919bcbfe8f
Reviewed-on: http://gerrit.openafs.org/6071
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>

src/WINNT/afsrdr/kernel/fs/AFSCommSupport.cpp

index f803c7e..9585be6 100644 (file)
@@ -1124,6 +1124,7 @@ AFSProcessIrpRequest( IN PIRP Irp)
     AFSPoolEntry    *pEntry = NULL, *pPrevEntry = NULL;
     AFSCommRequest  *pRequest = NULL;
     BOOLEAN          bReleaseRequestThread = FALSE;
+    PVOID            Objects[2];
 
     __Enter
     {
@@ -1162,6 +1163,19 @@ AFSProcessIrpRequest( IN PIRP Irp)
         }
 
         //
+        // Populate the objects array for the non release only threads
+        // Release only workers can only process release extent events
+        // whereas normal workers can process any kind of event.
+        // Release only workers are present to ensure there cannot be
+        // a deadlock due to all extents held by the redirector and
+        // there not be a worker available to release them.
+        //
+
+        Objects[0] = &pCommSrvc->IrpPoolHasReleaseEntries;
+
+        Objects[1] = &pCommSrvc->IrpPoolHasEntries;
+
+        //
         // Wait on the 'have items' event until we can retrieve an item
         //
 
@@ -1176,23 +1190,36 @@ AFSProcessIrpRequest( IN PIRP Irp)
                                                   UserMode,
                                                   TRUE,
                                                   NULL);
+
+                if( ntStatus != STATUS_SUCCESS)
+                {
+
+                    ntStatus = STATUS_DEVICE_NOT_READY;
+
+                    break;
+                }
+
             }
             else
             {
 
-                ntStatus = KeWaitForSingleObject( &pCommSrvc->IrpPoolHasEntries,
-                                                  UserRequest,
-                                                  UserMode,
-                                                  TRUE,
-                                                  NULL);
-            }
-
-            if( ntStatus != STATUS_SUCCESS)
-            {
+                ntStatus = KeWaitForMultipleObjects( 2,
+                                                     Objects,
+                                                     WaitAny,
+                                                     UserRequest,
+                                                     UserMode,
+                                                     TRUE,
+                                                     NULL,
+                                                     NULL);
+
+                if( ntStatus != STATUS_WAIT_0 &&
+                    ntStatus != STATUS_WAIT_1)
+                {
 
-                ntStatus = STATUS_DEVICE_NOT_READY;
+                    ntStatus = STATUS_DEVICE_NOT_READY;
 
-                break;
+                    break;
+                }
             }
 
             //