Windows: AFSVolumeCB track RefCount reasons
authorJeffrey Altman <jaltman@your-file-system.com>
Mon, 4 Feb 2013 20:14:16 +0000 (15:14 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 6 Feb 2013 05:14:05 +0000 (21:14 -0800)
Introduct AFSVolumeIncrement and AFSVolumeDecrement functions
which are used to increment not only the AFSVolumeCB.VolumeReferenceCount
but also a new VolumeReferences[Reason] counter.  In the future when
a VolumeReferenceCount error occurs it may be possible to isolate the
cause to a subset of the code.

In the process, the VolumeReferenceCount necessary to free the
AFSVolumeCB object is changed from 1 to 0 and AFSInitVolume no longer
initializes the AFSVolumeCB count to 2.

The signature for AFSInitVolume and AFSLocateNameEntry are modified
to permit a volume reference reason to be provided.  This permits
the reference to be allocated in one function and released in another
without resulting in count imbalances.

Change-Id: I021a6efe061817ff044c18a699ee63a7ffbfc7bf
Reviewed-on: http://gerrit.openafs.org/9067
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/AFSCreate.cpp
src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h
src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h
src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h

index 20f4e9e..bff8341 100644 (file)
@@ -143,6 +143,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
     UNICODE_STRING      uniRelativeName;
     AFSNameArrayHdr    *pNameArray = NULL;
     AFSVolumeCB        *pVolumeCB = NULL;
+    LONG                VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB     *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
     BOOLEAN             bReleaseParentDir = FALSE, bReleaseDir = FALSE;
     ULONG               ulParseFlags = 0;
@@ -390,6 +391,8 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
         // We have a reference on the root volume
         //
 
+        VolumeReferenceReason = AFS_VOLUME_REFERENCE_PARSE_NAME;
+
         bReleaseVolume = TRUE;
 
         //
@@ -441,6 +444,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                            pNameArray,
                                            ulNameProcessingFlags,
                                            &pVolumeCB,
+                                           &VolumeReferenceReason,
                                            &pParentDirectoryCB,
                                            &pDirectoryCB,
                                            &uniComponentName);
@@ -467,13 +471,16 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               ntStatus);
 
                 //
-                // We released any root volume locks in the above on failure
+                // We released any root volume locks in AFSLocateNameEntry on failure
+                // other than STATUS_OBJECT_NAME_NOT_FOUND
                 //
 
                 bReleaseVolume = FALSE;
 
                 bReleaseParentDir = FALSE;
 
+                VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
+
                 try_return( ntStatus);
             }
 
@@ -1158,12 +1165,14 @@ try_exit:
         if( bReleaseVolume)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
+                          "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
                           pVolumeCB,
+                          VolumeReferenceReason,
                           lCount);
         }
 
index 247ccae..0b7cfc6 100644 (file)
@@ -1426,7 +1426,8 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_EXTENTS);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1568,7 +1569,8 @@ try_exit:
         if ( pVolumeCB)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_EXTENTS);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1839,7 +1841,8 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
         // The Volume list may move under our feet.  Lock it.
         //
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_EXTENTS);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -1860,7 +1863,8 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeDecrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_EXTENTS);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -2078,7 +2082,8 @@ AFSProcessExtentFailure( PIRP Irp)
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_EXTENTS);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2204,7 +2209,8 @@ try_exit:
         if ( pVolumeCB)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_EXTENTS);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2332,7 +2338,8 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
             if( pVolumeCB != NULL)
             {
 
-                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeIncrement( pVolumeCB,
+                                             AFS_VOLUME_REFERENCE_EXTENTS);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2620,7 +2627,8 @@ try_exit:
         if ( pVolumeCB)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_EXTENTS);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
index eb1b25d..0e1c572 100644 (file)
@@ -362,6 +362,7 @@ try_exit:
 NTSTATUS
 AFSInitVolume( IN GUID *AuthGroup,
                IN AFSFileID *RootFid,
+               IN LONG VolumeReferenceReason,
                OUT AFSVolumeCB **VolumeCB)
 {
 
@@ -432,12 +433,14 @@ AFSInitVolume( IN GUID *AuthGroup,
                 // So we don't lock with an invalidation call ...
                 //
 
-                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeIncrement( pVolumeCB,
+                                             VolumeReferenceReason);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSInitVolume Increment count on volume %p Cnt %d\n",
+                              "AFSInitVolume Increment count on volume %p Reason %u Cnt %d\n",
                               pVolumeCB,
+                              VolumeReferenceReason,
                               lCount);
 
                 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
@@ -539,16 +542,15 @@ AFSInitVolume( IN GUID *AuthGroup,
 
         pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
 
-        //
-        // Bias our reference by 1
-        //
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     VolumeReferenceReason);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitVolume Initializing count (2) on volume %p\n",
-                      pVolumeCB);
-
-        pVolumeCB->VolumeReferenceCount = 2;
+                      "AFSInitVolume Initializing volume %p Reason %u count %d\n",
+                      pVolumeCB,
+                      VolumeReferenceReason,
+                      lCount);
 
         AFSAcquireExcl( pVolumeCB->VolumeLock,
                         TRUE);
@@ -632,6 +634,11 @@ AFSInitVolume( IN GUID *AuthGroup,
 
         pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
 
+        //
+        // The ObjectInformation VolumeCB pointer does not obtain
+        // a reference count.
+        //
+
         pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
 
         //
@@ -752,6 +759,8 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
     __Enter
     {
 
+        ASSERT( VolumeCB->VolumeReferenceCount == 0);
+
         //
         // Remove the volume from the tree and list
         // Don't process the list information for reserved entries
@@ -898,6 +907,37 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
     return ntStatus;
 }
 
+LONG
+AFSVolumeIncrement( IN AFSVolumeCB *VolumeCB,
+                    IN LONG Reason)
+{
+
+    LONG lCount;
+
+    lCount = InterlockedIncrement( &VolumeCB->VolumeReferenceCount);
+
+    InterlockedIncrement( &VolumeCB->VolumeReferences[ Reason]);
+
+    return lCount;
+}
+
+LONG
+AFSVolumeDecrement( IN AFSVolumeCB *VolumeCB,
+                    IN LONG Reason)
+{
+
+    LONG lCount;
+
+    lCount = InterlockedDecrement( &VolumeCB->VolumeReferences[ Reason]);
+
+    ASSERT( lCount >= 0);
+
+    lCount = InterlockedDecrement( &VolumeCB->VolumeReferenceCount);
+
+    ASSERT( lCount >= 0);
+
+    return lCount;
+}
 
 //
 // Function: AFSInitRootFcb
index e653397..5b50bb3 100644 (file)
@@ -2002,7 +2002,8 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2116,7 +2117,8 @@ try_exit:
         if ( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2714,7 +2716,8 @@ AFSInvalidateAllVolumes( VOID)
                       pVolumeCB->ObjectInfoTree.TreeLock,
                       PsGetCurrentThread());
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_INVALIDATE);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -2731,7 +2734,8 @@ AFSInvalidateAllVolumes( VOID)
         if ( pNextVolumeCB)
         {
 
-            lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pNextVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2749,7 +2753,8 @@ AFSInvalidateAllVolumes( VOID)
         AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
                           TRUE);
 
-        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeDecrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_INVALIDATE);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -3313,7 +3318,8 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_INVALIDATE);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -6043,6 +6049,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
     UNICODE_STRING uniFullPathName = {0};
     AFSNameArrayHdr    *pNameArray = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
@@ -6295,12 +6302,16 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
         // Increment the ref count on the volume and dir entry for correct processing below
         //
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
+
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     VolumeReferenceReason);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRetrieveFileAttributes Increment count on volume %p Cnt %d\n",
+                      "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
                       pVolumeCB,
+                      VolumeReferenceReason,
                       lCount);
 
         lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
@@ -6320,6 +6331,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                        pNameArray,
                                        AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
                                        &pVolumeCB,
+                                       &VolumeReferenceReason,
                                        &pParentDirEntry,
                                        &pDirectoryEntry,
                                        NULL);
@@ -6339,12 +6351,14 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                 if( pVolumeCB != NULL)
                 {
 
-                    lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                    lCount = AFSVolumeDecrement( pVolumeCB,
+                                                 VolumeReferenceReason);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRetrieveFileAttributes Decrement count on volume %p Cnt %d\n",
+                                  "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
                                   pVolumeCB,
+                                  VolumeReferenceReason,
                                   lCount);
                 }
 
@@ -6455,12 +6469,14 @@ try_exit:
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSRetrieveFileAttributes Decrement2 count on volume %p Cnt %d\n",
+                          "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
                           pVolumeCB,
+                          VolumeReferenceReason,
                           lCount);
         }
 
@@ -6898,6 +6914,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
     UNICODE_STRING uniFullPathName = {0};
     AFSNameArrayHdr    *pNameArray = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
@@ -7057,12 +7074,16 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         pParentDirEntry = AFSGlobalRoot->DirectoryCB;
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
+
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     VolumeReferenceReason);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSEvaluateRootEntry Increment count on volume %p Cnt %d\n",
+                      "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
                       pVolumeCB,
+                      VolumeReferenceReason,
                       lCount);
 
         lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
@@ -7082,6 +7103,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                        pNameArray,
                                        0,
                                        &pVolumeCB,
+                                       &VolumeReferenceReason,
                                        &pParentDirEntry,
                                        &pDirectoryEntry,
                                        NULL);
@@ -7101,12 +7123,14 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                 if( pVolumeCB != NULL)
                 {
 
-                    lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                    lCount = AFSVolumeDecrement( pVolumeCB,
+                                                 VolumeReferenceReason);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSEvaluateRootEntry Decrement count on volume %p Cnt %d\n",
+                                  "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
                                   pVolumeCB,
+                                  VolumeReferenceReason,
                                   lCount);
                 }
 
@@ -7165,12 +7189,14 @@ try_exit:
         if( pVolumeCB != NULL)
         {
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSEvaluateRootEntry Decrement2 count on volume %p Cnt %d\n",
+                          "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
                           pVolumeCB,
+                          VolumeReferenceReason,
                           lCount);
         }
 
@@ -8136,6 +8162,7 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         ntStatus = AFSInitVolume( NULL,
                                   &LibraryInit->GlobalRootFid,
+                                  AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
                                   &AFSGlobalRoot);
 
         if( !NT_SUCCESS( ntStatus))
@@ -8160,11 +8187,12 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
                           "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
                           ntStatus);
 
-            lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( AFSGlobalRoot,
+                                         AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSInitializeLibrary Increment count on volume %p Cnt %d\n",
+                          "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
                           AFSGlobalRoot,
                           lCount);
 
@@ -8194,7 +8222,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
 
         AFSInitVolumeWorker( AFSGlobalRoot);
 
-        lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
+        lCount = AFSVolumeDecrement( AFSGlobalRoot,
+                                     AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -8333,6 +8362,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSVolumeCB *pVolumeCB = NULL;
+    LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
     AFSObjectInfoCB *pObjectInfo = NULL;
     ULONGLONG   ullIndex = 0;
@@ -8370,12 +8400,16 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             if( pVolumeCB != NULL)
             {
 
-                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
+
+                lCount = AFSVolumeIncrement( pVolumeCB,
+                                             VolumeReferenceReason);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSGetObjectStatus Increment count on volume %p Cnt %d\n",
+                              "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
                               pVolumeCB,
+                              VolumeReferenceReason,
                               lCount);
             }
 
@@ -8400,14 +8434,6 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                               "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
                               pObjectInfo,
                               lCount);
-
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSGetObjectStatus Decrement count on volume %p Cnt %d\n",
-                              pVolumeCB,
-                              lCount);
             }
             else
             {
@@ -8415,14 +8441,6 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                                   TRUE);
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSGetObjectStatus Decrement2 count on volume %p Cnt %d\n",
-                              pVolumeCB,
-                              lCount);
-
                 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
 
                 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
@@ -8513,12 +8531,16 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             // Increment the ref count on the volume and dir entry for correct processing below
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
+
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         VolumeReferenceReason);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSGetObjectStatus Increment2 count on volume %p Cnt %d\n",
+                          "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
                           pVolumeCB,
+                          VolumeReferenceReason,
                           lCount);
 
             lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
@@ -8539,6 +8561,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                            AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
                                                AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
                                            &pVolumeCB,
+                                           &VolumeReferenceReason,
                                            &pParentDirEntry,
                                            &pDirectoryEntry,
                                            NULL);
@@ -8558,12 +8581,14 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                     if( pVolumeCB != NULL)
                     {
 
-                        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                        lCount = AFSVolumeDecrement( pVolumeCB,
+                                                     VolumeReferenceReason);
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement3 count on volume %p Cnt %d\n",
+                                      "AFSGetObjectStatus Decrement3 count on volume %p Reason %u Cnt %d\n",
                                       pVolumeCB,
+                                      VolumeReferenceReason,
                                       lCount);
                     }
 
@@ -8630,18 +8655,6 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                           "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
                           pObjectInfo,
                           lCount);
-
-            if( pVolumeCB != NULL)
-            {
-
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSGetObjectStatus Decrement4 count on volume %p Cnt %d\n",
-                              pVolumeCB,
-                              lCount);
-            }
         }
 
         //
@@ -8699,6 +8712,20 @@ try_exit:
                           lCount);
         }
 
+        if( pVolumeCB != NULL)
+        {
+
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         VolumeReferenceReason);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
+                          pVolumeCB,
+                          VolumeReferenceReason,
+                          lCount);
+        }
+
         if( pNameArray != NULL)
         {
 
index 4642a8f..03fcfa2 100644 (file)
@@ -57,6 +57,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     IN AFSNameArrayHdr *NameArray,
                     IN ULONG Flags,
                     IN OUT AFSVolumeCB **VolumeCB,
+                    IN OUT LONG *pVolumeReferenceReason,
                     IN OUT AFSDirectoryCB **ParentDirectoryCB,
                     OUT AFSDirectoryCB **DirectoryCB,
                     OUT PUNICODE_STRING ComponentName)
@@ -77,6 +78,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
     AFSObjectInfoCB  *pParentObjectInfo = NULL;
     AFSVolumeCB      *pCurrentVolume = *VolumeCB;
     BOOLEAN           bReleaseCurrentVolume = TRUE;
+    LONG              VolumeReferenceReason = *pVolumeReferenceReason;
     BOOLEAN           bSubstitutedName = FALSE;
     LONG              lCount;
 
@@ -135,7 +137,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
         while( TRUE)
         {
 
-            ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+            ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
 
             ASSERT( pDirEntry->DirOpenReferenceCount > 0);
 
@@ -754,22 +756,28 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                           pCurrentObject->FileId.Vnode,
                                           pCurrentObject->FileId.Unique);
 
-                            lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                            lCount = AFSVolumeDecrement( pCurrentVolume,
+                                                         VolumeReferenceReason);
 
                             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSLocateNameEntry Decrement count on volume %p Cnt %d\n",
+                                          "AFSLocateNameEntry Decrement count on volume %p Reason %u Cnt %d\n",
                                           pCurrentVolume,
+                                          VolumeReferenceReason,
                                           lCount);
 
                             pCurrentVolume = AFSGlobalRoot;
 
-                            lCount = InterlockedIncrement( &pCurrentVolume->VolumeReferenceCount);
+                            VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
+
+                            lCount = AFSVolumeIncrement( pCurrentVolume,
+                                                         VolumeReferenceReason);
 
                             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                           AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSLocateNameEntry Increment count on volume %p Cnt %d\n",
+                                          "AFSLocateNameEntry Increment count on volume %p Reason %u Cnt %d\n",
                                           pCurrentVolume,
+                                          VolumeReferenceReason,
                                           lCount);
                         }
 
@@ -883,16 +891,20 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // Also decrement the ref count on the volume
                     //
 
-                    ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+                    ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
 
-                    lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                    lCount = AFSVolumeDecrement( pCurrentVolume,
+                                                 VolumeReferenceReason);
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                                   AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNameEntry Decrement2 count on volume %p Cnt %d\n",
+                                  "AFSLocateNameEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
                                   pCurrentVolume,
+                                  VolumeReferenceReason,
                                   lCount);
 
+                    bReleaseCurrentVolume = FALSE;
+
                     ntStatus = AFSBuildMountPointTarget( AuthGroup,
                                                          pDirEntry,
                                                          &pCurrentVolume);
@@ -911,16 +923,14 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                       pCurrentObject->FileId.Unique,
                                       ntStatus);
 
-                        //
-                        // We already decremented the current volume above
-                        //
-
-                        bReleaseCurrentVolume = FALSE;
-
                         try_return( ntStatus);
                     }
 
-                    ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+                    ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
+
+                    bReleaseCurrentVolume = TRUE;
+
+                    VolumeReferenceReason = AFS_VOLUME_REFERENCE_MOUNTPT;
 
                     //
                     // We want to restart processing here on the new parent ...
@@ -2036,15 +2046,19 @@ try_exit:
             if( bReleaseCurrentVolume)
             {
 
-                ASSERT( pCurrentVolume->VolumeReferenceCount > 1);
+                ASSERT( pCurrentVolume->VolumeReferenceCount > 0);
 
-                lCount = InterlockedDecrement( &pCurrentVolume->VolumeReferenceCount);
+                lCount = AFSVolumeDecrement( pCurrentVolume,
+                                             VolumeReferenceReason);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement3 count on volume %p Cnt %d\n",
+                              "AFSLocateNameEntry Decrement3 count on volume %p Reason %u Cnt %d\n",
                               pCurrentVolume,
+                              VolumeReferenceReason,
                               lCount);
+
+                bReleaseCurrentVolume = FALSE;
             }
 
             if( RootPathName->Buffer != uniFullPathName.Buffer)
@@ -2087,6 +2101,11 @@ try_exit:
 
             AFSExFreePoolWithTag( uniSearchName.Buffer, 0);
         }
+
+        if ( bReleaseCurrentVolume) {
+
+            *pVolumeReferenceReason = VolumeReferenceReason;
+        }
     }
 
     return ntStatus;
@@ -3115,7 +3134,8 @@ AFSParseName( IN PIRP Irp,
             // Increment our volume reference count
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_PARSE_NAME);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -3821,7 +3841,8 @@ AFSParseName( IN PIRP Irp,
         // Increment our reference on the volume
         //
 
-        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = AFSVolumeIncrement( pVolumeCB,
+                                     AFS_VOLUME_REFERENCE_PARSE_NAME);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -3851,7 +3872,7 @@ try_exit:
 
         if( *VolumeCB != NULL)
         {
-            ASSERT( (*VolumeCB)->VolumeReferenceCount > 1);
+            ASSERT( (*VolumeCB)->VolumeReferenceCount > 0);
         }
 
         if( ntStatus != STATUS_SUCCESS)
@@ -3985,6 +4006,10 @@ AFSCheckCellName( IN GUID *AuthGroup,
                                            &pDirEnumEntry->FileId,
                                            &pVolumeCB);
 
+            //
+            // On success returns with a volume reference count held
+            //
+
             if( !NT_SUCCESS( ntStatus))
             {
                 try_return( ntStatus);
@@ -4002,11 +4027,12 @@ AFSCheckCellName( IN GUID *AuthGroup,
                           NULL,
                           lCount);
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeDecrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_BUILD_ROOT);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSCheckCellName Increment count on volume %p Cnt %d\n",
+                          "AFSCheckCellName Decrement count on volume %p Cnt %d\n",
                           pVolumeCB,
                           lCount);
         }
@@ -4308,6 +4334,7 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
 
             ntStatus = AFSInitVolume( AuthGroup,
                                       &stTargetFileID,
+                                      AFS_VOLUME_REFERENCE_MOUNTPT,
                                       &pVolumeCB);
 
             if( !NT_SUCCESS( ntStatus))
@@ -4332,7 +4359,8 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             // obtain one to match
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_MOUNTPT);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -4365,7 +4393,8 @@ AFSBuildMountPointTarget( IN GUID *AuthGroup,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeDecrement( pVolumeCB,
+                                             AFS_VOLUME_REFERENCE_MOUNTPT);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -4486,6 +4515,7 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
 
             ntStatus = AFSInitVolume( AuthGroup,
                                       FileId,
+                                      AFS_VOLUME_REFERENCE_BUILD_ROOT,
                                       &pVolumeCB);
 
             if( !NT_SUCCESS( ntStatus))
@@ -4510,7 +4540,8 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             // obtain one to match
             //
 
-            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = AFSVolumeIncrement( pVolumeCB,
+                                         AFS_VOLUME_REFERENCE_BUILD_ROOT);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -4544,7 +4575,8 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = AFSVolumeDecrement( pVolumeCB,
+                                             AFS_VOLUME_REFERENCE_BUILD_ROOT);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
index 5596c89..7372239 100644 (file)
@@ -1873,7 +1873,7 @@ AFSPrimaryVolumeWorkerThread( IN PVOID Context)
                 if( pVolumeCB->ObjectInfoListHead == NULL &&
                     pVolumeCB->DirectoryCB->DirOpenReferenceCount <= 0 &&
                     pVolumeCB->DirectoryCB->NameArrayReferenceCount <= 0 &&
-                    pVolumeCB->VolumeReferenceCount == 1 &&
+                    pVolumeCB->VolumeReferenceCount == 0 &&
                     ( pVolumeCB->RootFcb == NULL ||
                       pVolumeCB->RootFcb->OpenReferenceCount == 0) &&
                     pVolumeCB->ObjectInformation.ObjectReferenceCount <= 0)
index 0f11fdf..fca40b8 100644 (file)
@@ -527,11 +527,20 @@ AFSInitFcb( IN AFSDirectoryCB   *DirEntry);
 NTSTATUS
 AFSInitVolume( IN GUID *AuthGroup,
                IN AFSFileID *RootFid,
+               IN LONG VolumeReferenceReason,
                OUT AFSVolumeCB **VolumeCB);
 
 NTSTATUS
 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB);
 
+LONG
+AFSVolumeIncrement( IN AFSVolumeCB *VolumeCB,
+                    IN LONG         Reason);
+
+LONG
+AFSVolumeDecrement( IN AFSVolumeCB *VolumeCB,
+                    IN LONG         Reason);
+
 NTSTATUS
 AFSInitRootFcb( IN ULONGLONG ProcessID,
                 IN AFSVolumeCB *VolumeCB);
@@ -568,6 +577,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     IN AFSNameArrayHdr *NameArray,
                     IN ULONG Flags,
                     IN OUT AFSVolumeCB **VolumeCB,
+                    IN OUT LONG *pVolumeReferenceReason,
                     IN OUT AFSDirectoryCB **ParentDirectoryCB,
                     OUT AFSDirectoryCB **DirectoryCB,
                     OUT PUNICODE_STRING ComponentName);
index 2396f4f..32eea3b 100644 (file)
@@ -169,6 +169,23 @@ NTSTATUS
 #define AFS_OBJECT_REFERENCE_MAX                        8
 
 //
+// Volume reference count reasons
+//
+
+#define AFS_VOLUME_REFERENCE_INVALID                    0
+#define AFS_VOLUME_REFERENCE_EXTENTS                    1
+#define AFS_VOLUME_REFERENCE_GLOBAL_ROOT                2
+#define AFS_VOLUME_REFERENCE_INVALIDATE                 3
+#define AFS_VOLUME_REFERENCE_FILE_ATTRS                 4
+#define AFS_VOLUME_REFERENCE_EVAL_ROOT                  5
+#define AFS_VOLUME_REFERENCE_GET_OBJECT                 6
+#define AFS_VOLUME_REFERENCE_MOUNTPT                    7
+#define AFS_VOLUME_REFERENCE_BUILD_ROOT                 8
+#define AFS_VOLUME_REFERENCE_LOCATE_NAME                9
+#define AFS_VOLUME_REFERENCE_PARSE_NAME                10
+#define AFS_VOLUME_REFERENCE_MAX                       12
+
+//
 // Define one second in terms of 100 nS units
 //
 
index 3e308ff..f881e75 100644 (file)
@@ -358,6 +358,8 @@ typedef struct _AFS_VOLUME_CB
 
     LONG                      VolumeReferenceCount;
 
+    LONG                      VolumeReferences[ AFS_VOLUME_REFERENCE_MAX];
+
     //
     // Object information tree
     //