Windows: DirOpenReferenceCount reorganizing completed
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 29 Dec 2012 05:57:31 +0000 (00:57 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Thu, 31 Jan 2013 19:25:40 +0000 (11:25 -0800)
This patchset completes the reorganizing of the DirOpenReferenceCount
handling.  Now that every AFSCcb is given a refCount in AFSInitCcb()
which is released in AFSRemoveCcb() it is possible to simplify some
of the logic surrounding DirOpenReferenceCount handling across
the AFSCommonCreate -> XXX -> AFSLocateNameEntry -> {MountPoint, Symlink}
call sequences.

Wherever possible releasing of DirOpenReferenceCounts occur in a
functions try_exit block.  AFSCommonCreate() uses the new variables
bReleaseDir and bReleaseParentDir to track whether these refcounts
need to be released.  Additional comments document the decision
making.

There was at least one code path in AFSLocateNameEntry() where
the DirOpenReferenceCount could be dropped when it should not have
been. (pExistingDirNode == pDirNode).

Change-Id: I266a902ad4c44b4b8e49258c2da4acd2df1f4476
Reviewed-on: http://gerrit.openafs.org/8860
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/AFSDirControl.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp
src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp

index ba1e642..d42220d 100644 (file)
@@ -144,6 +144,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
     AFSNameArrayHdr    *pNameArray = NULL;
     AFSVolumeCB        *pVolumeCB = NULL;
     AFSDirectoryCB     *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
+    BOOLEAN             bReleaseParentDir = FALSE, bReleaseDir = FALSE;
     ULONG               ulParseFlags = 0;
     GUID                stAuthGroup = {0};
     ULONG               ulNameProcessingFlags = 0;
@@ -266,6 +267,12 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
             try_return( ntStatus);
         }
 
+        if ( pParentDirectoryCB != NULL)
+        {
+
+            bReleaseParentDir = TRUE;
+        }
+
         //
         // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
         // name
@@ -317,6 +324,11 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                              TRUE) == 0)
                 {
 
+                    //
+                    // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
+                    // AFSGlobalRoot->DirectoryCB.
+                    //
+
                     ntStatus = AFSOpenIOCtlFcb( Irp,
                                                 &stAuthGroup,
                                                 AFSGlobalRoot->DirectoryCB,
@@ -332,23 +344,26 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                       ntStatus);
                     }
                 }
-                else if( pParentDirectoryCB != NULL &&
-                         pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
+                else if( pParentDirectoryCB != NULL)
                 {
 
-                    ntStatus = AFSOpenSpecialShareFcb( Irp,
-                                                       &stAuthGroup,
-                                                       pParentDirectoryCB,
-                                                       &pFcb,
-                                                       &pCcb);
-
-                    if( !NT_SUCCESS( ntStatus))
+                    if( pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
                     {
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                                      AFS_TRACE_LEVEL_ERROR,
-                                      "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
-                                      ntStatus);
+                        ntStatus = AFSOpenSpecialShareFcb( Irp,
+                                                           &stAuthGroup,
+                                                           pParentDirectoryCB,
+                                                           &pFcb,
+                                                           &pCcb);
+
+                        if( !NT_SUCCESS( ntStatus))
+                        {
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                          AFS_TRACE_LEVEL_ERROR,
+                                          "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
+                                          ntStatus);
+                        }
                     }
                 }
 
@@ -366,18 +381,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               AFS_TRACE_LEVEL_ERROR,
                               "AFSCommonCreate Failed to open root Status %08lX\n",
                               ntStatus);
-
-                lCount = InterlockedDecrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement1 count on &wZ DE %p Ccb %p Cnt %d\n",
-                              &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
-                              AFSGlobalRoot->DirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
             }
 
             try_return( ntStatus);
@@ -452,7 +455,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                 }
 
                 //
-                // The routine above released the root while walking the
+                // AFSLocateNameEntry released the Parent while walking the
                 // branch
                 //
 
@@ -469,6 +472,8 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
 
                 bReleaseVolume = FALSE;
 
+                bReleaseParentDir = FALSE;
+
                 try_return( ntStatus);
             }
 
@@ -493,6 +498,8 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
 
                 bReleaseVolume = FALSE;
 
+                bReleaseParentDir = FALSE;
+
                 try_return( ntStatus);
             }
 
@@ -519,6 +526,10 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                 pParentDirectoryCB != NULL)
             {
 
+                //
+                // pParentDirectoryCB DirOpenReferenceCount is still held
+                //
+
                 UNICODE_STRING uniFinalComponent;
 
                 uniFinalComponent.Length = 0;
@@ -545,6 +556,23 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                     try_return( ntStatus);
                 }
             }
+            else
+            {
+
+                //
+                // AFSLocateNameEntry succeeded.  The parent directory reference
+                // has been released and if there is a directory returned, it is
+                // referenced.
+                //
+
+                bReleaseParentDir = FALSE;
+
+                if ( pDirectoryCB)
+                {
+
+                    bReleaseDir = TRUE;
+                }
+            }
         }
 
         //
@@ -557,6 +585,18 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
         {
 
             pDirectoryCB = pVolumeCB->DirectoryCB;
+
+            lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryCB->NameInformation.FileName,
+                          pDirectoryCB,
+                          pCcb,
+                          lCount);
+
+            bReleaseDir = TRUE;
         }
 
         if( bOpenTargetDirectory)
@@ -569,19 +609,25 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
             if( pDirectoryCB != NULL)
             {
 
-                //
-                // Perform in this order to prevent thrashing
-                //
+                if ( !bReleaseParentDir)
+                {
 
-                lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
+                    //
+                    // Perform in this order to prevent thrashing
+                    //
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pParentDirectoryCB->NameInformation.FileName,
-                              pParentDirectoryCB,
-                              NULL,
-                              lCount);
+                    lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                                  &pParentDirectoryCB->NameInformation.FileName,
+                                  pParentDirectoryCB,
+                                  pCcb,
+                                  lCount);
+
+                    bReleaseParentDir = TRUE;
+                }
 
                 //
                 // Do NOT decrement the reference count on the pDirectoryCB yet.
@@ -610,23 +656,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                                &uniComponentName,
                                                &pFcb,
                                                &pCcb);
-            if( pDirectoryCB != NULL)
-            {
-                //
-                // It is now safe to drop the Reference Count
-                //
-                lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirectoryCB->NameInformation.FileName,
-                              pDirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-            }
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -636,22 +665,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
                               &pParentDirectoryCB->NameInformation.FileName,
                               ntStatus);
-
-                //
-                // Decrement the reference on the parent
-                //
-
-                lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pParentDirectoryCB->NameInformation.FileName,
-                              pParentDirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
             }
 
             try_return( ntStatus);
@@ -711,18 +724,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                   "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
                                   &pDirectoryCB->NameInformation.FileName,
                                   ntStatus);
-
-                    lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSCommonCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirectoryCB->NameInformation.FileName,
-                                  pDirectoryCB,
-                                  NULL,
-                                  lCount);
-
-                    ASSERT( lCount >= 0);
                 }
                 else
                 {
@@ -731,18 +732,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                   AFS_TRACE_LEVEL_VERBOSE,
                                   "AFSCommonCreate Object name collision on create Status %08lX\n",
                                   ntStatus);
-
-                    lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSCommonCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pParentDirectoryCB->NameInformation.FileName,
-                                  pParentDirectoryCB,
-                                  NULL,
-                                  lCount);
-
-                    ASSERT( lCount >= 0);
                 }
 
                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
@@ -773,22 +762,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               ntStatus);
             }
 
-            //
-            // Dereference the parent entry
-            //
-
-            lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
-                          &pParentDirectoryCB->NameInformation.FileName,
-                          pParentDirectoryCB,
-                          NULL,
-                          lCount);
-
-            ASSERT( lCount >= 0);
-
             try_return( ntStatus);
         }
 
@@ -808,6 +781,11 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                          TRUE) == 0)
             {
 
+                //
+                // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
+                // pParentDirectoryCB.
+                //
+
                 ntStatus = AFSOpenIOCtlFcb( Irp,
                                             &stAuthGroup,
                                             pParentDirectoryCB,
@@ -836,45 +814,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
             }
 
-            if( !NT_SUCCESS( ntStatus))
-            {
-
-                //
-                // Dereference the parent entry
-                //
-
-                if( pDirectoryCB != NULL)
-                {
-
-                    lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSCommonCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirectoryCB->NameInformation.FileName,
-                                  pDirectoryCB,
-                                  NULL,
-                                  lCount);
-
-                    ASSERT( lCount >= 0);
-                }
-                else
-                {
-
-                    lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSCommonCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pParentDirectoryCB->NameInformation.FileName,
-                                  pParentDirectoryCB,
-                                  NULL,
-                                  lCount);
-
-                    ASSERT( lCount >= 0);
-                }
-            }
-
             try_return( ntStatus);
         }
 
@@ -897,18 +836,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
                               Irp);
 
-                lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirectoryCB->NameInformation.FileName,
-                              pDirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-
                 try_return( ntStatus = STATUS_CANNOT_DELETE);
             }
 
@@ -924,18 +851,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               "AFSCommonCreate (%p) Attempt to open root as target directory\n",
                               Irp);
 
-                lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirectoryCB->NameInformation.FileName,
-                              pDirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-
                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
             }
 
@@ -958,18 +873,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               pVolumeCB->ObjectInformation.FileId.Cell,
                               pVolumeCB->ObjectInformation.FileId.Volume,
                               ntStatus);
-
-                lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirectoryCB->NameInformation.FileName,
-                              pDirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
             }
 
             try_return( ntStatus);
@@ -1016,18 +919,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
                               &pDirectoryCB->NameInformation.FileName,
                               ntStatus);
-
-                lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCommonCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirectoryCB->NameInformation.FileName,
-                              pDirectoryCB,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
             }
 
             try_return( ntStatus);
@@ -1053,18 +944,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                           "AFSCommonCreate Failed open on %wZ Status %08lX\n",
                           &pDirectoryCB->NameInformation.FileName,
                           ntStatus);
-
-            lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSCommonCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
-                          &pDirectoryCB->NameInformation.FileName,
-                          pDirectoryCB,
-                          NULL,
-                          lCount);
-
-            ASSERT( lCount >= 0);
         }
 
 try_exit:
@@ -1288,6 +1167,46 @@ try_exit:
                           lCount);
         }
 
+        if ( bReleaseDir)
+        {
+
+            //
+            // Release the reference from AFSLocateNameEntry
+            //
+
+            lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryCB->NameInformation.FileName,
+                          pDirectoryCB,
+                          pCcb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( bReleaseParentDir)
+        {
+
+            //
+            // Release the reference from AFSLocateNameEntry
+            //
+
+            lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirectoryCB->NameInformation.FileName,
+                          pParentDirectoryCB,
+                          pCcb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         //
         // Setup the Irp for completion, the Information has been set previously
         //
@@ -3446,6 +3365,11 @@ AFSControlDeviceCreate( IN PIRP Irp)
     return ntStatus;
 }
 
+//
+// AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
+// the ParentDirCB.
+//
+
 NTSTATUS
 AFSOpenIOCtlFcb( IN PIRP Irp,
                  IN GUID *AuthGroup,
@@ -3594,20 +3518,6 @@ AFSOpenIOCtlFcb( IN PIRP Irp,
         }
 
         //
-        // Reference the directory entry
-        //
-
-        lCount = InterlockedIncrement( &((*Ccb)->DirectoryCB->DirOpenReferenceCount));
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenIOCtlFcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
-                      &(*Ccb)->DirectoryCB->NameInformation.FileName,
-                      (*Ccb)->DirectoryCB,
-                      (*Ccb),
-                      lCount);
-
-        //
         // Increment the handle on the node
         //
 
@@ -3648,23 +3558,6 @@ AFSOpenIOCtlFcb( IN PIRP Irp,
 try_exit:
 
         //
-        //Dereference the passed in parent since the returned dir entry
-        // is already referenced
-        //
-
-        lCount = InterlockedDecrement( &ParentDirCB->DirOpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenIOCtlFcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
-                      &ParentDirCB->NameInformation.FileName,
-                      ParentDirCB,
-                      NULL,
-                      lCount);
-
-        ASSERT( lCount >= 0);
-
-        //
         // If we created the Fcb we need to release the resources
         //
 
index 267dc9f..b6bb2ef 100644 (file)
@@ -609,6 +609,29 @@ AFSQueryDirectory( IN PIRP Irp)
 
             ULONG ulBytesRemainingInBuffer;
 
+            //
+            // Drop the DirOpenReferenceCount held during a prior
+            // execution of the loop
+            //
+
+            if ( pDirEntry != NULL)
+            {
+
+                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSQueryDirectory Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &pDirEntry->NameInformation.FileName,
+                              pDirEntry,
+                              pCcb,
+                              lCount);
+
+                ASSERT( lCount >= 0);
+
+                pDirEntry = NULL;
+            }
+
             ulAdditionalAttributes = 0;
 
             //
@@ -622,6 +645,10 @@ AFSQueryDirectory( IN PIRP Irp)
                 try_return( ntStatus);
             }
 
+            //
+            // On Success, pDirEntry has a held DirOpenReferenceCount
+            //
+
             pDirEntry = AFSLocateNextDirEntry( pFcb->ObjectInformation,
                                                pCcb);
 
@@ -654,18 +681,6 @@ AFSQueryDirectory( IN PIRP Irp)
                      BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
             {
 
-                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSQueryDirectory Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              pCcb,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-
                 continue;
             }
 
@@ -688,18 +703,6 @@ AFSQueryDirectory( IN PIRP Irp)
                     if( !FlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
                     {
 
-                        lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSQueryDirectory Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                      &pDirEntry->NameInformation.FileName,
-                                      pDirEntry,
-                                      pCcb,
-                                      lCount);
-
-                        ASSERT( lCount >= 0);
-
                         continue;
                     }
                 }
@@ -719,18 +722,6 @@ AFSQueryDirectory( IN PIRP Irp)
                                                       NULL))
                         {
 
-                            lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                          AFS_TRACE_LEVEL_VERBOSE,
-                                          "AFSQueryDirectory Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                          &pDirEntry->NameInformation.FileName,
-                                          pDirEntry,
-                                          pCcb,
-                                          lCount);
-
-                            ASSERT( lCount >= 0);
-
                             continue;
                         }
                     }
@@ -751,18 +742,6 @@ AFSQueryDirectory( IN PIRP Irp)
                                                          TRUE))
                             {
 
-                                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                              AFS_TRACE_LEVEL_VERBOSE,
-                                              "AFSQueryDirectory Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                              &pDirEntry->NameInformation.FileName,
-                                              pDirEntry,
-                                              pCcb,
-                                              lCount);
-
-                                ASSERT( lCount >= 0);
-
                                 continue;
                             }
                         }
@@ -823,18 +802,6 @@ AFSQueryDirectory( IN PIRP Irp)
 
                 pCcb->CurrentDirIndex--;
 
-                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSQueryDirectory Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              pCcb,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-
                 try_return( ntStatus = STATUS_SUCCESS);
             }
 
@@ -1001,6 +968,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
                     break;
                 }
+
                 default:
                 {
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -1009,21 +977,7 @@ AFSQueryDirectory( IN PIRP Irp)
                                   Irp,
                                   FileInformationClass);
 
-                    lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSQueryDirectory Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirEntry->NameInformation.FileName,
-                                  pDirEntry,
-                                  pCcb,
-                                  lCount);
-
-                    ASSERT( lCount >= 0);
-
                     try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
-
-                    break;
                 }
             }
 
@@ -1047,20 +1001,20 @@ AFSQueryDirectory( IN PIRP Irp)
             if( ulBytesConverted < pDirEntry->NameInformation.FileName.Length)
             {
 
-                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+                try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
+            }
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSQueryDirectory Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              pCcb,
-                              lCount);
+            dStatus = STATUS_SUCCESS;
 
-                ASSERT( lCount >= 0);
+            //  Set ourselves up for the next iteration
+            ulLastEntry = ulNextEntry;
+            ulNextEntry += (ULONG)QuadAlign( ulBaseLength + ulBytesConverted);
+        }
 
-                try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
-            }
+try_exit:
+
+        if ( pDirEntry != NULL)
+        {
 
             lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
 
@@ -1073,16 +1027,8 @@ AFSQueryDirectory( IN PIRP Irp)
                           lCount);
 
             ASSERT( lCount >= 0);
-
-            dStatus = STATUS_SUCCESS;
-
-            //  Set ourselves up for the next iteration
-            ulLastEntry = ulNextEntry;
-            ulNextEntry += (ULONG)QuadAlign( ulBaseLength + ulBytesConverted);
         }
 
-try_exit:
-
         if( bReleaseMain)
         {
 
@@ -1241,22 +1187,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
                 pDirEntry = ObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
 
-                if( pDirEntry != NULL)
-                {
-
-                    lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
-
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSLocateNextDirEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirEntry->NameInformation.FileName,
-                                  pDirEntry,
-                                  Ccb,
-                                  lCount);
-
-                    ASSERT( lCount >= 0);
-                }
-
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNextDirEntry Returning PIOctl entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
@@ -1283,22 +1213,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
             pDirEntry = AFSGlobalDotDirEntry;
 
-            if( pDirEntry != NULL)
-            {
-
-                lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNextDirEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              Ccb,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-            }
-
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSLocateNextDirEntry Returning1 snapshot entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
@@ -1317,22 +1231,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
             pDirEntry = AFSGlobalDotDotDirEntry;
 
-            if( pDirEntry != NULL)
-            {
-
-                lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNextDirEntry Increment3 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              Ccb,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-            }
-
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSLocateNextDirEntry Returning2 snapshot entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
@@ -1403,18 +1301,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
                                       ObjectInfo->FileId.Volume,
                                       ObjectInfo->FileId.Vnode,
                                       ObjectInfo->FileId.Unique);
-
-                        lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
-
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSLocateNextDirEntry Increment4 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                      &pDirEntry->NameInformation.FileName,
-                                      pDirEntry,
-                                      Ccb,
-                                      lCount);
-
-                        ASSERT( lCount >= 0);
                     }
                     else
                     {
@@ -1451,6 +1337,22 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
 try_exit:
 
+        if( pDirEntry != NULL)
+        {
+
+            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNextDirEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          Ccb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         AFSReleaseResource( &Ccb->NPCcb->CcbLock);
 
         AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
index 8c71c9c..6289b3a 100644 (file)
@@ -6950,6 +6950,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         //
         // Pass back the target dir entry for this request
+        // The caller must release the DirOpenReferenceCount
         //
 
         *TargetDirEntry = pDirectoryEntry;
@@ -8319,7 +8320,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                            &uniParsedName,
                                            pNameArray,
                                            AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
-                                                        AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
+                                               AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
                                            &pVolumeCB,
                                            &pParentDirEntry,
                                            &pDirectoryEntry,
@@ -8387,7 +8388,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
             }
 
             //
-            // Remove the reference made above
+            // Remove the reference obtained from AFSLocateNameEntry
             //
 
             lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
index 42bb751..776fa33 100644 (file)
 
 #include "AFSCommon.h"
 
+//
+// AFSLocateNameEntry
+//
+// On entry, *VolumeCB must have a held ReferenceCount provided by
+// the caller which will be released.  On successful exit, *VolumeCB
+// will be assigned the new current volume with a held ReferenceCount.
+//
+// On entry, *ParentDirectoryCB must have a held DirOpenReferenceCount
+// provided by the caller.
+//
+
 NTSTATUS
 AFSLocateNameEntry( IN GUID *AuthGroup,
                     IN PFILE_OBJECT FileObject,
@@ -2127,6 +2138,11 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
             try_return( ntStatus);
         }
 
+        //
+        // If AFSNotifyFileCreate returns pDirNode != NULL, then its
+        // DirOpenReferenceCount is held.
+        //
+
         AFSAcquireExcl( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
                         TRUE);
 
@@ -2182,19 +2198,32 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                                &pExistingDirNode->ObjectInformation->FileId))
             {
 
-                AFSDeleteDirEntry( ParentObjectInfo,
-                                   pDirNode);
+                if ( pExistingDirNode != pDirNode)
+                {
 
-                lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
+                    lCount = InterlockedDecrement( &pDirNode->DirOpenReferenceCount);
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
-                              &pExistingDirNode->NameInformation.FileName,
-                              pExistingDirNode,
-                              lCount);
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCreateDirEntry Decrement count on %wZ DE %p Cnt %d\n",
+                                  &pDirNode->NameInformation.FileName,
+                                  pDirNode,
+                                  lCount);
+
+                    AFSDeleteDirEntry( ParentObjectInfo,
+                                       pDirNode);
+
+                    lCount = InterlockedIncrement( &pExistingDirNode->DirOpenReferenceCount);
 
-                *DirEntry = pExistingDirNode;
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSCreateDirEntry Increment count on %wZ DE %p Cnt %d\n",
+                                  &pExistingDirNode->NameInformation.FileName,
+                                  pExistingDirNode,
+                                  lCount);
+
+                    *DirEntry = pExistingDirNode;
+                }
 
                 AFSReleaseResource( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -2249,7 +2278,6 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                     AFSRemoveNameEntry( ParentObjectInfo,
                                         pExistingDirNode);
                 }
-
             }
         }
 
@@ -2271,15 +2299,6 @@ AFSCreateDirEntry( IN GUID            *AuthGroup,
                                 pDirNode,
                                 TRUE);
 
-        lCount = InterlockedIncrement( &pDirNode->DirOpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSCreateDirEntry Increment2 count on %wZ DE %p Cnt %d\n",
-                      &pDirNode->NameInformation.FileName,
-                      pDirNode,
-                      lCount);
-
         //
         // Pass back the dir entry
         //
@@ -2766,6 +2785,8 @@ AFSParseName( IN PIRP Irp,
 
         *ParseFlags = AFS_PARSE_FLAG_ROOT_ACCESS;
 
+        *ParentDirectoryCB = NULL;
+
         if( pIrpSp->FileObject->RelatedFileObject != NULL)
         {
 
@@ -2969,7 +2990,7 @@ AFSParseName( IN PIRP Irp,
 
                 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
                                pIrpSp->FileObject->FileName.Buffer,
-                               pIr\epSp->FileObject->FileName.Length);
+                               pIrpSp->FileObject->FileName.Length);
 
                 uniFullName.Length += pIrpSp->FileObject->FileName.Length;
             }
@@ -3061,8 +3082,6 @@ AFSParseName( IN PIRP Irp,
 
             *NameArray = pNameArray;
 
-            *VolumeCB = pVolumeCB;
-
             //
             // Increment our volume reference count
             //
@@ -3075,17 +3094,9 @@ AFSParseName( IN PIRP Irp,
                           pVolumeCB,
                           lCount);
 
-            *ParentDirectoryCB = pDirEntry;
-
-            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+            *VolumeCB = pVolumeCB;
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                          &pDirEntry->NameInformation.FileName,
-                          pDirEntry,
-                          NULL,
-                          lCount);
+            *ParentDirectoryCB = pDirEntry;
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
@@ -3314,7 +3325,7 @@ AFSParseName( IN PIRP Irp,
         }
 
         //
-        // Check for the \\Server access and return it as though it where \\Server\Globalroot
+        // Check for the \\Server access and return it as though it were \\Server\Globalroot
         //
 
         if( uniRemainingPath.Buffer == NULL ||
@@ -3508,19 +3519,9 @@ AFSParseName( IN PIRP Irp,
 
             *FileName = uniComponentName;
 
-            *ParentDirectoryCB = pDirEntry;
-
             ClearFlag( *ParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS);
 
-            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSParseName Increment5 count on %wZ DE %p Ccb %p Cnt %d\n",
-                          &pDirEntry->NameInformation.FileName,
-                          pDirEntry,
-                          NULL,
-                          lCount);
+            *ParentDirectoryCB = pDirEntry;
 
             try_return( ntStatus = STATUS_SUCCESS);
         }
@@ -3694,8 +3695,6 @@ AFSParseName( IN PIRP Irp,
                 //
                 // This is a root open so pass back no parent
                 //
-
-                *ParentDirectoryCB = NULL;
             }
         }
         else
@@ -3763,22 +3762,11 @@ AFSParseName( IN PIRP Irp,
             uniRemainingPath.Length += sizeof( WCHAR);
             uniRemainingPath.MaximumLength += sizeof( WCHAR);
 
-            lCount = InterlockedIncrement( &pVolumeCB->DirectoryCB->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSParseName Increment6 count on %wZ DE %p Ccb %p Cnt %d\n",
-                          &pVolumeCB->DirectoryCB->NameInformation.FileName,
-                          pVolumeCB->DirectoryCB,
-                          NULL,
-                          lCount);
-
             //
             // Pass back the parent being the volume root
             //
 
             *ParentDirectoryCB = pVolumeCB->DirectoryCB;
-
         }
 
         //
@@ -3813,13 +3801,15 @@ try_exit:
             if( *ParentDirectoryCB != NULL)
             {
 
+                lCount = InterlockedIncrement( &(*ParentDirectoryCB)->DirOpenReferenceCount);
+
                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSParseName Count on %wZ DE %p Ccb %p Cnt %d\n",
+                              "AFSParseName Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
                               &(*ParentDirectoryCB)->NameInformation.FileName,
-                              *ParentDirectoryCB,
+                              (*ParentDirectoryCB),
                               NULL,
-                              (*ParentDirectoryCB)->DirOpenReferenceCount);
+                              lCount);
             }
         }
 
index 800b111..5918a2c 100644 (file)
@@ -1309,6 +1309,7 @@ AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
 
         //
         // Setup the request to evaluate the entry
+        // On success, pTargetDirEntry has the DirOpenReferenceCount held
         //
 
         ntStatus = AFSEvaluateRootEntry( pShareDirEntry,
@@ -1391,6 +1392,10 @@ AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB,
             pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
         }
 
+        //
+        // Release the DirOpenReferenceCount obtained from AFSEvaluateRootEntry
+        //
+
         lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,