Windows: add braces to case statements
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSDirControl.cpp
index ca759ff..1c5a8cc 100644 (file)
@@ -262,16 +262,75 @@ AFSQueryDirectory( IN PIRP Irp)
         }
 
         //
-        // Grab the directory node hdr tree lock shared while parsing the directory
+        // Grab the directory node hdr tree lock while parsing the directory
         // contents
         //
 
-        AFSAcquireShared( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
-                          TRUE);
+        AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                        TRUE);
 
         bReleaseMain = TRUE;
 
         //
+        // Before attempting to insert the new entry, check if we need to validate the parent
+        //
+
+        if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSQueryDirectory Verifying parent %wZ FID %08lX-%08lX-%08lX-%08lX\n",
+                          &pCcb->DirectoryCB->NameInformation.FileName,
+                          pFcb->ObjectInformation->FileId.Cell,
+                          pFcb->ObjectInformation->FileId.Volume,
+                          pFcb->ObjectInformation->FileId.Vnode,
+                          pFcb->ObjectInformation->FileId.Unique);
+
+            ntStatus = AFSVerifyEntry( &pFcb->AuthGroup,
+                                       pCcb->DirectoryCB);
+
+            if( !NT_SUCCESS( ntStatus))
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSQueryDirectory Failed to verify parent %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                              &pCcb->DirectoryCB->NameInformation.FileName,
+                              pFcb->ObjectInformation->FileId.Cell,
+                              pFcb->ObjectInformation->FileId.Volume,
+                              pFcb->ObjectInformation->FileId.Vnode,
+                              pFcb->ObjectInformation->FileId.Unique,
+                              ntStatus);
+
+                try_return( ntStatus);
+            }
+
+            //
+            // Perform a new snapshot of the directory
+            //
+
+            ntStatus = AFSSnapshotDirectory( pFcb,
+                                             pCcb,
+                                             FALSE);
+
+            if( !NT_SUCCESS( ntStatus))
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSQueryDirectory Snapshot directory failure for parent %wZ Mask %wZ Status %08lX\n",
+                              &pCcb->DirectoryCB->NameInformation.FileName,
+                              &pCcb->MaskName,
+                              ntStatus);
+
+                try_return( ntStatus);
+            }
+        }
+
+        AFSConvertToShared( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+        //
         // We can now safely drop the lock on the node
         //
 
@@ -295,7 +354,8 @@ AFSQueryDirectory( IN PIRP Irp)
         {
 
             ntStatus = AFSSnapshotDirectory( pFcb,
-                                             pCcb);
+                                             pCcb,
+                                             TRUE);
 
             if( !NT_SUCCESS( ntStatus))
             {
@@ -540,7 +600,7 @@ AFSQueryDirectory( IN PIRP Irp)
                               FileInformationClass);
 
                 try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
-            }
+        }
 
         AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
 
@@ -595,6 +655,8 @@ AFSQueryDirectory( IN PIRP Irp)
                      BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
             {
 
+                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                 continue;
             }
 
@@ -617,6 +679,8 @@ AFSQueryDirectory( IN PIRP Irp)
                     if( !FlagOn( pObjectInfo->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
                     {
 
+                        InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                         continue;
                     }
                 }
@@ -636,6 +700,8 @@ AFSQueryDirectory( IN PIRP Irp)
                                                       NULL))
                         {
 
+                            InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                             continue;
                         }
                     }
@@ -656,6 +722,8 @@ AFSQueryDirectory( IN PIRP Irp)
                                                          TRUE))
                             {
 
+                                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                                 continue;
                             }
                         }
@@ -729,6 +797,8 @@ AFSQueryDirectory( IN PIRP Irp)
 
                 pCcb->CurrentDirIndex--;
 
+                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                 try_return( ntStatus = STATUS_SUCCESS);
             }
 
@@ -748,7 +818,7 @@ AFSQueryDirectory( IN PIRP Irp)
                 //  Now fill the base parts of the structure that are applicable.
                 case FileIdBothDirectoryInformation:
                 case FileBothDirectoryInformation:
-
+                {
                     pBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)&pBuffer[ ulNextEntry];
 
                     pBothDirInfo->ShortNameLength = (CHAR)pDirEntry->NameInformation.ShortNameLength;
@@ -759,14 +829,15 @@ AFSQueryDirectory( IN PIRP Irp)
                                        &pDirEntry->NameInformation.ShortName[ 0],
                                        pBothDirInfo->ShortNameLength);
                     }
+                }
                 case FileIdFullDirectoryInformation:
                 case FileFullDirectoryInformation:
-
+                {
                     pFullDirInfo = (PFILE_FULL_DIR_INFORMATION)&pBuffer[ ulNextEntry];
                     pFullDirInfo->EaSize = 0;
-
+                }
                 case FileDirectoryInformation:
-
+                {
                     pDirInfo = (PFILE_DIRECTORY_INFORMATION)&pBuffer[ ulNextEntry];
 
                     if( bUseFileInfo)
@@ -832,26 +903,30 @@ AFSQueryDirectory( IN PIRP Irp)
                     pDirInfo->FileNameLength = pDirEntry->NameInformation.FileName.Length;
 
                     break;
+                }
 
                 case FileNamesInformation:
-
+                {
                     pNamesInfo = (PFILE_NAMES_INFORMATION)&pBuffer[ ulNextEntry];
                     pNamesInfo->FileIndex = pDirEntry->FileIndex;
                     pNamesInfo->FileNameLength = pDirEntry->NameInformation.FileName.Length;
 
                     break;
-
+                }
                 default:
-
+                {
                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                   AFS_TRACE_LEVEL_ERROR,
                                   "AFSQueryDirectory (%08lX) Unknown FileInformationClass %u\n",
                                   Irp,
                                   FileInformationClass);
 
+                    InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                     try_return( ntStatus = STATUS_INVALID_INFO_CLASS);
 
                     break;
+                }
             }
 
             ulBytesConverted = ulBytesRemainingInBuffer - ulBaseLength >= pDirEntry->NameInformation.FileName.Length ?
@@ -874,9 +949,13 @@ AFSQueryDirectory( IN PIRP Irp)
             if( ulBytesConverted < pDirEntry->NameInformation.FileName.Length)
             {
 
+                InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
                 try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
             }
 
+            InterlockedDecrement( &pDirEntry->OpenReferenceCount);
+
             dStatus = STATUS_SUCCESS;
 
             //  Set ourselves up for the next iteration
@@ -1109,6 +1188,9 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
             // Get to a valid entry
             //
 
+            AFSAcquireShared( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+                              TRUE);
+
             while( ulCount < pSnapshotHdr->EntryCount)
             {
 
@@ -1145,6 +1227,8 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
                                       ObjectInfo->FileId.Volume,
                                       ObjectInfo->FileId.Vnode,
                                       ObjectInfo->FileId.Unique);
+
+                        InterlockedIncrement( &pDirEntry->OpenReferenceCount);
                     }
                     else
                     {
@@ -1177,6 +1261,8 @@ AFSLocateNextDirEntry( IN AFSObjectInfoCB *ObjectInfo,
 
                 Ccb->CurrentDirIndex++;
             }
+
+            AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
         }
 
 try_exit:
@@ -1281,7 +1367,8 @@ try_exit:
 
 NTSTATUS
 AFSSnapshotDirectory( IN AFSFcb *Fcb,
-                      IN AFSCcb *Ccb)
+                      IN AFSCcb *Ccb,
+                      IN BOOLEAN ResetIndex)
 {
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
@@ -1292,19 +1379,23 @@ AFSSnapshotDirectory( IN AFSFcb *Fcb,
     __Enter
     {
 
-        //
-        // Set it up so we still get the . and .. entries for empty directories
-        //
-
-        if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES))
+        if( ResetIndex)
         {
 
-            Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_DIR_INDEX;
-        }
-        else
-        {
+            //
+            // Set it up so we still get the . and .. entries for empty directories
+            //
+
+            if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES))
+            {
 
-            Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_ROOT_INDEX;
+                Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_DIR_INDEX;
+            }
+            else
+            {
+
+                Ccb->CurrentDirIndex = AFS_DIR_ENTRY_INITIAL_ROOT_INDEX;
+            }
         }
 
         if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeCount == 0)