Windows: DirOpenReferenceCount reorganizing completed
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSDirControl.cpp
index e67de20..b6bb2ef 100644 (file)
@@ -54,11 +54,9 @@ NTSTATUS
 AFSDirControl( IN PDEVICE_OBJECT LibDeviceObject,
                IN PIRP Irp)
 {
-
+    UNREFERENCED_PARAMETER(LibDeviceObject);
     NTSTATUS ntStatus = STATUS_SUCCESS;
-    ULONG ulRequestType = 0;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    AFSFcb *pFcb = NULL;
 
     __try
     {
@@ -120,21 +118,18 @@ AFSQueryDirectory( IN PIRP Irp)
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     BOOLEAN bInitialQuery = FALSE;
-    ULONG ulIndex;
     PUCHAR pBuffer;
     ULONG ulUserBufferLength;
     PUNICODE_STRING puniArgFileName = NULL;
     UNICODE_STRING uniTmpMaskName;
-    UNICODE_STRING uniDirUniBuf;
     WCHAR wchMaskBuffer[ 4];
     FILE_INFORMATION_CLASS FileInformationClass;
-    ULONG ulFileIndex, ulDOSFileIndex;
+    ULONG ulFileIndex;
     BOOLEAN bRestartScan;
     BOOLEAN bReturnSingleEntry;
     BOOLEAN bIndexSpecified;
     ULONG ulNextEntry = 0;
     ULONG ulLastEntry = 0;
-    BOOLEAN bDoCase;
     PFILE_DIRECTORY_INFORMATION pDirInfo;
     PFILE_FULL_DIR_INFORMATION pFullDirInfo;
     PFILE_BOTH_DIR_INFORMATION pBothDirInfo;
@@ -144,9 +139,7 @@ AFSQueryDirectory( IN PIRP Irp)
     AFSDirectoryCB *pDirEntry = NULL;
     BOOLEAN bReleaseMain = FALSE;
     BOOLEAN bReleaseFcb = FALSE;
-    ULONG ulTargetFileType = AFS_FILE_TYPE_UNKNOWN;
     AFSFileInfoCB       stFileInfo;
-    BOOLEAN         bUseFileInfo = TRUE;
     AFSObjectInfoCB *pObjectInfo = NULL;
     ULONG ulAdditionalAttributes = 0;
     LONG lCount;
@@ -165,7 +158,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryDirectory Attempted access (%08lX) when pFcb == NULL\n",
+                          "AFSQueryDirectory Attempted access (%p) when pFcb == NULL\n",
                           Irp);
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
@@ -178,7 +171,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSQueryDirectory Attempted access (%08lX) to non-directory Fcb %08lX NodeType %u\n",
+                          "AFSQueryDirectory Attempted access (%p) to non-directory Fcb %p NodeType %u\n",
                           Irp,
                           pFcb,
                           pFcb->Header.NodeTypeCode);
@@ -218,7 +211,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryDirectory Acquiring Dcb lock %08lX EXCL %08lX\n",
+                          "AFSQueryDirectory Acquiring Dcb lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->Resource,
                           PsGetCurrentThread());
 
@@ -237,7 +230,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSQueryDirectory Acquiring Dcb lock %08lX SHARED %08lX\n",
+                          "AFSQueryDirectory Acquiring Dcb lock %p SHARED %08lX\n",
                           &pFcb->NPFcb->Resource,
                           PsGetCurrentThread());
 
@@ -604,7 +597,7 @@ AFSQueryDirectory( IN PIRP Irp)
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+                              "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
                               Irp,
                               FileInformationClass);
 
@@ -615,7 +608,31 @@ AFSQueryDirectory( IN PIRP Irp)
         {
 
             ULONG ulBytesRemainingInBuffer;
-            int rc;
+
+            //
+            // Drop the DirOpenReferenceCount held during a prior
+            // execution of the loop
+            //
+
+            if ( pDirEntry != NULL)
+            {
+
+                lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSQueryDirectory Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
+                              &pDirEntry->NameInformation.FileName,
+                              pDirEntry,
+                              pCcb,
+                              lCount);
+
+                ASSERT( lCount >= 0);
+
+                pDirEntry = NULL;
+            }
+
+            ulAdditionalAttributes = 0;
 
             //
             //  If the user had requested only a single match and we have
@@ -628,6 +645,10 @@ AFSQueryDirectory( IN PIRP Irp)
                 try_return( ntStatus);
             }
 
+            //
+            // On Success, pDirEntry has a held DirOpenReferenceCount
+            //
+
             pDirEntry = AFSLocateNextDirEntry( pFcb->ObjectInformation,
                                                pCcb);
 
@@ -660,8 +681,6 @@ AFSQueryDirectory( IN PIRP Irp)
                      BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
             {
 
-                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                 continue;
             }
 
@@ -684,8 +703,6 @@ AFSQueryDirectory( IN PIRP Irp)
                     if( !FlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
                     {
 
-                        lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                         continue;
                     }
                 }
@@ -705,8 +722,6 @@ AFSQueryDirectory( IN PIRP Irp)
                                                       NULL))
                         {
 
-                            lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                             continue;
                         }
                     }
@@ -727,8 +742,6 @@ AFSQueryDirectory( IN PIRP Irp)
                                                          TRUE))
                             {
 
-                                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                                 continue;
                             }
                         }
@@ -741,42 +754,27 @@ AFSQueryDirectory( IN PIRP Irp)
             // We don't worry about entries while enumerating the directory
             //
 
-            AFSValidateEntry( pDirEntry,
-                              &pCcb->AuthGroup,
-                              FALSE);
-
-            pObjectInfo = pDirEntry->ObjectInformation;
-
-            bUseFileInfo = FALSE;
-
-            ulAdditionalAttributes = 0;
-
-            if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
+            if ( BooleanFlagOn( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
             {
 
-                //
-                // Go grab the file information for this entry
-                // No worries on failures since we will just display
-                // pseudo information
-                //
-
-                RtlZeroMemory( &stFileInfo,
-                               sizeof( AFSFileInfoCB));
-
-                if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB,
-                                                           pDirEntry,
-                                                           &pCcb->FullFileName,
-                                                           pCcb->NameArray,
-                                                           &pCcb->AuthGroup,
-                                                           &stFileInfo)))
+                ntStatus = AFSValidateEntry( pDirEntry,
+                                             &pCcb->AuthGroup,
+                                             FALSE,
+                                             FALSE);
+                if ( NT_SUCCESS( ntStatus))
                 {
 
-                    ulAdditionalAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+                    ClearFlag( pDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
+                }
+                else
+                {
 
-                    bUseFileInfo = TRUE;
+                    ntStatus = STATUS_SUCCESS;
                 }
             }
 
+            pObjectInfo = pDirEntry->ObjectInformation;
+
             //  Here are the rules concerning filling up the buffer:
             //
             //  1.  The Io system guarantees that there will always be
@@ -804,11 +802,77 @@ AFSQueryDirectory( IN PIRP Irp)
 
                 pCcb->CurrentDirIndex--;
 
-                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                 try_return( ntStatus = STATUS_SUCCESS);
             }
 
+
+            //
+            // For Symlinks and Mount Points the reparse point attribute
+            // must be associated with the directory entry.  In addition,
+            // for Symlinks it must be determined if the target object is
+            // a directory or not.  If so, the directory attribute must be
+            // specified.  Mount points always refer to directories and
+            // must have the directory attribute set.
+            //
+
+            switch( pObjectInfo->FileType)
+            {
+
+            case AFS_FILE_TYPE_MOUNTPOINT:
+            case AFS_FILE_TYPE_DFSLINK:
+            {
+
+                ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT;
+
+                break;
+            }
+
+            case AFS_FILE_TYPE_SYMLINK:
+            {
+
+                //
+                // Go grab the file information for this entry
+                // No worries on failures since we will just display
+                // pseudo information
+                //
+
+                RtlZeroMemory( &stFileInfo,
+                               sizeof( AFSFileInfoCB));
+
+                if( NT_SUCCESS( AFSRetrieveFileAttributes( pCcb->DirectoryCB,
+                                                           pDirEntry,
+                                                           &pCcb->FullFileName,
+                                                           pCcb->NameArray,
+                                                           &pCcb->AuthGroup,
+                                                           &stFileInfo)))
+                {
+
+                    if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                    {
+
+                        ulAdditionalAttributes = FILE_ATTRIBUTE_DIRECTORY;
+                    }
+                }
+
+                ulAdditionalAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+
+                break;
+            }
+            }
+
+            //
+            // Check if the name begins with a . and we are hiding them
+            //
+
+            if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
+                pDirEntry->NameInformation.FileName.Buffer[ 0] == L'.' &&
+                BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
+            {
+
+                ulAdditionalAttributes |= FILE_ATTRIBUTE_HIDDEN;
+            }
+
+
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSQueryDirectory Insert into parent %wZ Entry %wZ\n",
@@ -847,20 +911,7 @@ AFSQueryDirectory( IN PIRP Irp)
                 {
                     pDirInfo = (PFILE_DIRECTORY_INFORMATION)&pBuffer[ ulNextEntry];
 
-                    if( bUseFileInfo)
-                    {
-
-                        pDirInfo->CreationTime = stFileInfo.CreationTime;
-                        pDirInfo->LastWriteTime = stFileInfo.LastWriteTime;
-                        pDirInfo->LastAccessTime = stFileInfo.LastAccessTime;
-                        pDirInfo->ChangeTime = stFileInfo.ChangeTime;
-
-                        pDirInfo->EndOfFile = stFileInfo.EndOfFile;
-                        pDirInfo->AllocationSize = stFileInfo.AllocationSize;
-
-                        pDirInfo->FileAttributes = stFileInfo.FileAttributes | ulAdditionalAttributes;
-                    }
-                    else if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
+                    if( BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
                     {
 
                         pDirInfo->CreationTime = pFcb->ObjectInformation->CreationTime;
@@ -891,19 +942,16 @@ AFSQueryDirectory( IN PIRP Irp)
                         pDirInfo->EndOfFile = pObjectInfo->EndOfFile;
                         pDirInfo->AllocationSize = pObjectInfo->AllocationSize;
 
-                        pDirInfo->FileAttributes = pObjectInfo->FileAttributes | ulAdditionalAttributes;
-                    }
-
-                    //
-                    // Check if the name begins with a . and we are hiding them
-                    //
+                        if ( ulAdditionalAttributes && pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+                        {
 
-                    if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
-                        pDirEntry->NameInformation.FileName.Buffer[ 0] == L'.' &&
-                        BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
-                    {
+                            pDirInfo->FileAttributes = ulAdditionalAttributes;
+                        }
+                        else
+                        {
 
-                        pDirInfo->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
+                            pDirInfo->FileAttributes = pObjectInfo->FileAttributes | ulAdditionalAttributes;
+                        }
                     }
 
                     pDirInfo->FileIndex = pDirEntry->FileIndex;
@@ -920,19 +968,16 @@ AFSQueryDirectory( IN PIRP Irp)
 
                     break;
                 }
+
                 default:
                 {
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
-                                  "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
+                                  "AFSQueryDirectory (%p) Unknown FileInformationClass %u\n",
                                   Irp,
                                   FileInformationClass);
 
-                    lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                     try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
-
-                    break;
                 }
             }
 
@@ -956,13 +1001,9 @@ AFSQueryDirectory( IN PIRP Irp)
             if( ulBytesConverted < pDirEntry->NameInformation.FileName.Length)
             {
 
-                lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
                 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
             }
 
-            lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
-
             dStatus = STATUS_SUCCESS;
 
             //  Set ourselves up for the next iteration
@@ -972,6 +1013,22 @@ AFSQueryDirectory( IN PIRP Irp)
 
 try_exit:
 
+        if ( pDirEntry != NULL)
+        {
+
+            lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSQueryDirectory Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          pCcb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         if( bReleaseMain)
         {
 
@@ -1020,7 +1077,7 @@ AFSNotifyChangeDirectory( IN PIRP Irp)
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_ERROR,
-                          "AFSNotifyChangeDirectory Attempted access (%08lX) when pFcb == NULL\n",
+                          "AFSNotifyChangeDirectory Attempted access (%p) when pFcb == NULL\n",
                           Irp);
 
             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
@@ -1046,7 +1103,7 @@ AFSNotifyChangeDirectory( IN PIRP Irp)
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSNotifyChangeDirectory Acquiring Dcb lock %08lX EXCL %08lX\n",
+                      "AFSNotifyChangeDirectory Acquiring Dcb lock %p EXCL %08lX\n",
                       &pFcb->NPFcb->Resource,
                       PsGetCurrentThread());
 
@@ -1130,12 +1187,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
                 pDirEntry = ObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
 
-                if( pDirEntry != NULL)
-                {
-
-                    lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
-                }
-
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSLocateNextDirEntry Returning PIOctl entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
@@ -1162,12 +1213,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
             pDirEntry = AFSGlobalDotDirEntry;
 
-            if( pDirEntry != NULL)
-            {
-
-                lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
-            }
-
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSLocateNextDirEntry Returning1 snapshot entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
@@ -1186,12 +1231,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
             pDirEntry = AFSGlobalDotDotDirEntry;
 
-            if( pDirEntry != NULL)
-            {
-
-                lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
-            }
-
             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSLocateNextDirEntry Returning2 snapshot entry %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
@@ -1262,8 +1301,6 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
                                       ObjectInfo->FileId.Volume,
                                       ObjectInfo->FileId.Vnode,
                                       ObjectInfo->FileId.Unique);
-
-                        lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
                     }
                     else
                     {
@@ -1300,6 +1337,22 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
 try_exit:
 
+        if( pDirEntry != NULL)
+        {
+
+            lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSLocateNextDirEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
+                          &pDirEntry->NameInformation.FileName,
+                          pDirEntry,
+                          Ccb,
+                          lCount);
+
+            ASSERT( lCount >= 0);
+        }
+
         AFSReleaseResource( &Ccb->NPCcb->CcbLock);
 
         AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
@@ -1446,7 +1499,7 @@ AFSSnapshotDirectory( IN AFSFcb *Fcb,
             if( Ccb->DirectorySnapshot != NULL)
             {
 
-                AFSExFreePool( Ccb->DirectorySnapshot);
+                AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
 
                 Ccb->DirectorySnapshot = NULL;
             }
@@ -1534,7 +1587,7 @@ AFSSnapshotDirectory( IN AFSFcb *Fcb,
         if( Ccb->DirectorySnapshot != NULL)
         {
 
-            AFSExFreePool( Ccb->DirectorySnapshot);
+            AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
 
             Ccb->DirectorySnapshot = NULL;
         }
@@ -1616,7 +1669,7 @@ AFSFsRtlNotifyFullChangeDirectory( IN AFSObjectInfoCB *ObjectInfo,
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NOTIF_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSFsRtlNotifyFullChangeDirectory Registering notification on %wZ Irp %08lX Filter %08lX Tree %02lX\n",
+                      "AFSFsRtlNotifyFullChangeDirectory Registering notification on %wZ Irp %p Filter %08lX Tree %02lX\n",
                       &Ccb->NotifyMask,
                       NotifyIrp,
                       CompletionFilter,
@@ -1642,7 +1695,7 @@ try_exit:
             if( Ccb->NotifyMask.Buffer != NULL)
             {
 
-                AFSExFreePool( Ccb->NotifyMask.Buffer);
+                AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
 
                 Ccb->NotifyMask.Buffer = NULL;
             }
@@ -1763,7 +1816,7 @@ try_exit:
         if( uniName.Buffer != NULL)
         {
 
-            AFSExFreePool( uniName.Buffer);
+            AFSExFreePoolWithTag( uniName.Buffer, AFS_GENERIC_MEMORY_8_TAG);
         }
     }
 
@@ -1778,10 +1831,9 @@ BOOLEAN
 AFSNotifyReportChangeCallback( IN void *NotifyContext,
                                IN void *FilterContext)
 {
-
+    UNREFERENCED_PARAMETER(NotifyContext);
+    UNREFERENCED_PARAMETER(FilterContext);
     BOOLEAN bReturn = TRUE;
-    AFSCcb *pDirCcb = (AFSCcb *)NotifyContext;
-    AFSCcb *pNotifyCcb = (AFSCcb *)FilterContext;
 
     __Enter
     {