Windows: Protect ObjectRefCnts with ObjectInfoLock
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSWorker.cpp
index 869e145..fc90bd7 100644 (file)
@@ -1066,6 +1066,9 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                 pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
 
+                AFSAcquireShared( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock,
+                                  TRUE);
+
                 if( pVolumeCB->ObjectInfoListHead == NULL &&
                     pVolumeCB->DirectoryCB->OpenReferenceCount == 0 &&
                     pVolumeCB->VolumeReferenceCount == 1 &&
@@ -1080,11 +1083,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                         AFSRemoveRootFcb( pVolumeCB->RootFcb);
                     }
 
+                    AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
                     AFSRemoveVolume( pVolumeCB);
                 }
                 else
                 {
 
+                    AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
                     AFSReleaseResource( pVolumeCB->VolumeLock);
                 }
 
@@ -1171,6 +1178,9 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                                 FALSE))
                             {
 
+                                AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+                                                TRUE);
+
                                 if ( pCurrentObject->ObjectReferenceCount <= 0 &&
                                      ( pCurrentObject->Fcb == NULL ||
                                        pCurrentObject->Fcb->OpenReferenceCount == 0 &&
@@ -1182,8 +1192,13 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                     if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
                                     {
 
+                                        AFSAcquireExcl( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                                        TRUE);
+
                                         AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
 
+                                        AFSReleaseResource( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
                                         AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
 
                                         ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
@@ -1193,6 +1208,8 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                         AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
                                     }
 
+                                    AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+
                                     AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                                   AFS_TRACE_LEVEL_VERBOSE,
                                                   "AFSPrimaryVolumeWorkerThread Deleting deleted object %08lX\n",
@@ -1200,6 +1217,11 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                                     AFSDeleteObjectInfo( pCurrentObject);
                                 }
+                                else
+                                {
+
+                                    AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+                                }
 
                                 AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
 
@@ -1360,6 +1382,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                     AFSDeleteDirEntry( pCurrentObject,
                                                        pCurrentDirEntry);
 
+
+                                    //
+                                    // Acquire ObjectInfoLock shared here so as not to deadlock
+                                    // with an invalidation call from the service during AFSCleanupFcb
+                                    //
+
+                                    AFSAcquireShared( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+                                                      TRUE);
+
                                     if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
                                         pCurrentChildObject->Fcb != NULL &&
                                         pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE)
@@ -1385,6 +1416,11 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                                         TRUE);
                                     }
 
+                                    AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+
+                                    AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+                                                    TRUE);
+
                                     if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
                                         ( pCurrentChildObject->Fcb == NULL ||
                                           pCurrentChildObject->Fcb->OpenReferenceCount == 0 &&
@@ -1397,8 +1433,13 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                             pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
                                         {
 
+                                            AFSAcquireExcl( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                                            TRUE);
+
                                             AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
 
+                                            AFSReleaseResource( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
                                             AFSDeleteObjectInfo( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
 
                                             ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
@@ -1408,6 +1449,8 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                                             AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
                                         }
 
+                                        AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+
                                         AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                                       AFS_TRACE_LEVEL_VERBOSE,
                                                       "AFSPrimaryVolumeWorkerThread Deleting object %08lX\n",
@@ -1415,6 +1458,11 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                                         AFSDeleteObjectInfo( pCurrentChildObject);
                                     }
+                                    else
+                                    {
+
+                                        AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+                                    }
 
                                     pCurrentDirEntry = pNextDirEntry;
 
@@ -1523,6 +1571,9 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                             break;
                         }
 
+                        AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+                                        TRUE);
+
                         if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
                             pCurrentObject->ObjectReferenceCount <= 0 &&
                             ( pCurrentObject->Fcb == NULL ||
@@ -1532,8 +1583,15 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
 
                             AFSRemoveFcb( &pCurrentObject->Fcb);
 
+                            AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+
                             AFSDeleteObjectInfo( pCurrentObject);
                         }
+                        else
+                        {
+
+                            AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+                        }
 
                         AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);