Windows: Add CCB NonPaged Resource for synchronization
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSCreate.cpp
index 9814049..ec41544 100644 (file)
@@ -99,7 +99,7 @@ try_exit:
 
         NOTHING;
     }
-    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
         AFSDbgLogMsg( 0,
@@ -107,6 +107,8 @@ try_exit:
                       "EXCEPTION - AFSCreate\n");
 
         ntStatus = STATUS_ACCESS_DENIED;
+
+        AFSDumpTraceFilesFnc();
     }
 
     //
@@ -187,6 +189,21 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                  (ULONGLONG)PsGetCurrentThreadId(),
                                   &stAuthGroup);
 
+        //
+        // If we are in shutdown mode then fail the request
+        //
+
+        if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_WARNING,
+                          "AFSCommonCreate (%08lX) Open request after shutdown\n",
+                          Irp);
+
+            try_return( ntStatus = STATUS_TOO_LATE);
+        }
+
         if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
         {
 
@@ -205,21 +222,6 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
         }
 
         //
-        // If we are in shutdown mode then fail the request
-        //
-
-        if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
-        {
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_WARNING,
-                          "AFSCommonCreate (%08lX) Open request after shutdown\n",
-                          Irp);
-
-            try_return( ntStatus = STATUS_TOO_LATE);
-        }
-
-        //
         // Go and parse the name for processing.
         // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
         // then we are responsible for releasing the uniRootFileName.Buffer.
@@ -1048,6 +1050,9 @@ try_exit:
             if( pCcb != NULL)
             {
 
+                AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
+                                TRUE);
+
                 RtlCopyMemory( &pCcb->AuthGroup,
                                &stAuthGroup,
                                sizeof( GUID));
@@ -1109,6 +1114,8 @@ try_exit:
                 pCcb->NameArray = pNameArray;
 
                 pNameArray = NULL;
+
+                AFSReleaseResource( &pCcb->NPCcb->CcbLock);
             }
 
             //
@@ -1138,9 +1145,15 @@ try_exit:
                 // For files perform additional processing
                 //
 
-                if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
+                switch( pFcb->Header.NodeTypeCode)
                 {
-                    pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
+
+                    case AFS_FILE_FCB:
+                    case AFS_IOCTL_FCB:
+                    {
+
+                        pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
+                    }
                 }
 
                 //
@@ -1260,79 +1273,6 @@ try_exit:
 }
 
 NTSTATUS
-AFSOpenRedirector( IN PIRP Irp,
-                   IN AFSFcb **Fcb,
-                   IN AFSCcb **Ccb)
-{
-
-    NTSTATUS ntStatus = STATUS_SUCCESS;
-    LONG lCount;
-
-    __Enter
-    {
-
-        //
-        // Initialize the Ccb for the file.
-        //
-
-        ntStatus = AFSInitCcb( Ccb);
-
-        if( !NT_SUCCESS( ntStatus))
-        {
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                          AFS_TRACE_LEVEL_ERROR,
-                          "AFSOpenRedirector (%08lX) Failed to allocate Ccb\n",
-                          Irp);
-
-            try_return( ntStatus);
-        }
-
-        //
-        // Setup the Ccb
-        //
-
-        (*Ccb)->DirectoryCB = AFSRedirectorRoot->DirectoryCB;
-
-        //
-        // Increment the open count on this Fcb
-        //
-
-        lCount = InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenRedirector Increment count on Fcb %08lX Cnt %d\n",
-                      AFSRedirectorRoot->RootFcb,
-                      lCount);
-
-        lCount = InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenHandleCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenRedirector Increment handle count on Fcb %08lX Cnt %d\n",
-                      AFSRedirectorRoot->RootFcb,
-                      lCount);
-
-        *Fcb = AFSRedirectorRoot->RootFcb;
-
-        lCount = InterlockedIncrement( &(*Ccb)->DirectoryCB->OpenReferenceCount);
-
-        //
-        // Return the open result for this file
-        //
-
-        Irp->IoStatus.Information = FILE_OPENED;
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
 AFSOpenAFSRoot( IN PIRP Irp,
                 IN AFSFcb **Fcb,
                 IN AFSCcb **Ccb)
@@ -1453,7 +1393,6 @@ AFSOpenRoot( IN PIRP Irp,
 
         ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
                                      AuthGroup,
-                                     TRUE,
                                      FALSE);
 
         if( !NT_SUCCESS( ntStatus))
@@ -1854,16 +1793,82 @@ AFSProcessCreate( IN PIRP               Irp,
             if( !NT_SUCCESS( ntStatus))
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
-                              Irp,
-                              &pDirEntry->NameInformation.FileName,
-                              pObjectInfo->FileId.Cell,
-                              pObjectInfo->FileId.Volume,
-                              pObjectInfo->FileId.Vnode,
-                              pObjectInfo->FileId.Unique,
-                              ntStatus);
+                if ( ntStatus == STATUS_NOT_A_DIRECTORY)
+                {
+
+                    if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
+                    {
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                      Irp,
+                                      &pDirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      pParentObjectInfo->FileId.Cell,
+                                      pParentObjectInfo->FileId.Volume,
+                                      pParentObjectInfo->FileId.Vnode,
+                                      pParentObjectInfo->FileId.Unique,
+                                      ntStatus);
+                    }
+                    else if ( pObjectInfo->ParentObjectInformation == NULL)
+                    {
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
+                                      Irp,
+                                      &pDirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      pParentObjectInfo->FileId.Cell,
+                                      pParentObjectInfo->FileId.Volume,
+                                      pParentObjectInfo->FileId.Vnode,
+                                      pParentObjectInfo->FileId.Unique,
+                                      ntStatus);
+                    }
+                    else
+                    {
+
+                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                      AFS_TRACE_LEVEL_ERROR,
+                                      "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                      Irp,
+                                      &pDirEntry->NameInformation.FileName,
+                                      pObjectInfo->FileId.Cell,
+                                      pObjectInfo->FileId.Volume,
+                                      pObjectInfo->FileId.Vnode,
+                                      pObjectInfo->FileId.Unique,
+                                      pParentObjectInfo->FileId.Cell,
+                                      pParentObjectInfo->FileId.Volume,
+                                      pParentObjectInfo->FileId.Vnode,
+                                      pParentObjectInfo->FileId.Unique,
+                                      pObjectInfo->ParentObjectInformation->FileId.Cell,
+                                      pObjectInfo->ParentObjectInformation->FileId.Volume,
+                                      pObjectInfo->ParentObjectInformation->FileId.Vnode,
+                                      pObjectInfo->ParentObjectInformation->FileId.Unique,
+                                      ntStatus);
+                    }
+                }
+                else
+                {
+
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                                  AFS_TRACE_LEVEL_ERROR,
+                                  "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                  Irp,
+                                  &pDirEntry->NameInformation.FileName,
+                                  pObjectInfo->FileId.Cell,
+                                  pObjectInfo->FileId.Volume,
+                                  pObjectInfo->FileId.Vnode,
+                                  pObjectInfo->FileId.Unique,
+                                  ntStatus);
+                }
 
                 try_return( ntStatus);
             }
@@ -1896,8 +1901,9 @@ AFSProcessCreate( IN PIRP               Irp,
             // Allocate and initialize the Fcb for the file.
             //
 
-            ntStatus = AFSInitFcb( pDirEntry,
-                                   Fcb);
+            ntStatus = AFSInitFcb( pDirEntry);
+
+            *Fcb = pObjectInfo->Fcb;
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -1912,9 +1918,27 @@ AFSProcessCreate( IN PIRP               Irp,
                 try_return( ntStatus);
             }
 
-            bAllocatedFcb = TRUE;
+            if ( ntStatus != STATUS_REPARSE)
+            {
+
+                bAllocatedFcb = TRUE;
+            }
+
+            ntStatus = STATUS_SUCCESS;
         }
 
+        //
+        // Increment the open count on this Fcb
+        //
+
+        lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
+                      *Fcb,
+                      lCount);
+
         bReleaseFcb = TRUE;
 
         //
@@ -2027,18 +2051,6 @@ AFSProcessCreate( IN PIRP               Irp,
                           pFileObject,
                           &(*Fcb)->ShareAccess);
 
-        //
-        // Increment the open count on this Fcb
-        //
-
-        lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
-                      *Fcb,
-                      lCount);
-
         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -2105,6 +2117,21 @@ try_exit:
         if( bReleaseFcb)
         {
 
+            if( !NT_SUCCESS( ntStatus))
+            {
+                //
+                // Decrement the open count on this Fcb
+                //
+
+                lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessCreate Decrement count on Fcb %08lX Cnt %d\n",
+                              *Fcb,
+                              lCount);
+            }
+
             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
         }
 
@@ -2130,6 +2157,10 @@ try_exit:
 
                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
 
+                AFSNotifyDelete( pDirEntry,
+                                 AuthGroup,
+                                 FALSE);
+
                 //
                 // Decrement the reference added during initialization of the DE
                 //
@@ -2151,10 +2182,6 @@ try_exit:
                                             pDirEntry,
                                             FALSE); // Leave it in the enum list so the worker cleans it up
 
-                AFSNotifyDelete( pDirEntry,
-                                 AuthGroup,
-                                 FALSE);
-
                 //
                 // Tag the parent as needing verification
                 //
@@ -2176,9 +2203,7 @@ try_exit:
             if( bAllocatedFcb)
             {
 
-                AFSRemoveFcb( pObjectInfo->Fcb);
-
-                pObjectInfo->Fcb = NULL;
+                AFSRemoveFcb( &pObjectInfo->Fcb);
             }
 
             *Fcb = NULL;
@@ -2252,8 +2277,9 @@ AFSOpenTargetDirectory( IN PIRP Irp,
             // Allocate and initialize the Fcb for the file.
             //
 
-            ntStatus = AFSInitFcb( ParentDirectoryCB,
-                                   Fcb);
+            ntStatus = AFSInitFcb( ParentDirectoryCB);
+
+            *Fcb = pParentObject->Fcb;
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -2268,9 +2294,27 @@ AFSOpenTargetDirectory( IN PIRP Irp,
                 try_return( ntStatus);
             }
 
-            bAllocatedFcb = TRUE;
+            if ( ntStatus == STATUS_REPARSE)
+            {
+
+                bAllocatedFcb = TRUE;
+            }
+
+            ntStatus = STATUS_SUCCESS;
         }
 
+        //
+        // Increment the open count on this Fcb
+        //
+
+        lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
+                      pParentObject->Fcb,
+                      lCount);
+
         bReleaseFcb = TRUE;
 
         //
@@ -2381,18 +2425,6 @@ AFSOpenTargetDirectory( IN PIRP Irp,
                               &pParentObject->Fcb->ShareAccess);
         }
 
-        //
-        // Increment the open count on this Fcb
-        //
-
-        lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
-                      pParentObject->Fcb,
-                      lCount);
-
         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -2430,6 +2462,21 @@ try_exit:
         if( bReleaseFcb)
         {
 
+            if( !NT_SUCCESS( ntStatus))
+            {
+                //
+                // Decrement the open count on this Fcb
+                //
+
+                lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSOpenTargetDirectory Decrement count on Fcb %08lX Cnt %d\n",
+                              pParentObject->Fcb,
+                              lCount);
+            }
+
             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
         }
 
@@ -2448,9 +2495,7 @@ try_exit:
             if( bAllocatedFcb)
             {
 
-                AFSRemoveFcb( pParentObject->Fcb);
-
-                pParentObject->Fcb = NULL;
+                AFSRemoveFcb( &pParentObject->Fcb);
             }
 
             *Fcb = NULL;
@@ -2529,7 +2574,6 @@ AFSProcessOpen( IN PIRP Irp,
 
         ntStatus = AFSValidateEntry( DirectoryCB,
                                      AuthGroup,
-                                     TRUE,
                                      FALSE);
 
         if( !NT_SUCCESS( ntStatus))
@@ -2579,8 +2623,7 @@ AFSProcessOpen( IN PIRP Irp,
         if( pObjectInfo->Fcb == NULL)
         {
 
-            ntStatus = AFSInitFcb( DirectoryCB,
-                                   &pObjectInfo->Fcb);
+            ntStatus = AFSInitFcb( DirectoryCB);
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -2595,7 +2638,13 @@ AFSProcessOpen( IN PIRP Irp,
                 try_return( ntStatus);
             }
 
-            bAllocatedFcb = TRUE;
+            if ( ntStatus != STATUS_REPARSE)
+            {
+
+                bAllocatedFcb = TRUE;
+            }
+
+            ntStatus = STATUS_SUCCESS;
         }
         else
         {
@@ -2604,20 +2653,20 @@ AFSProcessOpen( IN PIRP Irp,
                             TRUE);
         }
 
-        bReleaseFcb = TRUE;
-
         //
-        // Reference the Fcb so it won't go away while we call into the service for processing
+        // Increment the open count on this Fcb
         //
 
         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSProcessOpen Increment count on Fcb %08lX Cnt %d\n",
+                      "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
                       pObjectInfo->Fcb,
                       lCount);
 
+        bReleaseFcb = TRUE;
+
         //
         // Check access on the entry
         //
@@ -2847,18 +2896,6 @@ AFSProcessOpen( IN PIRP Irp,
                               &pObjectInfo->Fcb->ShareAccess);
         }
 
-        //
-        // Increment the open count on this Fcb
-        //
-
-        lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
-                      pObjectInfo->Fcb,
-                      lCount);
-
         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -2923,17 +2960,20 @@ try_exit:
         if( bReleaseFcb)
         {
 
-            //
-            // Remove the reference we added initially
-            //
+            if( !NT_SUCCESS( ntStatus))
+            {
+                //
+                // Decrement the open count on this Fcb
+                //
 
-            lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
+                lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSProcessOpen Decrement count on Fcb %08lX Cnt %d\n",
-                          pObjectInfo->Fcb,
-                          lCount);
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessOpen Decrement2 count on Fcb %08lX Cnt %d\n",
+                              pObjectInfo->Fcb,
+                              lCount);
+            }
 
             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
         }
@@ -2973,9 +3013,7 @@ try_exit:
             if( bAllocatedFcb)
             {
 
-                AFSRemoveFcb( pObjectInfo->Fcb);
-
-                pObjectInfo->Fcb = NULL;
+                AFSRemoveFcb( &pObjectInfo->Fcb);
             }
 
             *Fcb = NULL;
@@ -3010,11 +3048,15 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
     AFSObjectInfoCB *pParentObjectInfo = NULL;
     AFSObjectInfoCB *pObjectInfo = NULL;
     LONG lCount;
+    LARGE_INTEGER liSaveSize;
+    LARGE_INTEGER liSaveVDL;
+    LARGE_INTEGER liSaveAlloc;
 
     __Enter
     {
 
         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
+
         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
 
         pFileObject = pIrpSp->FileObject;
@@ -3045,7 +3087,6 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
 
         ntStatus = AFSValidateEntry( DirectoryCB,
                                      AuthGroup,
-                                     TRUE,
                                      FALSE);
 
         if( !NT_SUCCESS( ntStatus))
@@ -3068,8 +3109,9 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
         if( pObjectInfo->Fcb == NULL)
         {
 
-            ntStatus = AFSInitFcb( DirectoryCB,
-                                   Fcb);
+            ntStatus = AFSInitFcb( DirectoryCB);
+
+            *Fcb = pObjectInfo->Fcb;
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -3084,7 +3126,13 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
                 try_return( ntStatus);
             }
 
-            bAllocatedFcb = TRUE;
+            if ( ntStatus != STATUS_REPARSE)
+            {
+
+                bAllocatedFcb = TRUE;
+            }
+
+            ntStatus = STATUS_SUCCESS;
         }
         else
         {
@@ -3093,20 +3141,20 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
                             TRUE);
         }
 
-        bReleaseFcb = TRUE;
-
         //
-        // Reference the Fcb so it won't go away while processing the request
+        // Increment the open count on this Fcb.
         //
 
         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSProcessOverwriteSupersede Increment count on Fcb %08lX Cnt %d\n",
+                      "AFSProcessOverwriteSupersede Increment2 count on Fcb %08lX Cnt %d\n",
                       pObjectInfo->Fcb,
                       lCount);
 
+        bReleaseFcb = TRUE;
+
         //
         // Check access on the entry
         //
@@ -3185,13 +3233,17 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
         (*Ccb)->GrantedAccess = *pDesiredAccess;
 
         //
-        // Need to purge any data currently in the cache
+        // Set the file length to zero
         //
 
-        CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                             NULL,
-                             0,
-                             FALSE);
+        AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
+                        TRUE);
+
+        bReleasePaging = TRUE;
+
+        liSaveSize = pObjectInfo->Fcb->Header.FileSize;
+        liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
+        liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
 
         pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
         pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
@@ -3213,10 +3265,18 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
 
         KeQuerySystemTime( &pObjectInfo->LastAccessTime);
 
-        //KeQuerySystemTime( &pObjectInfo->CreationTime);
-
         KeQuerySystemTime( &pObjectInfo->LastWriteTime);
 
+        //
+        // Set the update flag accordingly
+        //
+
+        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
+                                          AFS_FCB_FLAG_UPDATE_CREATE_TIME |
+                                          AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
+                                          AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
+                                          AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
+
         ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
                                              pObjectInfo,
                                              AuthGroup);
@@ -3224,6 +3284,12 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
         if( !NT_SUCCESS( ntStatus))
         {
 
+            pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
+            pObjectInfo->Fcb->Header.FileSize = liSaveSize;
+            pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
+            pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
+            pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
+
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
                           "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
@@ -3234,34 +3300,6 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
             try_return( ntStatus);
         }
 
-        AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
-                        TRUE);
-
-        bReleasePaging = TRUE;
-
-        pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
-
-        pFileObject->FsContext = (void *)pObjectInfo->Fcb;
-
-        pFileObject->FsContext2 = (void *)*Ccb;
-
-        //
-        // Set the update flag accordingly
-        //
-
-        SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
-                                          AFS_FCB_FLAG_UPDATE_CREATE_TIME |
-                                          AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
-                                          AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
-                                          AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
-
-        CcSetFileSizes( pFileObject,
-                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
-
-        AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
-
-        bReleasePaging = FALSE;
-
         ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
 
         if( ulCreateDisposition == FILE_SUPERSEDE)
@@ -3314,18 +3352,6 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
             Irp->IoStatus.Information = FILE_OVERWRITTEN;
         }
 
-        //
-        // Increment the open count on this Fcb.
-        //
-
-        lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSProcessOverwriteSupersede Increment2 count on Fcb %08lX Cnt %d\n",
-                      pObjectInfo->Fcb,
-                      lCount);
-
         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -3354,8 +3380,27 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
                       pObjectInfo->ParentObjectInformation,
                       lCount);
 
+        AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
+
+        bReleaseFcb = FALSE;
+
         *Fcb = pObjectInfo->Fcb;
 
+        //
+        // Now that the Fcb->Resource has been dropped
+        // we can call CcSetFileSizes.  We are still holding
+        // the PagingIoResource
+        //
+
+        pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
+
+        pFileObject->FsContext = (void *)pObjectInfo->Fcb;
+
+        pFileObject->FsContext2 = (void *)*Ccb;
+
+        CcSetFileSizes( pFileObject,
+                        (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
+
 try_exit:
 
         if( bReleasePaging)
@@ -3367,17 +3412,20 @@ try_exit:
         if( bReleaseFcb)
         {
 
-            //
-            // Remove the reference we added above to prevent tear down
-            //
+            if( !NT_SUCCESS( ntStatus))
+            {
+                //
+                // Decrement the open count on this Fcb.
+                //
 
-            lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
+                lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSProcessOverwriteSupersede Decrement count on Fcb %08lX Cnt %d\n",
-                          pObjectInfo->Fcb,
-                          lCount);
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessOverwriteSupersede Decrement2 count on Fcb %08lX Cnt %d\n",
+                              pObjectInfo->Fcb,
+                              lCount);
+            }
 
             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
         }
@@ -3397,9 +3445,7 @@ try_exit:
             if( bAllocatedFcb)
             {
 
-                AFSRemoveFcb( pObjectInfo->Fcb);
-
-                pObjectInfo->Fcb = NULL;
+                AFSRemoveFcb( &pObjectInfo->Fcb);
             }
 
             *Fcb = NULL;
@@ -3476,8 +3522,9 @@ AFSOpenIOCtlFcb( IN PIRP Irp,
             // Allocate and initialize the Fcb for the file.
             //
 
-            ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
-                                   Fcb);
+            ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
+
+            *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -3491,7 +3538,13 @@ AFSOpenIOCtlFcb( IN PIRP Irp,
                 try_return( ntStatus);
             }
 
-            bAllocatedFcb = TRUE;
+            if ( ntStatus != STATUS_REPARSE)
+            {
+
+                bAllocatedFcb = TRUE;
+            }
+
+            ntStatus = STATUS_SUCCESS;
         }
         else
         {
@@ -3502,6 +3555,18 @@ AFSOpenIOCtlFcb( IN PIRP Irp,
                             TRUE);
         }
 
+        //
+        // Increment the open reference and handle on the node
+        //
+
+        lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSOpenIOCtlFcb Increment count on Fcb %08lX Cnt %d\n",
+                      (*Fcb),
+                      lCount);
+
         bReleaseFcb = TRUE;
 
         //
@@ -3593,17 +3658,9 @@ AFSOpenIOCtlFcb( IN PIRP Irp,
                       lCount);
 
         //
-        // Increment the open reference and handle on the node
+        // Increment the handle on the node
         //
 
-        lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenIOCtlFcb Increment count on Fcb %08lX Cnt %d\n",
-                      (*Fcb),
-                      lCount);
-
         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -3662,6 +3719,21 @@ try_exit:
         if( bReleaseFcb)
         {
 
+            if( !NT_SUCCESS( ntStatus))
+            {
+                //
+                // Decrement the open reference and handle on the node
+                //
+
+                lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSOpenIOCtlFcb Decrement count on Fcb %08lX Cnt %d\n",
+                              (*Fcb),
+                              lCount);
+            }
+
             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
         }
 
@@ -3673,10 +3745,10 @@ try_exit:
 
                 AFSRemoveCcb( NULL,
                               *Ccb);
-
-                *Ccb = NULL;
             }
 
+            *Ccb = NULL;
+
             if( bAllocatedFcb)
             {
 
@@ -3684,14 +3756,10 @@ try_exit:
                 // Need to tear down this Fcb since it is not in the tree for the worker thread
                 //
 
-                AFSRemoveFcb( *Fcb);
-
-                pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb = NULL;
+                AFSRemoveFcb( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
             }
 
             *Fcb = NULL;
-
-            *Ccb = NULL;
         }
     }
 
@@ -3734,8 +3802,9 @@ AFSOpenSpecialShareFcb( IN PIRP Irp,
             // Allocate and initialize the Fcb for the file.
             //
 
-            ntStatus = AFSInitFcb( DirectoryCB,
-                                   Fcb);
+            ntStatus = AFSInitFcb( DirectoryCB);
+
+            *Fcb = DirectoryCB->ObjectInformation->Fcb;
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -3749,7 +3818,13 @@ AFSOpenSpecialShareFcb( IN PIRP Irp,
                 try_return( ntStatus);
             }
 
-            bAllocateFcb = TRUE;
+            if ( ntStatus != STATUS_REPARSE)
+            {
+
+                bAllocateFcb = TRUE;
+            }
+
+            ntStatus = STATUS_SUCCESS;
         }
         else
         {
@@ -3760,6 +3835,18 @@ AFSOpenSpecialShareFcb( IN PIRP Irp,
                             TRUE);
         }
 
+        //
+        // Increment the open count on this Fcb
+        //
+
+        lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSOpenSpecialShareFcb Increment count on Fcb %08lX Cnt %d\n",
+                      (*Fcb),
+                      lCount);
+
         bReleaseFcb = TRUE;
 
         //
@@ -3827,18 +3914,6 @@ AFSOpenSpecialShareFcb( IN PIRP Irp,
             try_return( ntStatus);
         }
 
-        //
-        // Increment the open count on this Fcb
-        //
-
-        lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSOpenSpecialShareFcb Increment count on Fcb %08lX Cnt %d\n",
-                      (*Fcb),
-                      lCount);
-
         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
@@ -3878,6 +3953,21 @@ try_exit:
         if( bReleaseFcb)
         {
 
+            if( !NT_SUCCESS( ntStatus))
+            {
+                //
+                // Decrement the open count on this Fcb
+                //
+
+                lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSOpenSpecialShareFcb Decrement count on Fcb %08lX Cnt %d\n",
+                              (*Fcb),
+                              lCount);
+            }
+
             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
         }
 
@@ -3889,10 +3979,10 @@ try_exit:
 
                 AFSRemoveCcb( NULL,
                               *Ccb);
-
-                *Ccb = NULL;
             }
 
+            *Ccb = NULL;
+
             if( bAllocateFcb)
             {
 
@@ -3900,14 +3990,10 @@ try_exit:
                 // Need to tear down this Fcb since it is not in the tree for the worker thread
                 //
 
-                AFSRemoveFcb( *Fcb);
-
-                DirectoryCB->ObjectInformation->Fcb = NULL;
+                AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
             }
 
             *Fcb = NULL;
-
-            *Ccb = NULL;
         }
     }