Windows: Allocated VolumeCB from PagedPool
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFcbSupport.cpp
index 134077a..fec903f 100644 (file)
 //
 // Return:
 //
-//      A status is returned for the function
+//      Return Fcb->NPFcb->Resource held exclusive
 //
 
 NTSTATUS
-AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
-            IN OUT AFSFcb     **Fcb)
+AFSInitFcb( IN AFSDirectoryCB  *DirEntry)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSFcb *pFcb = NULL;
     AFSNonPagedFcb *pNPFcb = NULL;
-    IO_STATUS_BLOCK stIoSb = {0,0};
-    BOOLEAN bUninitFileLock = FALSE;
     USHORT  usFcbLength = 0;
-    ULONGLONG   ullIndex = 0;
-    AFSDirEnumEntry *pDirEnumCB = NULL;
     AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
 
@@ -76,6 +70,15 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
 
         pVolumeCB = pObjectInfo->VolumeCB;
 
+        if ( pObjectInfo->Fcb != NULL)
+        {
+
+            AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                            TRUE);
+
+            try_return( ntStatus = STATUS_SUCCESS);
+        }
+
         //
         // Allocate the Fcb and the nonpaged portion of the Fcb.
         //
@@ -128,6 +131,7 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
                        sizeof( AFSNonPagedFcb));
 
         pNPFcb->Size = sizeof( AFSNonPagedFcb);
+
         pNPFcb->Type = AFS_NON_PAGED_FCB;
 
         //
@@ -146,6 +150,10 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
 
         ExInitializeResourceLite( &pNPFcb->PagingResource);
 
+        ExInitializeResourceLite( &pNPFcb->SectionObjectResource);
+
+        ExInitializeResourceLite( &pNPFcb->CcbListLock);
+
         pFcb->Header.Resource = &pNPFcb->Resource;
 
         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
@@ -156,7 +164,7 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
+                      "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
                       &pNPFcb->Resource,
                       PsGetCurrentThread());
 
@@ -166,14 +174,6 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
         pFcb->NPFcb = pNPFcb;
 
         //
-        // Initialize some fields in the Fcb
-        //
-
-        pFcb->ObjectInformation = pObjectInfo;
-
-        pObjectInfo->Fcb = pFcb;
-
-        //
         // Set type specific information
         //
 
@@ -185,14 +185,6 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
             //
 
             pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
-
-            //
-            // Initialize enumeration information
-            //
-
-            KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
-                               NotificationEvent,
-                               FALSE);
         }
         else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
         {
@@ -207,8 +199,6 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
                                      NULL,
                                      NULL);
 
-            bUninitFileLock = TRUE;
-
             //
             // Initialize the header file sizes to our dir entry information
             //
@@ -274,64 +264,96 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
         }
         else
         {
-            ASSERT( FALSE);
-            try_return( ntStatus = STATUS_INVALID_PARAMETER);
+            pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
         }
 
+        pFcb->ObjectInformation = pObjectInfo;
+
+        AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+                          TRUE);
         //
-        // And return the Fcb
+        // Swap the allocated FCB into the ObjectInformation structure if it
+        // does not already have one.
         //
 
-        *Fcb = pFcb;
+        if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_WARNING,
+                          "AFSInitFcb Raced Fcb %p pFcb %p Name %wZ\n",
+                          pObjectInfo->Fcb,
+                          pFcb,
+                          &DirEntry->NameInformation.FileName);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
+                          &pObjectInfo->Fcb->NPFcb->Resource,
+                          PsGetCurrentThread());
+
+            AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+            AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                            TRUE);
+
+            try_return( ntStatus = STATUS_REPARSE);
+        }
+
+        AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
-                      pFcb,
+                      "AFSInitFcb Initialized Fcb %p Name %wZ\n",
+                      &pObjectInfo->Fcb,
                       &DirEntry->NameInformation.FileName);
 
 try_exit:
 
-        if( !NT_SUCCESS( ntStatus))
+        if( ntStatus != STATUS_SUCCESS)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSInitFcb Failed to initialize fcb Status %08lX\n",
-                          ntStatus);
-
-            if( pFcb != NULL)
+            if ( !NT_SUCCESS( ntStatus))
             {
 
-                if( bUninitFileLock)
-                {
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSInitFcb Failed to initialize fcb Status %08lX\n",
+                              ntStatus);
+            }
 
-                    FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
-                }
+            if( pFcb != NULL)
+            {
 
                 if( pNPFcb != NULL)
                 {
 
                     AFSReleaseResource( &pNPFcb->Resource);
 
-                    ExDeleteResourceLite( &pNPFcb->PagingResource);
+                    FsRtlTeardownPerStreamContexts( &pFcb->Header);
 
-                    ExDeleteResourceLite( &pNPFcb->Resource);
-                }
+                    if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
+                    {
 
-                AFSExFreePool( pFcb);
-            }
+                        FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
 
-            if( pNPFcb != NULL)
-            {
+                        ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
 
-                AFSExFreePool( pNPFcb);
-            }
+                        ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
+                    }
 
-            if( Fcb != NULL)
-            {
+                    ExDeleteResourceLite( &pNPFcb->SectionObjectResource);
 
-                *Fcb = NULL;
+                    ExDeleteResourceLite( &pNPFcb->PagingResource);
+
+                    ExDeleteResourceLite( &pNPFcb->CcbListLock);
+
+                    ExDeleteResourceLite( &pNPFcb->Resource);
+
+                    AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
+                }
+
+                AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
             }
         }
     }
@@ -346,15 +368,15 @@ AFSInitVolume( IN GUID *AuthGroup,
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    IO_STATUS_BLOCK stIoStatus = {0,0};
     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
     AFSVolumeCB *pVolumeCB = NULL;
     AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
     ULONGLONG ullIndex = 0;
     BOOLEAN bReleaseLocks = FALSE;
-    AFSVolumeInfoCB stVolumeInformation;
+    AFSVolumeInfoCB stVolumeInformation = {0};
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -412,7 +434,13 @@ AFSInitVolume( IN GUID *AuthGroup,
                 // So we don't lock with an invalidation call ...
                 //
 
-                InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSInitVolume Increment count on volume %p Cnt %d\n",
+                              pVolumeCB,
+                              lCount);
 
                 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
 
@@ -423,8 +451,6 @@ AFSInitVolume( IN GUID *AuthGroup,
                 AFSAcquireExcl( pVolumeCB->VolumeLock,
                                 TRUE);
 
-                InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
                 *VolumeCB = pVolumeCB;
 
                 try_return( ntStatus);
@@ -442,7 +468,7 @@ AFSInitVolume( IN GUID *AuthGroup,
         // into the volume tree ...
         //
 
-        pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
+        pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( PagedPool,
                                                              sizeof( AFSVolumeCB),
                                                              AFS_VCB_ALLOCATION_TAG);
 
@@ -465,7 +491,7 @@ AFSInitVolume( IN GUID *AuthGroup,
 
         pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                         sizeof( AFSNonPagedVolumeCB),
-                                                                        AFS_VCB_ALLOCATION_TAG);
+                                                                        AFS_VCB_NP_ALLOCATION_TAG);
 
         if( pNonPagedVcb == NULL)
         {
@@ -486,7 +512,7 @@ AFSInitVolume( IN GUID *AuthGroup,
 
         pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                                sizeof( AFSNonPagedObjectInfoCB),
-                                                                               AFS_VCB_ALLOCATION_TAG);
+                                                                               AFS_NP_OBJECT_INFO_TAG);
 
         if( pNonPagedObject == NULL)
         {
@@ -501,6 +527,8 @@ AFSInitVolume( IN GUID *AuthGroup,
         RtlZeroMemory( pNonPagedObject,
                        sizeof( AFSNonPagedObjectInfoCB));
 
+        ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
+
         ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
 
         pVolumeCB->NonPagedVcb = pNonPagedVcb;
@@ -519,10 +547,10 @@ AFSInitVolume( IN GUID *AuthGroup,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitVolume Initializing count (1) on volume %08lX\n",
+                      "AFSInitVolume Initializing count (2) on volume %p\n",
                       pVolumeCB);
 
-        pVolumeCB->VolumeReferenceCount = 1;
+        pVolumeCB->VolumeReferenceCount = 2;
 
         AFSAcquireExcl( pVolumeCB->VolumeLock,
                         TRUE);
@@ -616,15 +644,19 @@ AFSInitVolume( IN GUID *AuthGroup,
             {
 
                 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
+
+                SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
             }
             else
             {
 
-                AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
-                                    &pVolumeCB->TreeEntry);
-            }
+                if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
+                                                     &pVolumeCB->TreeEntry)))
+                {
 
-            SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
+                    SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
+                }
+            }
 
             if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
             {
@@ -658,15 +690,15 @@ try_exit:
 
                 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
 
-                AFSExFreePool( pNonPagedVcb);
+                AFSExFreePoolWithTag( pNonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
             }
 
             if( pNonPagedObject != NULL)
             {
 
-                ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
+                ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
 
-                AFSExFreePool( pNonPagedObject);
+                AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
             }
 
             if( pVolumeCB != NULL)
@@ -675,10 +707,10 @@ try_exit:
                 if( pVolumeCB->DirectoryCB != NULL)
                 {
 
-                    AFSExFreePool( pVolumeCB->DirectoryCB);
+                    AFSExFreePoolWithTag( pVolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
                 }
 
-                AFSExFreePool( pVolumeCB);
+                AFSExFreePoolWithTag( pVolumeCB, AFS_VCB_ALLOCATION_TAG);
             }
 
             if( pNonPagedDirEntry != NULL)
@@ -686,7 +718,7 @@ try_exit:
 
                 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
 
-                AFSExFreePool( pNonPagedDirEntry);
+                AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
             }
         }
 
@@ -772,12 +804,21 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
             if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
             {
 
-                AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+                AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                                TRUE);
+
+                AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+
+                AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
             }
 
             AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
 
-            AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
+            ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
+
+            AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
+
+            AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
         }
 
         if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
@@ -799,7 +840,6 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
 
             if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
             {
-
                 AFSReleaseResource( VolumeCB->VolumeLock);
             }
 
@@ -807,15 +847,17 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
 
             ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
 
-            AFSExFreePool( VolumeCB->NonPagedVcb);
+            AFSExFreePoolWithTag( VolumeCB->NonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
         }
 
         if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
         {
 
+            ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
             ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
 
-            AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
+            AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
         }
 
         if( VolumeCB->DirectoryCB != NULL)
@@ -826,13 +868,13 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
 
                 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
 
-                AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
+                AFSExFreePoolWithTag( VolumeCB->DirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
             }
 
-            AFSExFreePool( VolumeCB->DirectoryCB);
+            AFSExFreePoolWithTag( VolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
         }
 
-        AFSExFreePool( VolumeCB);
+        AFSExFreePoolWithTag( VolumeCB, AFS_VCB_ALLOCATION_TAG);
     }
 
     return ntStatus;
@@ -856,11 +898,10 @@ AFSInitRootFcb( IN ULONGLONG ProcessID,
                 IN AFSVolumeCB *VolumeCB)
 {
 
+    UNREFERENCED_PARAMETER(ProcessID);
     NTSTATUS ntStatus = STATUS_SUCCESS;
     AFSFcb *pFcb = NULL;
     AFSNonPagedFcb *pNPFcb = NULL;
-    IO_STATUS_BLOCK stIoStatus = {0,0};
-    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
 
     __Enter
     {
@@ -921,7 +962,7 @@ AFSInitRootFcb( IN ULONGLONG ProcessID,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
+                      "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
                       &pNPFcb->Resource,
                       PsGetCurrentThread());
 
@@ -930,6 +971,8 @@ AFSInitRootFcb( IN ULONGLONG ProcessID,
 
         ExInitializeResourceLite( &pNPFcb->PagingResource);
 
+        ExInitializeResourceLite( &pNPFcb->CcbListLock);
+
         pFcb->Header.Resource = &pNPFcb->Resource;
 
         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
@@ -937,14 +980,6 @@ AFSInitRootFcb( IN ULONGLONG ProcessID,
         pFcb->NPFcb = pNPFcb;
 
         //
-        // Initialize enumeration information
-        //
-
-        KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
-                           NotificationEvent,
-                           FALSE);
-
-        //
         // Save the root Fcb in the VolumeCB
         //
 
@@ -988,9 +1023,6 @@ void
 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
 {
 
-    AFSDirectoryCB *pCurrentDirEntry = NULL;
-    AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
-
     if( RootFcb->NPFcb != NULL)
     {
 
@@ -1002,18 +1034,20 @@ AFSRemoveRootFcb( IN AFSFcb *RootFcb)
 
         ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
 
+        ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
+
         //
         // The non paged region
         //
 
-        AFSExFreePool( RootFcb->NPFcb);
+        AFSExFreePoolWithTag( RootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
     }
 
     //
     // And the Fcb itself
     //
 
-    AFSExFreePool( RootFcb);
+    AFSExFreePoolWithTag( RootFcb, AFS_FCB_ALLOCATION_TAG);
 
     return;
 }
@@ -1031,33 +1065,43 @@ AFSRemoveRootFcb( IN AFSFcb *RootFcb)
 //
 
 void
-AFSRemoveFcb( IN AFSFcb *Fcb)
+AFSRemoveFcb( IN AFSFcb **ppFcb)
 {
 
+    AFSFcb * pFcb;
+
+    pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
+
+    if ( pFcb == NULL)
+    {
+
+        return;
+    }
+
     //
     // Uninitialize the file lock if it is a file
     //
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSRemoveFcb Removing Fcb %08lX\n",
-                  Fcb);
+                  "AFSRemoveFcb Removing Fcb %p\n",
+                  pFcb);
 
-    if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
+    if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
     {
 
-        FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock);
+        FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
 
         //
         // The resource we allocated
         //
 
-        ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource );
+        ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
 
-        ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock);
+        ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
 
     }
-    else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
+    else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
     {
 
 
@@ -1067,39 +1111,45 @@ AFSRemoveFcb( IN AFSFcb *Fcb)
     // Tear down the FM specific contexts
     //
 
-    FsRtlTeardownPerStreamContexts( &Fcb->Header);
+    FsRtlTeardownPerStreamContexts( &pFcb->Header);
 
     //
     // Delete the resources
     //
 
-    ExDeleteResourceLite( &Fcb->NPFcb->Resource);
+    ExDeleteResourceLite( &pFcb->NPFcb->Resource);
 
-    ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
+    ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
 
+    ExDeleteResourceLite( &pFcb->NPFcb->SectionObjectResource);
 
+    ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
 
     //
     // The non paged region
     //
 
-    AFSExFreePool( Fcb->NPFcb);
+    AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
 
     //
     // And the Fcb itself, which includes the name
     //
 
-    AFSExFreePool( Fcb);
+    AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
 
     return;
 }
 
 NTSTATUS
-AFSInitCcb( IN OUT AFSCcb **Ccb)
+AFSInitCcb( IN OUT AFSCcb **Ccb,
+            IN     AFSDirectoryCB *DirectoryCB,
+            IN     ACCESS_MASK     GrantedAccess,
+            IN     ULONG           FileAccess)
 {
 
     NTSTATUS Status = STATUS_SUCCESS;
     AFSCcb *pCcb = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -1126,8 +1176,41 @@ AFSInitCcb( IN OUT AFSCcb **Ccb)
                        sizeof( AFSCcb));
 
         pCcb->Size = sizeof( AFSCcb);
+
         pCcb->Type = AFS_CCB;
 
+        pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
+                                                     sizeof( AFSNonPagedCcb),
+                                                     AFS_CCB_NP_ALLOCATION_TAG);
+
+        if( pCcb->NPCcb == NULL)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_ERROR,
+                          "AFSInitCcb Failed to allocate NPCcb\n");
+
+            try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
+        }
+
+        ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
+
+        pCcb->DirectoryCB = DirectoryCB;
+
+        lCount = InterlockedIncrement( &pCcb->DirectoryCB->DirOpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSInitCcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                      &pCcb->DirectoryCB->NameInformation.FileName,
+                      pCcb->DirectoryCB,
+                      pCcb,
+                      lCount);
+
+        pCcb->GrantedAccess = GrantedAccess;
+
+        pCcb->FileAccess = FileAccess;
+
         //
         // Return the Ccb
         //
@@ -1142,7 +1225,13 @@ try_exit:
             if( pCcb != NULL)
             {
 
-                AFSExFreePool( pCcb);
+                if ( pCcb->NPCcb != NULL)
+                {
+
+                    AFSExFreePoolWithTag( pCcb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
+                }
+
+                AFSExFreePoolWithTag( pCcb, AFS_CCB_ALLOCATION_TAG);
             }
 
             *Ccb = NULL;
@@ -1161,25 +1250,69 @@ try_exit:
 //
 // Return:
 //
-//      A status is returned for the function
+//      None
 //
 
-NTSTATUS
-AFSRemoveCcb( IN AFSCcb *Ccb)
+void
+AFSRemoveCcb( IN AFSFcb *Fcb,
+              IN AFSCcb *Ccb)
 {
 
-    NTSTATUS ntStatus = STATUS_SUCCESS;
+    LONG lCount;
+
+    AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+                    TRUE);
+
+    if( Fcb != NULL &&
+        BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
+    {
+
+        AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
+                        TRUE);
+
+        if( Ccb->ListEntry.fLink == NULL)
+        {
+
+            Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
+
+            if( Fcb->CcbListTail != NULL)
+            {
+                Fcb->CcbListTail->ListEntry.fLink = NULL;
+            }
+        }
+        else
+        {
+            ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
+        }
+
+        if( Ccb->ListEntry.bLink == NULL)
+        {
+
+            Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
+
+            if( Fcb->CcbListHead != NULL)
+            {
+                Fcb->CcbListHead->ListEntry.bLink = NULL;
+            }
+        }
+        else
+        {
+            ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
+        }
+
+        AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
+    }
 
     if( Ccb->MaskName.Buffer != NULL)
     {
 
-        AFSExFreePool( Ccb->MaskName.Buffer);
+        AFSExFreePoolWithTag( Ccb->MaskName.Buffer, AFS_GENERIC_MEMORY_6_TAG);
     }
 
     if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
     {
 
-        AFSExFreePool( Ccb->FullFileName.Buffer);
+        AFSExFreePoolWithTag( Ccb->FullFileName.Buffer, 0);
     }
 
     //
@@ -1197,7 +1330,7 @@ AFSRemoveCcb( IN AFSCcb *Ccb)
     if( Ccb->DirectorySnapshot != NULL)
     {
 
-        AFSExFreePool( Ccb->DirectorySnapshot);
+        AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
 
         Ccb->DirectorySnapshot = NULL;
     }
@@ -1205,14 +1338,69 @@ AFSRemoveCcb( IN AFSCcb *Ccb)
     if( Ccb->NotifyMask.Buffer != NULL)
     {
 
-        AFSExFreePool( Ccb->NotifyMask.Buffer);
+        AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
+    }
+
+    if ( Ccb->DirectoryCB != NULL)
+    {
+
+        lCount = InterlockedDecrement( &Ccb->DirectoryCB->DirOpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRemoveCcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                      &Ccb->DirectoryCB->NameInformation.FileName,
+                      Ccb->DirectoryCB,
+                      Ccb,
+                      lCount);
+
+        ASSERT( lCount >= 0);
     }
 
+    AFSReleaseResource( &Ccb->NPCcb->CcbLock);
+
     //
     // Free up the Ccb
     //
 
-    AFSExFreePool( Ccb);
+    ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
+
+    AFSExFreePoolWithTag( Ccb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
+
+    AFSExFreePoolWithTag( Ccb, AFS_CCB_ALLOCATION_TAG);
+}
+
+NTSTATUS
+AFSInsertCcb( IN AFSFcb *Fcb,
+              IN AFSCcb *Ccb)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+
+    AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
+                    TRUE);
+
+    AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
+                    TRUE);
+
+    if( Fcb->CcbListHead == NULL)
+    {
+        Fcb->CcbListHead = Ccb;
+    }
+    else
+    {
+        Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
+
+        Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
+    }
+
+    Fcb->CcbListTail = Ccb;
+
+    SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
+
+    AFSReleaseResource( &Ccb->NPCcb->CcbLock);
+
+    AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
 
     return ntStatus;
 }