Windows: AFSInitFcb STATUS_REPARSE cleanup
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFcbSupport.cpp
index cc61018..9f1a979 100644 (file)
@@ -51,8 +51,7 @@
 //
 
 NTSTATUS
-AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
-            IN OUT AFSFcb     **Fcb)
+AFSInitFcb( IN AFSDirectoryCB  *DirEntry)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
@@ -60,7 +59,6 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
     AFSFcb *pFcb = NULL;
     AFSNonPagedFcb *pNPFcb = NULL;
     IO_STATUS_BLOCK stIoSb = {0,0};
-    BOOLEAN bUninitFileLock = FALSE;
     USHORT  usFcbLength = 0;
     ULONGLONG   ullIndex = 0;
     AFSDirEnumEntry *pDirEnumCB = NULL;
@@ -128,6 +126,7 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
                        sizeof( AFSNonPagedFcb));
 
         pNPFcb->Size = sizeof( AFSNonPagedFcb);
+
         pNPFcb->Type = AFS_NON_PAGED_FCB;
 
         //
@@ -146,6 +145,8 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
 
         ExInitializeResourceLite( &pNPFcb->PagingResource);
 
+        ExInitializeResourceLite( &pNPFcb->CcbListLock);
+
         pFcb->Header.Resource = &pNPFcb->Resource;
 
         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
@@ -166,14 +167,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 +178,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 +192,6 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
                                      NULL,
                                      NULL);
 
-            bUninitFileLock = TRUE;
-
             //
             // Initialize the header file sizes to our dir entry information
             //
@@ -274,65 +257,87 @@ AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
         }
         else
         {
-            ASSERT( FALSE);
-            try_return( ntStatus = STATUS_INVALID_PARAMETER);
+            pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
         }
 
         //
-        // And return the Fcb
+        // Initialize some fields in the Fcb
         //
 
-        *Fcb = pFcb;
+        if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_WARNING,
+                          "AFSInitFcb Raced Fcb %08lX pFcb %08lX Name %wZ\n",
+                          pObjectInfo->Fcb,
+                          pFcb,
+                          &DirEntry->NameInformation.FileName);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
+                          &pObjectInfo->Fcb->NPFcb->Resource,
+                          PsGetCurrentThread());
+
+            AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
+                            TRUE);
+
+            try_return( ntStatus = STATUS_REPARSE);
+        }
+
+        pFcb->ObjectInformation = pObjectInfo;
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
-                                                    pFcb,
-                                                    &DirEntry->NameInformation.FileName);
-
+                      &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->PagingResource);
+
+                    ExDeleteResourceLite( &pNPFcb->CcbListLock);
+
+                    ExDeleteResourceLite( &pNPFcb->Resource);
+
+                    AFSExFreePool( pNPFcb);
+                }
 
-                *Fcb = NULL;
+                AFSExFreePool( pFcb);
             }
         }
     }
@@ -356,6 +361,7 @@ AFSInitVolume( IN GUID *AuthGroup,
     BOOLEAN bReleaseLocks = FALSE;
     AFSVolumeInfoCB stVolumeInformation;
     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
+    LONG lCount;
 
     __Enter
     {
@@ -413,7 +419,7 @@ AFSInitVolume( IN GUID *AuthGroup,
                 // So we don't lock with an invalidation call ...
                 //
 
-                InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
                 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
 
@@ -424,7 +430,7 @@ AFSInitVolume( IN GUID *AuthGroup,
                 AFSAcquireExcl( pVolumeCB->VolumeLock,
                                 TRUE);
 
-                InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
                 *VolumeCB = pVolumeCB;
 
@@ -617,15 +623,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)
             {
@@ -773,7 +783,7 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
             if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
             {
 
-                AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+                AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
             }
 
             AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
@@ -800,7 +810,6 @@ AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
 
             if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
             {
-
                 AFSReleaseResource( VolumeCB->VolumeLock);
             }
 
@@ -931,6 +940,8 @@ AFSInitRootFcb( IN ULONGLONG ProcessID,
 
         ExInitializeResourceLite( &pNPFcb->PagingResource);
 
+        ExInitializeResourceLite( &pNPFcb->CcbListLock);
+
         pFcb->Header.Resource = &pNPFcb->Resource;
 
         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
@@ -938,14 +949,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
         //
 
@@ -1003,6 +1006,8 @@ AFSRemoveRootFcb( IN AFSFcb *RootFcb)
 
         ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
 
+        ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
+
         //
         // The non paged region
         //
@@ -1032,9 +1037,19 @@ 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
     //
@@ -1042,23 +1057,23 @@ AFSRemoveFcb( IN AFSFcb *Fcb)
     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSRemoveFcb Removing Fcb %08lX\n",
-                  Fcb);
+                  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)
     {
 
 
@@ -1068,29 +1083,29 @@ AFSRemoveFcb( IN AFSFcb *Fcb)
     // Tear down the FM specific contexts
     //
 
-    FsRtlTeardownPerStreamContexts( &Fcb->Header);
+    FsRtlTeardownPerStreamContexts( &pFcb->Header);
 
     //
     // Delete the resources
     //
 
-    ExDeleteResourceLite( &Fcb->NPFcb->Resource);
-
-    ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
+    ExDeleteResourceLite( &pFcb->NPFcb->Resource);
 
+    ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
 
+    ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
 
     //
     // The non paged region
     //
 
-    AFSExFreePool( Fcb->NPFcb);
+    AFSExFreePool( pFcb->NPFcb);
 
     //
     // And the Fcb itself, which includes the name
     //
 
-    AFSExFreePool( Fcb);
+    AFSExFreePool( pFcb);
 
     return;
 }
@@ -1166,11 +1181,52 @@ try_exit:
 //
 
 NTSTATUS
-AFSRemoveCcb( IN AFSCcb *Ccb)
+AFSRemoveCcb( IN AFSFcb *Fcb,
+              IN AFSCcb *Ccb)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
 
+    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)
     {
 
@@ -1217,3 +1273,33 @@ AFSRemoveCcb( IN AFSCcb *Ccb)
 
     return ntStatus;
 }
+
+NTSTATUS
+AFSInsertCcb( IN AFSFcb *Fcb,
+              IN AFSCcb *Ccb)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+
+    AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
+                    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( &Fcb->NPFcb->CcbListLock);
+
+    return ntStatus;
+}