Windows: fix indentation
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index ec9a025..4bd9ea6 100644 (file)
@@ -424,10 +424,10 @@ AFSLockUserBuffer( IN void *UserBuffer,
 
     NTSTATUS ntStatus = STATUS_SUCCESS;
     void *pAddress = NULL;
-       MDL *pMdl = NULL;
+    MDL *pMdl = NULL;
 
-       __Enter
-       {
+    __Enter
+    {
 
         pMdl = IoAllocateMdl( UserBuffer,
                               BufferLength,
@@ -435,11 +435,11 @@ AFSLockUserBuffer( IN void *UserBuffer,
                               FALSE,
                               NULL);
 
-               if( pMdl == NULL)
-               {
+            if( pMdl == NULL)
+            {
 
-                       try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
-               }
+                try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+            }
 
         //
         //  Lock the new Mdl in memory.
@@ -449,11 +449,11 @@ AFSLockUserBuffer( IN void *UserBuffer,
         {
 
             MmProbeAndLockPages( pMdl,
-                                                                KernelMode,
+                                 KernelMode,
                                  IoWriteAccess);
 
             pAddress = MmGetSystemAddressForMdlSafe( pMdl,
-                                                                                                        NormalPagePriority);
+                                                     NormalPagePriority);
         }
         __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
         {
@@ -463,11 +463,11 @@ AFSLockUserBuffer( IN void *UserBuffer,
             pAddress = NULL;
         }
 
-               if( pMdl != NULL)
-               {
+        if( pMdl != NULL)
+        {
 
-                       *Mdl = pMdl;
-               }
+            *Mdl = pMdl;
+        }
 
 try_exit:
 
@@ -5398,25 +5398,10 @@ AFSSetEnumerationEvent( IN AFSFcb *Fcb)
     {
 
         case AFS_DIRECTORY_FCB:
-        {
-
-            KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
-                        0,
-                        FALSE);
-
-            lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
-
-            break;
-        }
-
         case AFS_ROOT_FCB:
         case AFS_ROOT_ALL:
         {
 
-            KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
-                        0,
-                        FALSE);
-
             lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
 
             break;
@@ -5440,21 +5425,6 @@ AFSClearEnumerationEvent( IN AFSFcb *Fcb)
     {
 
         case AFS_DIRECTORY_FCB:
-        {
-
-            ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
-
-            lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
-
-            if( lCount == 0)
-            {
-
-                KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
-            }
-
-            break;
-        }
-
         case AFS_ROOT_FCB:
         case AFS_ROOT_ALL:
         {
@@ -5463,12 +5433,6 @@ AFSClearEnumerationEvent( IN AFSFcb *Fcb)
 
             lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
 
-            if( lCount == 0)
-            {
-
-                KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
-            }
-
             break;
         }
     }
@@ -5491,30 +5455,15 @@ AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
             try_return( bIsInProcess);
         }
 
-        //
-        // Depending on the type of node, set the event
-        //
-
         switch( ObjectInfo->Fcb->Header.NodeTypeCode)
         {
 
             case AFS_DIRECTORY_FCB:
-            {
-
-                if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
-                {
-
-                    bIsInProcess = TRUE;
-                }
-
-                break;
-            }
-
             case AFS_ROOT_FCB:
             case AFS_ROOT_ALL:
             {
 
-                if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
+                if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
                 {
 
                     bIsInProcess = TRUE;
@@ -8622,6 +8571,9 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                 LARGE_INTEGER liCurrentOffset = {0,0};
                 LARGE_INTEGER liFlushLength = {0,0};
                 ULONG ulFlushLength = 0;
+                BOOLEAN bLocked = FALSE;
+                BOOLEAN bExtentsLocked = FALSE;
+                BOOLEAN bCleanExtents = FALSE;
 
                 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
                     ObjectInfo->Fcb != NULL)
@@ -8630,101 +8582,290 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                     AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
                                     TRUE);
 
-                    AFSLockForExtentsTrim( ObjectInfo->Fcb);
+                    bLocked = TRUE;
 
-                    __try
-                    {
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
+                                  &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                  PsGetCurrentThread());
 
-                        le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+                    AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+                                      TRUE);
 
-                        ulProcessCount = 0;
+                    bExtentsLocked = TRUE;
 
-                        ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+                    //
+                    // There are several possibilities here:
+                    //
+                    // 0. If there are no extents or all of the extents are dirty, do nothing.
+                    //
+                    // 1. There could be nothing dirty and an open reference count of zero
+                    //    in which case we can just tear down all of the extents without
+                    //    holding any resources.
+                    //
+                    // 2. There could be nothing dirty and a non-zero open reference count
+                    //    in which case we can issue a CcPurge against the entire file
+                    //    while holding just the Fcb Resource.
+                    //
+                    // 3. There can be dirty extents in which case we need to identify
+                    //    the non-dirty ranges and then perform a CcPurge on just the
+                    //    non-dirty ranges while holding just the Fcb Resource.
+                    //
 
-                        if( ulCount > 0)
+                    if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
+                    {
+
+                        if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
                         {
-                            pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
 
-                            while( ulProcessCount < ulCount)
+                            if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
                             {
-                                pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
 
-                                if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                bExtentsLocked = FALSE;
+
+                                AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+
+                                bLocked = FALSE;
+
+                                (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
+                                                              NULL);
+                            }
+                            else
+                            {
+
+                                __try
                                 {
+
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                    bExtentsLocked = FALSE;
+
                                     if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                              &pEntry->FileOffset,
-                                                              pEntry->Size,
+                                                              NULL,
+                                                              0,
                                                               FALSE))
                                     {
                                         SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
                                     }
+                                    else
+                                    {
+
+                                        bCleanExtents = TRUE;
+                                    }
                                 }
+                                __except( EXCEPTION_EXECUTE_HANDLER)
+                                {
+
+                                    ntStatus = GetExceptionCode();
+
+                                    AFSDbgLogMsg( 0,
+                                                  0,
+                                                  "EXCEPTION - AFSPerformObjectInvalidate Status %08lX\n",
+                                                  ntStatus);
+                                }
+                            }
+                        }
+                        else
+                        {
+
+                            //
+                            // Must build a list of non-dirty ranges from the beginning of the file
+                            // to the end.  There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
+                            // ranges.  In all but the most extreme random data write scenario there will
+                            // be significantly fewer.
+                            //
+                            // For each range we need offset and size.
+                            //
+
+                            AFSByteRange * ByteRangeList = NULL;
+                            ULONG          ulByteRangeCount = 0;
+                            ULONG          ulIndex;
+                            BOOLEAN        bPurgeOnClose = FALSE;
+
+                            __try
+                            {
 
-                                if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+                                ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
+                                                                                   &ByteRangeList);
+
+                                if ( ByteRangeList != NULL ||
+                                     ulByteRangeCount == 0)
                                 {
 
-                                    liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+                                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+                                    bExtentsLocked = FALSE;
 
-                                    while( liFlushLength.QuadPart > 0)
+                                    for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
                                     {
 
-                                        if( liFlushLength.QuadPart > 512 * 1024000)
-                                        {
-                                            ulFlushLength = 512 * 1024000;
-                                        }
-                                        else
+                                        ULONG ulSize;
+
+                                        do {
+
+                                            ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
+
+                                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                      &ByteRangeList[ulIndex].FileOffset,
+                                                                      ulSize,
+                                                                      FALSE))
+                                            {
+
+                                                bPurgeOnClose = TRUE;
+                                            }
+                                            else
+                                            {
+
+                                                bCleanExtents = TRUE;
+                                            }
+
+                                            ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
+
+                                            ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
+
+                                        } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
+                                    }
+                                }
+                                else
+                                {
+
+                                    //
+                                    // We couldn't allocate the memory to build the purge list
+                                    // so just walk the extent list while holding the ExtentsList Resource.
+                                    // This could deadlock but we do not have much choice.
+                                    //
+
+                                    le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+
+                                    ulProcessCount = 0;
+
+                                    ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+
+                                    if( ulCount > 0)
+                                    {
+                                        pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                                        while( ulProcessCount < ulCount)
                                         {
-                                            ulFlushLength = liFlushLength.LowPart;
+                                            pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                                            if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                                            {
+                                                if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                          &pEntry->FileOffset,
+                                                                          pEntry->Size,
+                                                                          FALSE))
+                                                {
+
+                                                    bPurgeOnClose = TRUE;
+                                                }
+                                                else
+                                                {
+
+                                                    bCleanExtents = TRUE;
+                                                }
+                                            }
+
+                                            if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+                                            {
+
+                                                liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+
+                                                while( liFlushLength.QuadPart > 0)
+                                                {
+
+                                                    if( liFlushLength.QuadPart > 512 * 1024000)
+                                                    {
+                                                        ulFlushLength = 512 * 1024000;
+                                                    }
+                                                    else
+                                                    {
+                                                        ulFlushLength = liFlushLength.LowPart;
+                                                    }
+
+                                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                              &liCurrentOffset,
+                                                                              ulFlushLength,
+                                                                              FALSE))
+                                                    {
+
+                                                        bPurgeOnClose = TRUE;
+                                                    }
+                                                    else
+                                                    {
+
+                                                        bCleanExtents = TRUE;
+                                                    }
+
+                                                    liFlushLength.QuadPart -= ulFlushLength;
+                                                }
+                                            }
+
+                                            liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+
+                                            ulProcessCount++;
+                                            le = le->Flink;
                                         }
-
+                                    }
+                                    else
+                                    {
                                         if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                                  &liCurrentOffset,
-                                                                  ulFlushLength,
+                                                                  NULL,
+                                                                  0,
                                                                   FALSE))
                                         {
-                                            SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+                                            bPurgeOnClose = TRUE;
                                         }
+                                        else
+                                        {
 
-                                        liFlushLength.QuadPart -= ulFlushLength;
+                                            bCleanExtents = TRUE;
+                                        }
                                     }
-                                }
 
-                                liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+                                    if ( bPurgeOnClose)
+                                    {
 
-                                ulProcessCount++;
-                                le = le->Flink;
+                                        SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+                                    }
+                                }
                             }
-                        }
-                        else
-                        {
-                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                      NULL,
-                                                      0,
-                                                      FALSE))
+                            __except( EXCEPTION_EXECUTE_HANDLER)
                             {
-                                SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+                                ntStatus = GetExceptionCode();
+
+                                AFSDbgLogMsg( 0,
+                                              0,
+                                              "EXCEPTION - AFSPerformObjectInvalidate Status %08lX\n",
+                                              ntStatus);
                             }
                         }
                     }
-                    __except( EXCEPTION_EXECUTE_HANDLER)
+
+                    if ( bExtentsLocked)
                     {
 
-                        ntStatus = GetExceptionCode();
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
                     }
 
-                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
-
-                    AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+                    if ( bLocked)
+                    {
 
-                    AFSReleaseCleanExtents( ObjectInfo->Fcb,
-                                            NULL);
-                }
+                        AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+                    }
 
-                break;
-            }
+                    if ( bCleanExtents)
+                    {
 
-            default:
-            {
+                        AFSReleaseCleanExtents( ObjectInfo->Fcb,
+                                                NULL);
+                    }
+                }
 
                 break;
             }