Windows: Decrement Fcb OpenHandleCount while locked
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 29 Dec 2012 20:58:06 +0000 (15:58 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 31 Jan 2013 19:29:34 +0000 (11:29 -0800)
AFSCleanup performs tests on the Fcb Open Handle Count to determine
when to perform final cleanup tasks on the last handle close.  The
test is protected by holding the Fcb Resource.  If the Open Handle
Count is decremented after dropping the Resource, it creates a
race with other threads that might be blocked entering AFSCleanup
to close their handle on the same object.

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

src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp

index d8d31c5..6c8668c 100644 (file)
@@ -154,9 +154,11 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                 AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                   TRUE);
 
-                ASSERT( pFcb->OpenHandleCount != 0);
+                FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync,
+                                    &pControlDeviceExt->Specific.Control.DirNotifyList,
+                                    pCcb);
 
-                AFSReleaseResource( &pFcb->NPFcb->Resource);
+                ASSERT( pFcb->OpenHandleCount != 0);
 
                 lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
 
@@ -166,9 +168,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                               pFcb,
                               lCount);
 
-                FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync,
-                                    &pControlDeviceExt->Specific.Control.DirNotifyList,
-                                    pCcb);
+                AFSReleaseResource( &pFcb->NPFcb->Resource);
 
                 break;
             }
@@ -1071,8 +1071,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                   lCount);
                 }
 
-                AFSReleaseResource( &pFcb->NPFcb->Resource);
-
                 lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -1081,6 +1079,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                               pFcb,
                               lCount);
 
+                AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                 break;
             }
 
@@ -1372,8 +1372,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                   lCount);
                 }
 
-                AFSReleaseResource( &pFcb->NPFcb->Resource);
-
                 lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -1382,6 +1380,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                               pFcb,
                               lCount);
 
+                AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                 break;
             }
 
@@ -1418,8 +1418,6 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                                   lCount);
                 }
 
-                AFSReleaseResource( &pFcb->NPFcb->Resource);
-
                 lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -1428,13 +1426,15 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
                               pFcb,
                               lCount);
 
+                AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                 break;
             }
 
             default:
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_WARNING,
+                              AFS_TRACE_LEVEL_ERROR,
                               "AFSCleanup Processing unknown node type %d\n",
                               pFcb->Header.NodeTypeCode);