Windows: AFSLocateNameEntry tracking DirectoryCB IN/OUT
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 9 Feb 2013 04:46:44 +0000 (23:46 -0500)
committerJeffrey Altman <jaltman@your-file-system.com>
Tue, 12 Feb 2013 04:16:06 +0000 (20:16 -0800)
AFSLocateNameEntry previously accepted ParentDirectoryCB as an IN/OUT
parameter in which a reference count was passed in but a reference
count was not passed back out.  The DirectoryCB parameter is an OUT
parameter for which a reference count should be returned on success.

This patchset simplifies the logic.  ParentDirectoryCB is IN only
and OutParentDirectoryCB and DirectoryCB are out only.  AFSLocateNameEntry
never releases a reference count provided by the caller and it always
returns OutParentDirectoryCB and DirectoryCB with a new reference count
unless they are NULL.  It is the callers responsibility to determine if
ParentDirectoryCB has changed and to release all of the references.

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

index b7d9e2b..299247d 100644 (file)
@@ -147,6 +147,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
     AFSVolumeCB        *pNewVolumeCB = NULL;
     LONG                NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB     *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
+    AFSDirectoryCB     *pNewParentDirectoryCB = NULL;
     BOOLEAN             bReleaseParentDir = FALSE, bReleaseDir = FALSE;
     ULONG               ulParseFlags = 0;
     GUID                stAuthGroup = {0};
@@ -449,7 +450,7 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                            pParentDirectoryCB,
                                            &pNewVolumeCB,
                                            &NewVolumeReferenceReason,
-                                           &pParentDirectoryCB,
+                                           &pNewParentDirectoryCB,
                                            &pDirectoryCB,
                                            &uniComponentName);
 
@@ -481,6 +482,38 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
 
             bReleaseVolume = (pVolumeCB != NULL);
 
+            //
+            // AFSLocateNameEntry does not alter the reference count of
+            // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+            // a reference held.
+            //
+
+            if ( bReleaseParentDir)
+            {
+
+                lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &pParentDirectoryCB->NameInformation.FileName,
+                              pParentDirectoryCB,
+                              pCcb,
+                              lCount);
+            }
+
+            pParentDirectoryCB = pNewParentDirectoryCB;
+
+            pNewParentDirectoryCB = NULL;
+
+            bReleaseParentDir = (pParentDirectoryCB != NULL);
+
+            if ( pDirectoryCB)
+            {
+
+                bReleaseDir = TRUE;
+            }
+
             if( !NT_SUCCESS( ntStatus) &&
                 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
             {
@@ -502,8 +535,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                               &uniFileName,
                               ntStatus);
 
-                bReleaseParentDir = FALSE;
-
                 try_return( ntStatus);
             }
 
@@ -522,8 +553,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
 
                 Irp->IoStatus.Information = IO_REPARSE;
 
-                bReleaseParentDir = FALSE;
-
                 try_return( ntStatus);
             }
 
@@ -580,23 +609,6 @@ 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;
-                }
-            }
         }
 
         //
index 0d2c4cf..78600a6 100644 (file)
@@ -6053,6 +6053,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
     AFSVolumeCB *pNewVolumeCB = NULL;
     LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    AFSDirectoryCB *pNewParentDirEntry = NULL;
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
@@ -6336,7 +6337,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                        pParentDirEntry,
                                        &pNewVolumeCB,
                                        &NewVolumeReferenceReason,
-                                       &pParentDirEntry,
+                                       &pNewParentDirEntry,
                                        &pDirectoryEntry,
                                        NULL);
 
@@ -6366,44 +6367,28 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
         NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
 
-        if( !NT_SUCCESS( ntStatus) ||
-            ntStatus == STATUS_REPARSE)
-        {
-
-            if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
-            {
-
-                if( pDirectoryEntry != NULL)
-                {
-
-                    lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+        //
+        // AFSLocateNameEntry does not alter the reference count of
+        // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+        // a reference held.
+        //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirectoryEntry->NameInformation.FileName,
-                                  pDirectoryEntry,
-                                  NULL,
-                                  lCount);
+        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
-                    ASSERT( lCount >= 0);
-                }
-                else
-                {
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
+                      &pParentDirEntry->NameInformation.FileName,
+                      pParentDirEntry,
+                      lCount);
 
-                    lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+        pParentDirEntry = pNewParentDirEntry;
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pParentDirEntry->NameInformation.FileName,
-                                  pParentDirEntry,
-                                  NULL,
-                                  lCount);
+        pNewParentDirEntry = NULL;
 
-                    ASSERT( lCount >= 0);
-                }
-            }
+        if( !NT_SUCCESS( ntStatus) ||
+            ntStatus == STATUS_REPARSE)
+        {
 
             try_return( ntStatus);
         }
@@ -6451,28 +6436,44 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
         FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
 
-        //
-        // Remove the reference made above
-        //
+try_exit:
 
-        lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+        if( pDirEntry != NULL)
+        {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
-                      &pDirectoryEntry->NameInformation.FileName,
-                      pDirectoryEntry,
-                      NULL,
-                      lCount);
+            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
+        }
 
-        ASSERT( lCount >= 0);
+        if( pDirectoryEntry != NULL)
+        {
 
-try_exit:
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
 
-        if( pDirEntry != NULL)
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( pParentDirEntry != NULL)
         {
 
-            AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
         }
 
         if( pVolumeCB != NULL)
@@ -6927,6 +6928,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
     AFSVolumeCB *pNewVolumeCB = NULL;
     LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    AFSDirectoryCB *pNewParentDirEntry = NULL;
     WCHAR *pwchBuffer = NULL;
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
@@ -7117,7 +7119,7 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                        pParentDirEntry,
                                        &pNewVolumeCB,
                                        &VolumeReferenceReason,
-                                       &pParentDirEntry,
+                                       &pNewParentDirEntry,
                                        &pDirectoryEntry,
                                        NULL);
 
@@ -7147,44 +7149,28 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
 
-        if( !NT_SUCCESS( ntStatus) ||
-            ntStatus == STATUS_REPARSE)
-        {
-
-            if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
-            {
-
-                if( pDirectoryEntry != NULL)
-                {
-
-                    lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+        //
+        // AFSLocateNameEntry does not alter the reference count of
+        // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+        // a reference held.
+        //
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pDirectoryEntry->NameInformation.FileName,
-                                  pDirectoryEntry,
-                                  NULL,
-                                  lCount);
+        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
-                    ASSERT( lCount >= 0);
-                }
-                else
-                {
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
+                      &pParentDirEntry->NameInformation.FileName,
+                      pParentDirEntry,
+                      lCount);
 
-                    lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+        pParentDirEntry = pNewParentDirEntry;
 
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                  &pParentDirEntry->NameInformation.FileName,
-                                  pParentDirEntry,
-                                  NULL,
-                                  lCount);
+        pNewParentDirEntry = NULL;
 
-                    ASSERT( lCount >= 0);
-                }
-            }
+        if( !NT_SUCCESS( ntStatus) ||
+            ntStatus == STATUS_REPARSE)
+        {
 
             pVolumeCB = NULL;
 
@@ -7198,8 +7184,42 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
 
         *TargetDirEntry = pDirectoryEntry;
 
+        pDirectoryEntry = NULL;
+
 try_exit:
 
+        if( pDirectoryEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( pParentDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         if( pDirEntry != NULL)
         {
 
@@ -8391,6 +8411,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
     UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
     AFSNameArrayHdr *pNameArray = NULL;
     AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
+    AFSDirectoryCB *pNewParentDirEntry = NULL;
     LONG lCount;
 
     __Enter
@@ -8586,7 +8607,7 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                            pParentDirEntry,
                                            &pNewVolumeCB,
                                            &NewVolumeReferenceReason,
-                                           &pParentDirEntry,
+                                           &pNewParentDirEntry,
                                            &pDirectoryEntry,
                                            NULL);
 
@@ -8616,71 +8637,34 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
             NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
 
-            if( !NT_SUCCESS( ntStatus) ||
-                ntStatus == STATUS_REPARSE)
-            {
-
-                //
-                // The volume lock was released on failure or reparse above
-                // Except for STATUS_OBJECT_NAME_NOT_FOUND
-                //
-
-                if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
-                {
-
-                    if( pDirectoryEntry != NULL)
-                    {
-
-                        lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+            //
+            // AFSLocateNameEntry does not alter the reference count of
+            // pParentDirectoryCB and it returns pNewParentDirectoryCB with
+            // a reference held.
+            //
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                      &pDirectoryEntry->NameInformation.FileName,
-                                      pDirectoryEntry,
-                                      NULL,
-                                      lCount);
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
 
-                        ASSERT( lCount >= 0);
-                    }
-                    else
-                    {
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          lCount);
 
-                        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+            pParentDirEntry = pNewParentDirEntry;
 
-                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                                      AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
-                                      &pParentDirEntry->NameInformation.FileName,
-                                      pParentDirEntry,
-                                      NULL,
-                                      lCount);
+            pNewParentDirEntry = NULL;
 
-                        ASSERT( lCount >= 0);
-                    }
-                }
+            if( !NT_SUCCESS( ntStatus) ||
+                ntStatus == STATUS_REPARSE)
+            {
 
                 pVolumeCB = NULL;
 
                 try_return( ntStatus);
             }
 
-            //
-            // Remove the reference obtained from AFSLocateNameEntry
-            //
-
-            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSGetObjectStatus Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
-                          &pDirectoryEntry->NameInformation.FileName,
-                          pDirectoryEntry,
-                          NULL,
-                          lCount);
-
-            ASSERT( lCount >= 0);
-
             pObjectInfo = pDirectoryEntry->ObjectInformation;
 
             lCount = AFSObjectInfoIncrement( pObjectInfo,
@@ -8735,6 +8719,38 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
 
 try_exit:
 
+        if( pDirectoryEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirectoryEntry->NameInformation.FileName,
+                          pDirectoryEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
+        if ( pParentDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         if( pObjectInfo != NULL)
         {
 
index 60ceb75..f00257f 100644 (file)
 // will be assigned the new current volume with a held ReferenceCount.
 //
 // On entry, *ParentDirectoryCB must have a held DirOpenReferenceCount
-// provided by the caller.
+// provided by the caller.  This reference will not be released.
+// On exit, if OutParentDirectoryCB is set, it will have a new reference.
+//
+// On exit, if OutDirectoryCB is set, it will have a reference.
 //
 
 NTSTATUS
@@ -69,7 +72,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
     UNICODE_STRING    uniPathName, uniComponentName, uniRemainingPath, uniSearchName, uniFullPathName;
     ULONG             ulCRC = 0;
     AFSDirectoryCB   *pDirEntry = NULL, *pParentDirEntry = NULL;
-    AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+    AFSDeviceExt     *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
     UNICODE_STRING    uniSysName;
     ULONG             ulSubstituteIndex = 0;
     BOOLEAN           bSubstituteName = FALSE;
@@ -126,6 +129,20 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
         pDirEntry = ParentDirectoryCB;
 
+        //
+        // Increment our reference on this dir entry
+        //
+
+        lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                      &pDirEntry->NameInformation.FileName,
+                      pDirEntry,
+                      NULL,
+                      lCount);
+
         pCurrentVolume = VolumeCB;
 
         VolumeReferenceReason = AFS_VOLUME_REFERENCE_LOCATE_NAME;
@@ -372,8 +389,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         *OutParentDirectoryCB = pParentDirEntry;
 
+                        pParentDirEntry = NULL;
+
                         *OutDirectoryCB = pDirEntry;
 
+                        pDirEntry = NULL;
+
                         *OutVolumeCB = pCurrentVolume;
 
                         *OutVolumeReferenceReason = VolumeReferenceReason;
@@ -628,23 +649,44 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                       AFS_TRACE_LEVEL_VERBOSE,
-                                      "AFSLocateNameEntry Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
+                                      "AFSLocateNameEntry Increment2 count on %wZ DE %p Ccb %p Cnt %d\n",
                                       &pDirEntry->NameInformation.FileName,
                                       pDirEntry,
                                       NULL,
                                       lCount);
 
-                        if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
+                        if ( pParentDirEntry)
                         {
 
+                            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                          &pParentDirEntry->NameInformation.FileName,
+                                          pParentDirEntry,
+                                          NULL,
+                                          lCount);
+
                             pParentDirEntry = NULL;
                         }
-                        else
+
+                        if( !BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
                         {
 
                             pParentDirEntry = AFSGetParentEntry( pNameArray);
 
                             ASSERT( pParentDirEntry != pDirEntry);
+
+                            lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                                          &pParentDirEntry->NameInformation.FileName,
+                                          pParentDirEntry,
+                                          NULL,
+                                          lCount);
                         }
                     }
                     else
@@ -860,7 +902,21 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         pNameArray->LinkCount = lLinkCount;
 
-                        pParentDirEntry = NULL;
+                        if ( pParentDirEntry)
+                        {
+
+                            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                          AFS_TRACE_LEVEL_VERBOSE,
+                                          "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                          &pParentDirEntry->NameInformation.FileName,
+                                          pParentDirEntry,
+                                          NULL,
+                                          lCount);
+
+                            pParentDirEntry = NULL;
+                        }
                     }
 
                     //
@@ -890,8 +946,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         *OutParentDirectoryCB = pParentDirEntry;
 
+                        pParentDirEntry = NULL;
+
                         *OutDirectoryCB = pDirEntry;
 
+                        pDirEntry = NULL;
+
                         *OutVolumeCB = pCurrentVolume;
 
                         *OutVolumeReferenceReason = VolumeReferenceReason;
@@ -998,7 +1058,21 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     AFSInsertNextElement( pNameArray,
                                           pDirEntry);
 
-                    pParentDirEntry = NULL;
+                    if ( pParentDirEntry)
+                    {
+
+                        lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                      &pParentDirEntry->NameInformation.FileName,
+                                      pParentDirEntry,
+                                      NULL,
+                                      lCount);
+
+                        pParentDirEntry = NULL;
+                    }
 
                     //
                     // Increment our link count
@@ -1021,8 +1095,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                         *OutParentDirectoryCB = pParentDirEntry;
 
+                        pParentDirEntry = NULL;
+
                         *OutDirectoryCB = pDirEntry;
 
+                        pDirEntry = NULL;
+
                         *OutVolumeCB = pCurrentVolume;
 
                         *OutVolumeReferenceReason = VolumeReferenceReason;
@@ -1186,8 +1264,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                     *OutParentDirectoryCB = pParentDirEntry;
 
+                    pParentDirEntry = NULL;
+
                     *OutDirectoryCB = pDirEntry;
 
+                    pDirEntry = NULL;
+
                     *OutVolumeCB = pCurrentVolume;
 
                     *OutVolumeReferenceReason = VolumeReferenceReason;
@@ -1223,8 +1305,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                 *OutParentDirectoryCB = pParentDirEntry;
 
+                pParentDirEntry = NULL;
+
                 *OutDirectoryCB = pDirEntry;
 
+                pDirEntry = NULL;
+
                 *OutVolumeCB = pCurrentVolume;
 
                 *OutVolumeReferenceReason = VolumeReferenceReason;
@@ -1329,17 +1415,42 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                               NULL,
                               lCount);
 
-                if( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
+                if ( pParentDirEntry)
                 {
 
+                    lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                                  &pParentDirEntry->NameInformation.FileName,
+                                  pParentDirEntry,
+                                  NULL,
+                                  lCount);
+
                     pParentDirEntry = NULL;
                 }
-                else
+
+                if( !BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_ROOT_VOLUME))
                 {
 
                     pParentDirEntry = AFSGetParentEntry( pNameArray);
 
                     ASSERT( pParentDirEntry != pDirEntry);
+
+                    if ( pParentDirEntry)
+                    {
+
+                        lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                                      AFS_TRACE_LEVEL_VERBOSE,
+                                      "AFSLocateNameEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                                      &pParentDirEntry->NameInformation.FileName,
+                                      pParentDirEntry,
+                                      NULL,
+                                      lCount);
+                    }
                 }
 
                 uniPathName = uniRemainingPath;
@@ -1351,6 +1462,20 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             // Update our pointers
             //
 
+            if ( pParentDirEntry)
+            {
+
+                lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSLocateNameEntry Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &pParentDirEntry->NameInformation.FileName,
+                              pParentDirEntry,
+                              NULL,
+                              lCount);
+            }
+
             pParentDirEntry = pDirEntry;
 
             pDirEntry = NULL;
@@ -1424,6 +1549,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                             *OutParentDirectoryCB = pParentDirEntry;
 
+                            pParentDirEntry = NULL;
+
                             *OutDirectoryCB = NULL;
 
                             *OutVolumeCB = pCurrentVolume;
@@ -1554,6 +1681,12 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                 continue;       // while( pDirEntry == NULL)
                             }
 
+                            //
+                            // Node name not found so get out
+                            //
+
+                            AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
                             if( uniRemainingPath.Length > 0)
                             {
 
@@ -1590,6 +1723,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                                 *OutParentDirectoryCB = pParentDirEntry;
 
+                                pParentDirEntry = NULL;
+
                                 *OutDirectoryCB = NULL;
 
                                 *OutVolumeCB = pCurrentVolume;
@@ -1607,13 +1742,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                 *RootPathName = uniFullPathName;
                             }
 
-                            AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
-
-                            //
-                            // Node name not found so get out
-                            //
-
-                            try_return( ntStatus);  // while( pDirEntry == NULL)
+                            try_return( ntStatus);
                         }
                     }
                     else
@@ -1786,7 +1915,7 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                 ASSERT( lCount >= 0);
 
-                if( lCount <= 0)
+                if( lCount == 0)
                 {
 
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING|AFS_SUBSYSTEM_CLEANUP_PROCESSING,
@@ -1888,6 +2017,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
 
                     *OutParentDirectoryCB = pParentDirEntry;
 
+                    pParentDirEntry = NULL;
+
                     *OutDirectoryCB = NULL;
 
                     *OutVolumeCB = pCurrentVolume;
@@ -1913,22 +2044,6 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
             }
 
             //
-            // Decrement the previous parent
-            //
-
-            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSLocateNameEntry Decrement5 count on Parent %wZ DE %p Ccb %p Cnt %d\n",
-                          &pParentDirEntry->NameInformation.FileName,
-                          pParentDirEntry,
-                          NULL,
-                          lCount);
-
-            ASSERT( lCount >= 0);
-
-            //
             // If we ended up substituting a name in the component then update
             // the full path and update the pointers
             //
@@ -1964,8 +2079,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                                                     &uniSearchName,
                                                     &uniRemainingPath,
                                                     bRelativeOpen ||
-                                                            bAllocatedSymLinkBuffer ||
-                                                            bSubstitutedName);
+                                                    bAllocatedSymLinkBuffer ||
+                                                    bSubstitutedName);
 
                 if( !NT_SUCCESS( ntStatus))
                 {
@@ -2064,38 +2179,6 @@ try_exit:
               ntStatus != STATUS_OBJECT_NAME_NOT_FOUND) ||
             ntStatus == STATUS_REPARSE)
         {
-
-            if( pDirEntry != NULL)
-            {
-
-                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pDirEntry->NameInformation.FileName,
-                              pDirEntry,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-            }
-            else if( pParentDirEntry != NULL)
-            {
-
-                lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
-                              &pParentDirEntry->NameInformation.FileName,
-                              pParentDirEntry,
-                              NULL,
-                              lCount);
-
-                ASSERT( lCount >= 0);
-            }
-
             if( RootPathName->Buffer != uniFullPathName.Buffer)
             {
 
@@ -2130,6 +2213,38 @@ try_exit:
             }
         }
 
+        if( pDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNameEntry Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
+        if( pParentDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNameEntry Decrement7 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pParentDirEntry->NameInformation.FileName,
+                          pParentDirEntry,
+                          NULL,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         if( bReleaseCurrentVolume)
         {