Windows: correct typos or mistaken comments
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSExtentsSupport.cpp
index 0738720..63f2f95 100644 (file)
@@ -39,7 +39,6 @@
 
 #define AFS_MAX_FCBS_TO_DROP 10
 
-static AFSExtent *ExtentFor( PLIST_ENTRY le, ULONG SkipList );
 static AFSExtent *NextExtent( AFSExtent *Extent, ULONG SkipList );
 static ULONG ExtentsMasks[AFS_NUM_EXTENT_LISTS] = AFS_EXTENTS_MASKS;
 static VOID VerifyExtentsLists(AFSFcb *Fcb);
@@ -62,7 +61,7 @@ AFSLockForExtentsTrim( IN AFSFcb *Fcb)
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSLockForExtentsTrim Acuiring Fcb extents lock %08lX EXCL %08lX\n",
+                  "AFSLockForExtentsTrim Acquiring Fcb extents lock %08lX EXCL %08lX\n",
                   &pNPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
@@ -81,7 +80,7 @@ AFSLockForExtentsTrimNoWait( IN AFSFcb *Fcb)
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSLockForExtentsTrimNoWait Attempting to acquiring Fcb extent lock %08lX EXCL %08lX\n",
+                  "AFSLockForExtentsTrimNoWait Attempting to acquire Fcb extent lock %08lX EXCL %08lX\n",
                   &pNPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
@@ -121,11 +120,15 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb,
     AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
     GUID                *pAuthGroup = AuthGroup;
     GUID                 stAuthGroup;
+    LONG                 lCount;
 
     __Enter
     {
 
-        if( pAuthGroup == NULL)
+        if( pAuthGroup == NULL ||
+            RtlCompareMemory( pAuthGroup,
+                              &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                              sizeof( GUID)) == sizeof( GUID))
         {
 
             RtlZeroMemory( &stAuthGroup,
@@ -158,10 +161,6 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb,
             try_return ( ntStatus = STATUS_SUCCESS);
         }
 
-        //
-        // Release a max of 100 extents at a time
-        //
-
         sz = sizeof( AFSReleaseExtentsCB ) + (AFS_MAXIMUM_EXTENT_RELEASE_COUNT * sizeof ( AFSFileExtentCB ));
 
         pRelease = (AFSReleaseExtentsCB*) AFSExAllocatePoolWithTag( NonPagedPool,
@@ -276,9 +275,11 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb,
                 le = le->Flink;
                 AFSExFreePool( pEntry);
 
-                InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
 
-                if( InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount) == 0)
+                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+                if( lCount == 0)
                 {
 
                     KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
@@ -618,47 +619,59 @@ BOOLEAN AFSDoExtentsMapRegion(IN AFSFcb *Fcb,
 
         AFSAcquireShared( &Fcb->NPFcb->Specific.File.ExtentsResource, TRUE );
 
-        entry = AFSExtentForOffsetHint(Fcb, Offset, TRUE, *FirstExtent);
-        *FirstExtent = entry;
-
-        if (NULL == entry || !AFSExtentContains(entry, Offset))
-        {
-            try_return (retVal = FALSE);
-        }
-
-        ASSERT(Offset->QuadPart >= entry->FileOffset.QuadPart);
-
-        while (TRUE)
+        __try
         {
-            if ((entry->FileOffset.QuadPart + entry->Size) >=
-                                                (Offset->QuadPart + Size))
-            {
-                //
-                // The end is inside the extent
-                //
-                try_return (retVal = TRUE);
-            }
+            entry = AFSExtentForOffsetHint(Fcb, Offset, TRUE, *FirstExtent);
+            *FirstExtent = entry;
 
-            if (entry->Lists[AFS_EXTENTS_LIST].Flink == &Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST])
+            if (NULL == entry || !AFSExtentContains(entry, Offset))
             {
-                //
-                // Run out of extents
-                //
                 try_return (retVal = FALSE);
             }
 
-            newEntry = NextExtent( entry, AFS_EXTENTS_LIST );
+            ASSERT(Offset->QuadPart >= entry->FileOffset.QuadPart);
 
-            if (newEntry->FileOffset.QuadPart !=
-                (entry->FileOffset.QuadPart + entry->Size))
+            while (TRUE)
             {
-                //
-                // Gap
-                //
-                try_return (retVal = FALSE);
+                if ((entry->FileOffset.QuadPart + entry->Size) >=
+                     (Offset->QuadPart + Size))
+                {
+                    //
+                    // The end is inside the extent
+                    //
+                    try_return (retVal = TRUE);
+                }
+
+                if (entry->Lists[AFS_EXTENTS_LIST].Flink == &Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST])
+                {
+                    //
+                    // Run out of extents
+                    //
+                    try_return (retVal = FALSE);
+                }
+
+                newEntry = NextExtent( entry, AFS_EXTENTS_LIST );
+
+                if (newEntry->FileOffset.QuadPart !=
+                     (entry->FileOffset.QuadPart + entry->Size))
+                {
+                    //
+                    // Gap
+                    //
+                    try_return (retVal = FALSE);
+                }
+
+                entry = newEntry;
             }
+        }
+        __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+        {
 
-            entry = newEntry;
+            AFSDbgLogMsg( 0,
+                          0,
+                          "EXCEPTION - AFSDoExtentsMapRegion\n");
+
+            AFSDumpTraceFilesFnc();
         }
 
 try_exit:
@@ -677,216 +690,72 @@ try_exit:
     return retVal;
 }
 
-//
-// Given an FCB and an Offset we look to see whether there extents to
-// Map them all.  If there are then we return TRUE to fullymapped
-// and *FirstExtent points to the first extent to map the extent.
-// If not then we return FALSE, but we request the extents to be mapped.
-// Further *FirstExtent (if non null) is the last extent which doesn't
-// map the extent.
-//
-// Finally on the way *in* if *FirstExtent is non null it is where we start looking
-//
-
 NTSTATUS
-AFSRequestExtents( IN AFSFcb *Fcb,
-                   IN AFSCcb *Ccb,
-                   IN PLARGE_INTEGER Offset,
-                   IN ULONG Size,
-                   OUT BOOLEAN *FullyMapped)
+AFSRequestExtentsAsync( IN AFSFcb *Fcb,
+                        IN AFSCcb *Ccb,
+                        IN PLARGE_INTEGER Offset,
+                        IN ULONG Size)
 {
 
     AFSDeviceExt        *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     NTSTATUS             ntStatus = STATUS_SUCCESS;
-    AFSExtent           *pExtent;
+    AFSExtent           *pExtent = NULL;
     AFSRequestExtentsCB  request;
     AFSNonPagedFcb      *pNPFcb = Fcb->NPFcb;
-    AFSExtent           *pFirstExtent;
+    AFSExtent           *pFirstExtent = NULL;
     LARGE_INTEGER        liAlignedOffset;
     ULONG                ulAlignedLength = 0;
-    LARGE_INTEGER        liTimeOut;
+    BOOLEAN              bRegionMapped = FALSE;
     ULONGLONG            ullProcessId = (ULONGLONG)PsGetCurrentProcessId();
 
-    //
-    // Check our extents, then fire off a request if we need to.
-    // We start off knowing nothing about where we will go.
-    //
-    pFirstExtent = NULL;
-    pExtent = NULL;
-
-    *FullyMapped = AFSDoExtentsMapRegion( Fcb, Offset, Size, &pFirstExtent, &pExtent );
-
-    if (*FullyMapped)
-    {
-
-        ASSERT(AFSExtentContains(pFirstExtent, Offset));
-        LARGE_INTEGER end = *Offset;
-        end.QuadPart += (Size-1);
-        ASSERT(AFSExtentContains(pExtent, &end));
-
-        return STATUS_SUCCESS;
-    }
-
-    //
-    // So we need to queue a request. Since we will be clearing the
-    // ExtentsRequestComplete event we need to do with with the lock
-    // EX
-    //
-
-    liTimeOut.QuadPart = -(50000000);
-
-    while (TRUE)
+    __Enter
     {
-        if (!NT_SUCCESS( pNPFcb->Specific.File.ExtentsRequestStatus))
-        {
-
-            //
-            // If this isn't the same process which caused the failure
-            // then try to request them again
-            //
-
-            if( Fcb->Specific.File.ExtentRequestProcessId == ullProcessId)
-            {
-                ntStatus = pNPFcb->Specific.File.ExtentsRequestStatus;
-
-                break;
-            }
-
-            pNPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
-        }
-
-        ntStatus = KeWaitForSingleObject( &pNPFcb->Specific.File.ExtentsRequestComplete,
-                                          Executive,
-                                          KernelMode,
-                                          FALSE,
-                                          &liTimeOut);
-        if (!NT_SUCCESS(ntStatus))
-        {
-
-            //
-            // try again
-            //
 
-            continue;
-        }
+        ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->Specific.File.ExtentsResource ));
 
         //
-        // Lock resource EX and look again
+        // If the service set a failure on the file since the last
+        // CreateFile was issued, return it now.
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRequestExtents Acquiring Fcb extent lock %08lX EXCL %08lX\n",
-                      &pNPFcb->Specific.File.ExtentsResource,
-                      PsGetCurrentThread());
-
-        AFSAcquireExcl( &pNPFcb->Specific.File.ExtentsResource, TRUE );
-
         if (!NT_SUCCESS( pNPFcb->Specific.File.ExtentsRequestStatus))
         {
 
             //
-            // If this isn't the same process which caused the failure then try to request them again
+            // If this isn't the same authgroup which caused the failure
+            // then try to request them again
             //
 
-            if( Fcb->Specific.File.ExtentRequestProcessId == ullProcessId)
-            {
-                ntStatus = pNPFcb->Specific.File.ExtentsRequestStatus;
-
-                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSRequestExtents Releasing Fcb extent lock %08lX EXCL %08lX\n",
-                              &pNPFcb->Specific.File.ExtentsResource,
-                              PsGetCurrentThread());
-
-                AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource );
-
-                break;
-            }
-
-            pNPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
-        }
-
-        if( KeReadStateEvent( &pNPFcb->Specific.File.ExtentsRequestComplete) ||
-            ntStatus == STATUS_TIMEOUT)
-        {
-
-            ntStatus = pNPFcb->Specific.File.ExtentsRequestStatus;
-
-            if( !NT_SUCCESS( ntStatus))
+            if( RtlCompareMemory( &pNPFcb->Specific.File.ExtentsRequestAuthGroup,
+                                  &Ccb->AuthGroup,
+                                  sizeof( GUID)) == sizeof( GUID))
             {
 
-                //
-                // If this isn't the same process which caused the failure
-                // then try to request them again
-                //
-
-                if( Fcb->Specific.File.ExtentRequestProcessId == ullProcessId)
-                {
-                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                                  AFS_TRACE_LEVEL_VERBOSE,
-                                  "AFSRequestExtents Releasing Fcb extent lock %08lX EXCL %08lX\n",
-                                  &pNPFcb->Specific.File.ExtentsResource,
-                                  PsGetCurrentThread());
+                ntStatus = pNPFcb->Specific.File.ExtentsRequestStatus;
 
-                    AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource );
-                }
-                else
-                {
+                pNPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
 
-                    pNPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+                RtlZeroMemory( &pNPFcb->Specific.File.ExtentsRequestAuthGroup,
+                               sizeof( GUID));
 
-                    ntStatus = STATUS_SUCCESS;
-                }
+                try_return( ntStatus);
             }
-
-            break;
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRequestExtents Releasing Fcb extent lock %08lX EXCL %08lX\n",
-                      &pNPFcb->Specific.File.ExtentsResource,
-                      PsGetCurrentThread());
-
-        AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource );
-    }
-
-    if (!NT_SUCCESS(ntStatus))
-    {
-
-        return ntStatus;
-    }
-
-    __Enter
-    {
         //
-        // We have the lock Ex and there is no filling going on.
-        // Check again to see whether things have moved since we last
-        // checked.  Since we haven't locked against pinning, we will
-        // reset here.
+        // Check if we are already mapped
         //
 
-        pFirstExtent = NULL;
-
-        *FullyMapped = AFSDoExtentsMapRegion(Fcb, Offset, Size, &pFirstExtent, &pExtent);
+        bRegionMapped = AFSDoExtentsMapRegion( Fcb, Offset, Size, &pFirstExtent, &pExtent);
 
-        if (*FullyMapped)
+        if( bRegionMapped)
         {
 
-            ASSERT(AFSExtentContains(pFirstExtent, Offset));
-            LARGE_INTEGER end = *Offset;
-            end.QuadPart += (Size-1);
-            ASSERT(AFSExtentContains(pExtent, &end));
-
-            try_return (ntStatus = STATUS_SUCCESS);
+            try_return( ntStatus = STATUS_SUCCESS);
         }
 
-        RtlZeroMemory( &request,
-                       sizeof( AFSRequestExtentsCB));
-
         //
-        // Align the request
+        // Align our request on extent size boundary
         //
 
         ulAlignedLength = Size;
@@ -907,6 +776,9 @@ AFSRequestExtents( IN AFSFcb *Fcb,
             ulAlignedLength = (ULONG)(((ulAlignedLength / pDevExt->Specific.RDR.CacheBlockSize) + 1) * pDevExt->Specific.RDR.CacheBlockSize);
         }
 
+        RtlZeroMemory( &request,
+                       sizeof( AFSRequestExtentsCB));
+
         request.ByteOffset = liAlignedOffset;
         request.Length = ulAlignedLength;
 
@@ -917,7 +789,7 @@ AFSRequestExtents( IN AFSFcb *Fcb,
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSRequestExtents Request extents for fid %08lX-%08lX-%08lX-%08lX Offset %08lX Len %08lX Thread %08lX\n",
+                          "AFSRequestExtentsAsync Request extents for fid %08lX-%08lX-%08lX-%08lX Offset %08lX Len %08lX Thread %08lX\n",
                           Fcb->ObjectInformation->FileId.Cell,
                           Fcb->ObjectInformation->FileId.Volume,
                           Fcb->ObjectInformation->FileId.Vnode,
@@ -936,8 +808,37 @@ AFSRequestExtents( IN AFSFcb *Fcb,
                                           NULL,
                                           NULL);
 
+            if (  ntStatus == STATUS_ACCESS_DENIED)
+            {
+                GUID                 stAuthGroup;
+                DWORD                ntStatus2;
+
+                ntStatus2 = AFSRetrieveValidAuthGroup( Fcb,
+                                                      NULL,
+                                                      TRUE,
+                                                      &stAuthGroup);
+
+                if ( NT_SUCCESS( ntStatus2) &&
+                     RtlCompareMemory( &stAuthGroup,
+                                       &Ccb->AuthGroup,
+                                       sizeof( GUID)) != sizeof( GUID))
+                {
+
+                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS,
+                                                  0,
+                                                  &stAuthGroup,
+                                                  NULL,
+                                                  &Fcb->ObjectInformation->FileId,
+                                                  &request,
+                                                  sizeof( AFSRequestExtentsCB ),
+                                                  NULL,
+                                                  NULL);
+                }
+            }
+
             if( NT_SUCCESS( ntStatus))
             {
+
                 KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
             }
         }
@@ -949,206 +850,67 @@ AFSRequestExtents( IN AFSFcb *Fcb,
 
 try_exit:
 
-        if (NT_SUCCESS( ntStatus ))
-        {
-            KeQueryTickCount( &Fcb->Specific.File.LastExtentAccess );
-        }
-
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSRequestExtents Releasing Fcb extent lock %08lX EXCL %08lX\n",
-                      &pNPFcb->Specific.File.ExtentsResource,
-                      PsGetCurrentThread());
-
-        AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource );
+        NOTHING;
     }
 
     return ntStatus;
 }
 
 NTSTATUS
-AFSRequestExtentsAsync( IN AFSFcb *Fcb,
-                        IN AFSCcb *Ccb,
-                        IN PLARGE_INTEGER Offset,
-                        IN ULONG Size)
+AFSProcessExtentsResult( IN AFSFcb *Fcb,
+                         IN ULONG   Count,
+                         IN AFSFileExtentCB *Result)
 {
+    NTSTATUS          ntStatus = STATUS_SUCCESS;
+    AFSFileExtentCB  *pFileExtents = Result;
+    AFSExtent        *pExtent;
+    LIST_ENTRY       *le;
+    AFSNonPagedFcb   *pNPFcb = Fcb->NPFcb;
+    ULONG             fileExtentsUsed = 0;
+    BOOLEAN           bFoundExtent = FALSE;
+    LIST_ENTRY       *pSkipEntries[AFS_NUM_EXTENT_LISTS] = { 0 };
+    AFSDeviceExt     *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    LONG              lCount;
 
-    AFSDeviceExt        *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
-    NTSTATUS             ntStatus = STATUS_SUCCESS;
-    AFSExtent           *pExtent = NULL;
-    AFSRequestExtentsCB  request;
-    AFSNonPagedFcb      *pNPFcb = Fcb->NPFcb;
-    AFSExtent           *pFirstExtent = NULL;
-    LARGE_INTEGER        liAlignedOffset;
-    ULONG                ulAlignedLength = 0;
-    BOOLEAN              bRegionMapped = FALSE;
-    ULONGLONG            ullProcessId = (ULONGLONG)PsGetCurrentProcessId();
+    //
+    // Grab the extents exclusive for the duration
+    //
+
+    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                  AFS_TRACE_LEVEL_VERBOSE,
+                  "AFSProcessExtentsResult Acquiring Fcb extent lock %08lX EXCL %08lX\n",
+                  &pNPFcb->Specific.File.ExtentsResource,
+                  PsGetCurrentThread());
+
+    AFSAcquireExcl( &pNPFcb->Specific.File.ExtentsResource, TRUE );
 
     __Enter
     {
 
-        ASSERT( !ExIsResourceAcquiredLite( &pNPFcb->Specific.File.ExtentsResource ));
-
         //
-        // If the service set a failure on the file since the last
-        // CreateFile was issued, return it now.
+        // Find where to put the extents
         //
-
-        if (!NT_SUCCESS( pNPFcb->Specific.File.ExtentsRequestStatus))
+        for (ULONG i = AFS_EXTENTS_LIST; i < AFS_NUM_EXTENT_LISTS; i++)
         {
 
-            //
-            // If this isn't the same process which caused the failure then try to request them again
-            //
-
-            if( Fcb->Specific.File.ExtentRequestProcessId == ullProcessId)
-            {
-                try_return( ntStatus = pNPFcb->Specific.File.ExtentsRequestStatus);
-            }
-
-            pNPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+            pSkipEntries[i] = Fcb->Specific.File.ExtentsLists[i].Flink;
         }
 
-        //
-        // Check if we are already mapped
-        //
-
-        bRegionMapped = AFSDoExtentsMapRegion( Fcb, Offset, Size, &pFirstExtent, &pExtent);
+        le = pSkipEntries[AFS_EXTENTS_LIST];
 
-        if( bRegionMapped)
+        if (le == &Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST])
         {
-
-            try_return( ntStatus = STATUS_SUCCESS);
+            //
+            // No extents.  Insert at head of list (which is where the skip lists point!)
+            //
+            pExtent = NULL;
         }
-
-        //
-        // Align our request on extent size boundary
-        //
-
-        ulAlignedLength = Size;
-
-        liAlignedOffset = *Offset;
-
-        if( liAlignedOffset.QuadPart % pDevExt->Specific.RDR.CacheBlockSize != 0)
-        {
-
-            liAlignedOffset.QuadPart = (ULONGLONG)( (ULONGLONG)(liAlignedOffset.QuadPart / pDevExt->Specific.RDR.CacheBlockSize) * (ULONGLONG)pDevExt->Specific.RDR.CacheBlockSize);
-
-            ulAlignedLength += (ULONG)(Offset->QuadPart - liAlignedOffset.QuadPart);
-        }
-
-        if( ulAlignedLength % pDevExt->Specific.RDR.CacheBlockSize != 0)
-        {
-
-            ulAlignedLength = (ULONG)(((ulAlignedLength / pDevExt->Specific.RDR.CacheBlockSize) + 1) * pDevExt->Specific.RDR.CacheBlockSize);
-        }
-
-        RtlZeroMemory( &request,
-                       sizeof( AFSRequestExtentsCB));
-
-        request.ByteOffset = liAlignedOffset;
-        request.Length = ulAlignedLength;
-
-        if( !AFSIsExtentRequestQueued( &Fcb->ObjectInformation->FileId,
-                                       &request.ByteOffset,
-                                       request.Length))
-        {
-
-            AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSRequestExtentsAsync Request extents for fid %08lX-%08lX-%08lX-%08lX Offset %08lX Len %08lX Thread %08lX\n",
-                          Fcb->ObjectInformation->FileId.Cell,
-                          Fcb->ObjectInformation->FileId.Volume,
-                          Fcb->ObjectInformation->FileId.Vnode,
-                          Fcb->ObjectInformation->FileId.Unique,
-                          request.ByteOffset.LowPart,
-                          request.Length,
-                          PsGetCurrentThread());
-
-            ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS,
-                                          0,
-                                          &Ccb->AuthGroup,
-                                          NULL,
-                                          &Fcb->ObjectInformation->FileId,
-                                          &request,
-                                          sizeof( AFSRequestExtentsCB ),
-                                          NULL,
-                                          NULL);
-
-            if( NT_SUCCESS( ntStatus))
-            {
-
-                KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
-            }
-        }
-        else
-        {
-
-            KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
-        }
-
-try_exit:
-
-        NOTHING;
-    }
-
-    return ntStatus;
-}
-
-NTSTATUS
-AFSProcessExtentsResult( IN AFSFcb *Fcb,
-                         IN ULONG   Count,
-                         IN AFSFileExtentCB *Result)
-{
-    NTSTATUS          ntStatus = STATUS_SUCCESS;
-    AFSFileExtentCB  *pFileExtents = Result;
-    AFSExtent        *pExtent;
-    LIST_ENTRY       *le;
-    AFSNonPagedFcb   *pNPFcb = Fcb->NPFcb;
-    ULONG             fileExtentsUsed = 0;
-    BOOLEAN           bFoundExtent = FALSE;
-    LIST_ENTRY       *pSkipEntries[AFS_NUM_EXTENT_LISTS] = { 0 };
-    AFSDeviceExt     *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
-
-    //
-    // Grab the extents exclusive for the duration
-    //
-
-    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                  AFS_TRACE_LEVEL_VERBOSE,
-                  "AFSProcessExtentsResult Acquiring Fcb extent lock %08lX EXCL %08lX\n",
-                  &pNPFcb->Specific.File.ExtentsResource,
-                  PsGetCurrentThread());
-
-    AFSAcquireExcl( &pNPFcb->Specific.File.ExtentsResource, TRUE );
-
-    __Enter
-    {
-
-        //
-        // Find where to put the extents
-        //
-        for (ULONG i = AFS_EXTENTS_LIST; i < AFS_NUM_EXTENT_LISTS; i++)
-        {
-
-            pSkipEntries[i] = Fcb->Specific.File.ExtentsLists[i].Flink;
-        }
-
-        le = pSkipEntries[AFS_EXTENTS_LIST];
-
-        if (le == &Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST])
-        {
-            //
-            // No extents.  Insert at head of list (which is where the skip lists point!)
-            //
-            pExtent = NULL;
-        }
-        else if (0 != pFileExtents->FileOffset.QuadPart)
-        {
-            //
-            // We want to find the best extents immediately *behind* this offset
-            //
-            LARGE_INTEGER offset = pFileExtents->FileOffset;
+        else if (0 != pFileExtents->FileOffset.QuadPart)
+        {
+            //
+            // We want to find the best extents immediately *behind* this offset
+            //
+            LARGE_INTEGER offset = pFileExtents->FileOffset;
 
             //
             // Ask in the top skip list first, then work down
@@ -1260,8 +1022,6 @@ AFSProcessExtentsResult( IN AFSFcb *Fcb,
                 if (NULL  == pExtent)
                 {
 
-                    ASSERT( FALSE);
-
                     try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
                 }
 
@@ -1286,9 +1046,11 @@ AFSProcessExtentsResult( IN AFSFcb *Fcb,
 
                 InterlockedExchangeAdd( &Fcb->Specific.File.ExtentLength, (LONG)(pExtent->Size/1024));
 
-                InterlockedIncrement( &Fcb->Specific.File.ExtentCount);
+                lCount = InterlockedIncrement( &Fcb->Specific.File.ExtentCount);
 
-                if( InterlockedIncrement( &pControlDevExt->Specific.Control.ExtentCount) == 1)
+                lCount = InterlockedIncrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+                if( lCount == 1)
                 {
 
                     KeClearEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent);
@@ -1496,6 +1258,7 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
     AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     ULONGLONG     ullIndex = 0;
     AFSObjectInfoCB *pObjectInfo = NULL;
+    LONG          lCount;
 
     __Enter
     {
@@ -1535,7 +1298,7 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
                           pVolumeCB->ObjectInfoTree.TreeLock,
                           PsGetCurrentThread());
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
         }
 
         AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -1559,7 +1322,7 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
         //
         // Now locate the Object in this volume
@@ -1578,13 +1341,13 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
             // Reference the node so it won't be torn down
             //
 
-            InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSProcessSetFileExtents Increment count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
 
         AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
@@ -1659,13 +1422,13 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSProcessSetFileExtents Decrement count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
     }
 
@@ -1690,6 +1453,7 @@ AFSReleaseSpecifiedExtents( IN  AFSReleaseFileExtentsCB *Extents,
     NTSTATUS             ntStatus = STATUS_SUCCESS;
     BOOLEAN              bReleaseAll = FALSE;
     AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    LONG                 lCount;
 
     __Enter
     {
@@ -1867,7 +1631,7 @@ AFSReleaseSpecifiedExtents( IN  AFSReleaseFileExtentsCB *Extents,
 
                     FileExtents[*ExtentCount].Flags |= AFS_EXTENT_FLAG_DIRTY;
 
-                    InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
+                    lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
 
                     *DirtyExtents = TRUE;
                 }
@@ -1902,9 +1666,11 @@ AFSReleaseSpecifiedExtents( IN  AFSReleaseFileExtentsCB *Extents,
             //
             AFSExFreePool( pExtent);
 
-            InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+            lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+
+            lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
 
-            if( InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount) == 0)
+            if( lCount == 0)
             {
 
                 KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
@@ -1932,6 +1698,7 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
     BOOLEAN bLocatedEntry = FALSE;
     AFSObjectInfoCB *pCurrentObject = NULL;
     BOOLEAN bReleaseVolumeListLock = FALSE;
+    LONG lCount;
 
     pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
@@ -1962,7 +1729,7 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
                       pVolumeCB->ObjectInfoTree.TreeLock,
                       PsGetCurrentThread());
 
-        InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
         AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
 
@@ -1971,7 +1738,7 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
         if( NULL == LastFcb)
         {
@@ -2089,13 +1856,13 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
                 // A hit a very palpable hit.  Pin it
                 //
 
-                InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSFindFcbToClean Increment count on Fcb %08lX Cnt %d\n",
                               pCurrentObject,
-                              pCurrentObject->ObjectReferenceCount);
+                              lCount);
 
                 bLocatedEntry = TRUE;
 
@@ -2141,6 +1908,7 @@ AFSProcessExtentFailure( PIRP Irp)
     AFSVolumeCB                       *pVolumeCB = NULL;
     ULONGLONG                          ullIndex = 0;
     AFSObjectInfoCB                   *pObjectInfo = NULL;
+    LONG                               lCount;
 
     __Enter
     {
@@ -2186,7 +1954,7 @@ AFSProcessExtentFailure( PIRP Irp)
                           pVolumeCB->ObjectInfoTree.TreeLock,
                           PsGetCurrentThread());
 
-            InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
         }
 
         AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -2206,7 +1974,7 @@ AFSProcessExtentFailure( PIRP Irp)
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
         //
         // Now locate the Object in this volume
@@ -2226,13 +1994,13 @@ AFSProcessExtentFailure( PIRP Irp)
             // Reference the node so it won't be torn down
             //
 
-            InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSProcessExtentFailure Increment count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
 
         AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
@@ -2271,6 +2039,10 @@ AFSProcessExtentFailure( PIRP Irp)
 
         pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = pFailureCB->FailureStatus;
 
+        RtlCopyMemory( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                       &pFailureCB->AuthGroup,
+                       sizeof( GUID));
+
         KeSetEvent( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
                     0,
                     FALSE);
@@ -2283,13 +2055,13 @@ AFSProcessExtentFailure( PIRP Irp)
 
         AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
 
-        InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+        lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSProcessExtentFailure Decrement count on object %08lX Cnt %d\n",
                       pObjectInfo,
-                      pObjectInfo->ObjectReferenceCount);
+                      lCount);
 
 try_exit:
 
@@ -2317,6 +2089,7 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
     BOOLEAN                            bLocked = FALSE;
     BOOLEAN                            bDirtyExtents = FALSE;
     GUID                               stAuthGroup;
+    LONG                               lCount;
 
     __Enter
     {
@@ -2420,7 +2193,7 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
                               pVolumeCB->ObjectInfoTree.TreeLock,
                               PsGetCurrentThread());
 
-                InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+                lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
             }
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -2440,7 +2213,7 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
             AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                               TRUE);
 
-            InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
             //
             // Now locate the Object in this volume
@@ -2459,13 +2232,13 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
                 // Reference the node so it won't be torn down
                 //
 
-                InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSProcessReleaseFileExtents Increment count on object %08lX Cnt %d\n",
                               pObjectInfo,
-                              pObjectInfo->ObjectReferenceCount);
+                              lCount);
             }
 
             AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
@@ -2684,13 +2457,13 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSProcessReleaseFileExtents Decrement count on object %08lX Cnt %d\n",
                           pObjectInfo,
-                          pObjectInfo->ObjectReferenceCount);
+                          lCount);
         }
     }
 
@@ -2698,7 +2471,8 @@ try_exit:
 }
 
 NTSTATUS
-AFSWaitForExtentMapping( AFSFcb *Fcb )
+AFSWaitForExtentMapping( AFSFcb *Fcb,
+                         AFSCcb *Ccb)
 {
     NTSTATUS ntStatus = STATUS_SUCCESS;
     LARGE_INTEGER liTimeOut;
@@ -2713,18 +2487,27 @@ AFSWaitForExtentMapping( AFSFcb *Fcb )
         {
 
             //
-            // If this isn't the same process which caused the failure then try to request them again
+            // If this isn't the same authgroup which caused the failure
+            // then try to request them again
             //
 
-            if( Fcb->Specific.File.ExtentRequestProcessId == ullProcessId)
+            if( RtlCompareMemory( &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                                  &Ccb->AuthGroup,
+                                  sizeof( GUID)) == sizeof( GUID))
             {
-                try_return( ntStatus = Fcb->NPFcb->Specific.File.ExtentsRequestStatus);
-            }
 
-            Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+                ntStatus = Fcb->NPFcb->Specific.File.ExtentsRequestStatus;
+
+                Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+
+                RtlZeroMemory( &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                               sizeof( GUID));
+
+                try_return( ntStatus);
+            }
         }
 
-        liTimeOut.QuadPart = -(50000000);
+        liTimeOut.QuadPart = -(1 * AFS_ONE_SECOND);
 
         ntStatus = KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
                                           Executive,
@@ -2736,17 +2519,26 @@ AFSWaitForExtentMapping( AFSFcb *Fcb )
         {
 
             //
-            // If this isn't the same process which caused the failure
-            // and this isn't the System process, then try to request them again
+            // If this isn't the same authgroup which caused the failure
+            // or the System Process,
+            // then try to request the extents again
             //
 
-            if( Fcb->Specific.File.ExtentRequestProcessId == ullProcessId ||
-                ullProcessId == 0x4)
+            if( RtlCompareMemory( &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                                  &Ccb->AuthGroup,
+                                  sizeof( GUID)) == sizeof( GUID) ||
+                ullProcessId == (ULONGLONG)AFSSysProcess)
             {
-                try_return( ntStatus = Fcb->NPFcb->Specific.File.ExtentsRequestStatus);
-            }
 
-            Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+                ntStatus = Fcb->NPFcb->Specific.File.ExtentsRequestStatus;
+
+                Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+
+                RtlZeroMemory( &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                               sizeof( GUID));
+
+                try_return( ntStatus);
+            }
         }
 
         if( ntStatus == STATUS_TIMEOUT)
@@ -2782,6 +2574,7 @@ AFSFlushExtents( IN AFSFcb *Fcb,
     AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
     GUID                *pAuthGroup = AuthGroup;
     GUID                 stAuthGroup;
+    LONG                 lCount;
 
     ASSERT( Fcb->Header.NodeTypeCode == AFS_FILE_FCB);
 
@@ -2796,7 +2589,10 @@ AFSFlushExtents( IN AFSFcb *Fcb,
     __Enter
     {
 
-        if( pAuthGroup == NULL)
+        if( pAuthGroup == NULL ||
+            RtlCompareMemory( pAuthGroup,
+                              &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                              sizeof( GUID)) == sizeof( GUID))
         {
 
             RtlZeroMemory( &stAuthGroup,
@@ -2824,7 +2620,7 @@ AFSFlushExtents( IN AFSFcb *Fcb,
 
         bExtentsLocked = TRUE;
 
-        InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
+        lCount = InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
 
         //
         // Clear our queued flush event
@@ -2901,7 +2697,7 @@ AFSFlushExtents( IN AFSFcb *Fcb,
                 pExtent->DirtyList.fLink = NULL;
                 pExtent->DirtyList.bLink = NULL;
 
-                InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
+                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
 
                 //
                 // Clear the flag in advance of the write. If we do
@@ -2959,9 +2755,11 @@ AFSFlushExtents( IN AFSFcb *Fcb,
 
                 AFSExFreePool( pExtent);
 
-                InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
 
-                if( InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount) == 0)
+                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+                if( lCount == 0)
                 {
 
                     KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
@@ -3046,7 +2844,9 @@ AFSFlushExtents( IN AFSFcb *Fcb,
 
 try_exit:
 
-        if( InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount) == 0)
+        lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
+
+        if( lCount == 0)
         {
 
             KeSetEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
@@ -3098,6 +2898,7 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
     AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
     GUID                *pAuthGroup = AuthGroup;
     GUID                 stAuthGroup;
+    LONG                 lCount;
 
     ASSERT( Fcb->Header.NodeTypeCode == AFS_FILE_FCB);
 
@@ -3112,7 +2913,10 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
     __Enter
     {
 
-        if( pAuthGroup == NULL)
+        if( pAuthGroup == NULL ||
+            RtlCompareMemory( pAuthGroup,
+                              &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                              sizeof( GUID)) == sizeof( GUID))
         {
 
             RtlZeroMemory( &stAuthGroup,
@@ -3238,13 +3042,273 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
                         AFSRemoveEntryDirtyList( Fcb,
                                                  pExtent);
 
-                        pRelease->FileExtents[count].Flags |= AFS_EXTENT_FLAG_DIRTY;
+                        pRelease->FileExtents[count].Flags |= AFS_EXTENT_FLAG_DIRTY;
+
+                        lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
+                    }
+
+                    AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+                }
+
+                //
+                // Need to pull this extent from the main list as well
+                //
+
+                for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i ++)
+                {
+                    if (NULL != pExtent->Lists[i].Flink && !IsListEmpty(&pExtent->Lists[i]))
+                    {
+                        RemoveEntryList( &pExtent->Lists[i] );
+                    }
+                }
+
+                InterlockedExchangeAdd( &pControlDevExt->Specific.Control.ExtentsHeldLength, -((LONG)(pExtent->Size/1024)));
+
+                InterlockedExchangeAdd( &Fcb->Specific.File.ExtentLength, -((LONG)(pExtent->Size/1024)));
+
+                AFSExFreePool( pExtent);
+
+                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+
+                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+                if( lCount == 0)
+                {
+
+                    KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
+                                0,
+                                FALSE);
+                }
+
+                count ++;
+            }
+
+            //
+            // If we are done then get out
+            //
+
+            if( count == 0)
+            {
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSReleaseExtentsWithFlush No more dirty extents found\n");
+
+                break;
+            }
+
+            //
+            // Fire off the request synchronously
+            //
+
+            sz = sizeof( AFSReleaseExtentsCB ) + (count * sizeof ( AFSFileExtentCB ));
+
+            pRelease->ExtentCount = count;
+
+            //
+            // Drop the extents lock for the duration of the call to
+            // the network.  We have pinned the extents so, even
+            // though we might get extents added during this period,
+            // but none will be removed.  Hence we can carry on from
+            // le.
+            //
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSReleaseExtentsWithFlush Releasing Fcb extents lock %08lX thread %08lX\n",
+                          &pNPFcb->Specific.File.ExtentsResource,
+                          PsGetCurrentThread());
+
+            AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource);
+            bExtentsLocked = FALSE;
+
+            ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS,
+                                          AFS_REQUEST_FLAG_SYNCHRONOUS,
+                                          pAuthGroup,
+                                          NULL,
+                                          &Fcb->ObjectInformation->FileId,
+                                          pRelease,
+                                          sz,
+                                          NULL,
+                                          NULL);
+
+            if( !NT_SUCCESS(ntStatus))
+            {
+
+                //
+                // Regardless of whether or not the AFSProcessRequest() succeeded, the extents
+                // were released (if AFS_EXTENT_FLAG_RELEASE was set).  Log the error so it is known.
+                //
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
+                              AFS_TRACE_LEVEL_ERROR,
+                              "AFSReleaseExtentsWithFlush AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS failed fid %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                              Fcb->ObjectInformation->FileId.Cell,
+                              Fcb->ObjectInformation->FileId.Volume,
+                              Fcb->ObjectInformation->FileId.Vnode,
+                              Fcb->ObjectInformation->FileId.Unique,
+                              ntStatus);
+            }
+        }
+
+try_exit:
+
+        if (bExtentsLocked)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSReleaseExtentsWithFlush Releasing Fcb extents lock %08lX thread %08lX\n",
+                          &pNPFcb->Specific.File.ExtentsResource,
+                          PsGetCurrentThread());
+
+            AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource );
+        }
+
+        if (pRelease)
+        {
+            AFSExFreePool( pRelease);
+        }
+    }
+
+    return ntStatus;
+}
+
+NTSTATUS
+AFSReleaseCleanExtents( IN AFSFcb *Fcb,
+                        IN GUID *AuthGroup)
+{
+    AFSNonPagedFcb      *pNPFcb = Fcb->NPFcb;
+    AFSExtent           *pExtent;
+    LIST_ENTRY          *le;
+    AFSReleaseExtentsCB *pRelease = NULL;
+    ULONG                count = 0;
+    ULONG                initialDirtyCount = 0;
+    BOOLEAN              bExtentsLocked = FALSE;
+    ULONG                total = 0;
+    ULONG                sz = 0;
+    NTSTATUS             ntStatus = STATUS_SUCCESS;
+    LARGE_INTEGER        liLastFlush;
+    ULONG                ulRemainingExtentLength = 0;
+    AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    GUID                *pAuthGroup = AuthGroup;
+    GUID                 stAuthGroup;
+
+    ASSERT( Fcb->Header.NodeTypeCode == AFS_FILE_FCB);
+
+    //
+    // Save, then reset the flush time
+    //
+
+    liLastFlush = Fcb->Specific.File.LastServerFlush;
+
+    KeQueryTickCount( &Fcb->Specific.File.LastServerFlush);
+
+    __Enter
+    {
+
+        if( pAuthGroup == NULL ||
+            RtlCompareMemory( pAuthGroup,
+                              &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
+                              sizeof( GUID)) == sizeof( GUID))
+        {
+
+            RtlZeroMemory( &stAuthGroup,
+                           sizeof( GUID));
+
+            ntStatus = AFSRetrieveValidAuthGroup( Fcb,
+                                                  NULL,
+                                                  TRUE,
+                                                  &stAuthGroup);
+
+            if( !NT_SUCCESS( ntStatus))
+            {
+                try_return( ntStatus);
+            }
+
+            pAuthGroup = &stAuthGroup;
+        }
+
+        //
+        // Look for a start in the list to flush entries
+        //
+
+        total = count;
+
+        sz = sizeof( AFSReleaseExtentsCB ) + (AFS_MAXIMUM_EXTENT_RELEASE_COUNT * sizeof ( AFSFileExtentCB ));
+
+        pRelease = (AFSReleaseExtentsCB*) AFSExAllocatePoolWithTag( NonPagedPool,
+                                                                    sz,
+                                                                    AFS_EXTENT_RELEASE_TAG);
+        if( NULL == pRelease)
+        {
+
+            try_return ( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
+        }
+
+        while( Fcb->Specific.File.ExtentLength > (LONG)ulRemainingExtentLength)
+        {
+
+            AFSLockForExtentsTrim( Fcb);
+
+            bExtentsLocked = TRUE;
+
+            pRelease->Flags = AFS_EXTENT_FLAG_RELEASE;
+
+            //
+            // Update the metadata for this call
+            //
+
+            pRelease->AllocationSize = Fcb->ObjectInformation->EndOfFile;
+            pRelease->CreateTime = Fcb->ObjectInformation->CreationTime;
+            pRelease->ChangeTime = Fcb->ObjectInformation->ChangeTime;
+            pRelease->LastAccessTime = Fcb->ObjectInformation->LastAccessTime;
+            pRelease->LastWriteTime = Fcb->ObjectInformation->LastWriteTime;
+
+            count = 0;
+
+            le = Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+
+            while( count < AFS_MAXIMUM_EXTENT_RELEASE_COUNT &&
+                   le != &Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST])
+            {
+
+                pExtent = ExtentFor( le, AFS_EXTENTS_LIST);
+
+                le = le->Flink;
+
+                if( pExtent->ActiveCount > 0 ||
+                    BooleanFlagOn( pExtent->Flags, AFS_EXTENT_DIRTY))
+                {
+                    continue;
+                }
+
+                pRelease->FileExtents[count].Flags = AFS_EXTENT_FLAG_RELEASE;
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSReleaseCleanExtents Releasing extent %p fid %08lX-%08lX-%08lX-%08lX Offset %I64X Len %08lX\n",
+                              pExtent,
+                              Fcb->ObjectInformation->FileId.Cell,
+                              Fcb->ObjectInformation->FileId.Volume,
+                              Fcb->ObjectInformation->FileId.Vnode,
+                              Fcb->ObjectInformation->FileId.Unique,
+                              pExtent->FileOffset.QuadPart,
+                              pExtent->Size);
+
+                pRelease->FileExtents[count].Length = pExtent->Size;
+                pRelease->FileExtents[count].DirtyLength = pExtent->Size;
+                pRelease->FileExtents[count].DirtyOffset = 0;
+                pRelease->FileExtents[count].CacheOffset = pExtent->CacheOffset;
+                pRelease->FileExtents[count].FileOffset = pExtent->FileOffset;
 
-                        InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
-                    }
+#if GEN_MD5
+                RtlCopyMemory( pRelease->FileExtents[count].MD5,
+                               pExtent->MD5,
+                               sizeof(pExtent->MD5));
 
-                    AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
-                }
+                pRelease->FileExtents[count].Flags |= AFS_EXTENT_FLAG_MD5_SET;
+#endif
 
                 //
                 // Need to pull this extent from the main list as well
@@ -3286,7 +3350,7 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSReleaseExtentsWithFlush No more dirty extents found\n");
+                              "AFSReleaseCleanExtents No more dirty extents found\n");
 
                 break;
             }
@@ -3309,7 +3373,7 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSReleaseExtentsWithFlush Releasing Fcb extents lock %08lX thread %08lX\n",
+                          "AFSReleaseCleanExtents Releasing Fcb extents lock %08lX thread %08lX\n",
                           &pNPFcb->Specific.File.ExtentsResource,
                           PsGetCurrentThread());
 
@@ -3336,7 +3400,7 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
                               AFS_TRACE_LEVEL_ERROR,
-                              "AFSReleaseExtentsWithFlush AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS failed fid %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                              "AFSReleaseCleanExtents AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS failed fid %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                               Fcb->ObjectInformation->FileId.Cell,
                               Fcb->ObjectInformation->FileId.Volume,
                               Fcb->ObjectInformation->FileId.Vnode,
@@ -3352,7 +3416,7 @@ try_exit:
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSReleaseExtentsWithFlush Releasing Fcb extents lock %08lX thread %08lX\n",
+                          "AFSReleaseCleanExtents Releasing Fcb extents lock %08lX thread %08lX\n",
                           &pNPFcb->Specific.File.ExtentsResource,
                           PsGetCurrentThread());
 
@@ -3372,7 +3436,8 @@ VOID
 AFSMarkDirty( IN AFSFcb *Fcb,
               IN AFSExtent *StartExtent,
               IN ULONG ExtentsCount,
-              IN LARGE_INTEGER *StartingByte)
+              IN LARGE_INTEGER *StartingByte,
+              IN BOOLEAN DerefExtents)
 {
 
     AFSNonPagedFcb *pNPFcb = Fcb->NPFcb;
@@ -3380,6 +3445,8 @@ AFSMarkDirty( IN AFSFcb *Fcb,
     AFSExtent     *pNextExtent, *pCurrentExtent = NULL;
     ULONG ulCount = 0;
     BOOLEAN bInsertTail = FALSE, bInsertHead = FALSE;
+    LONG lCount;
+    BOOLEAN bLocked = FALSE;
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
@@ -3387,143 +3454,162 @@ AFSMarkDirty( IN AFSFcb *Fcb,
                   &Fcb->NPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
-    AFSAcquireShared( &Fcb->NPFcb->Specific.File.ExtentsResource, TRUE);
+    if( !ExIsResourceAcquiredLite( &Fcb->NPFcb->Specific.File.ExtentsResource))
+    {
+        AFSAcquireShared( &Fcb->NPFcb->Specific.File.ExtentsResource, TRUE);
+        bLocked = TRUE;
+    }
 
     AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
                     TRUE);
 
-    //
-    // Find the insertion point
-    //
-
-    if( pNPFcb->Specific.File.DirtyListHead == NULL)
-    {
-
-        bInsertTail = TRUE;
-    }
-    else if( StartingByte->QuadPart == 0)
+    __try
     {
+        //
+        // Find the insertion point
+        //
 
-        bInsertHead = TRUE;
-    }
-    else
-    {
+        if( pNPFcb->Specific.File.DirtyListHead == NULL)
+        {
 
-        pCurrentExtent = pNPFcb->Specific.File.DirtyListHead;
+            bInsertTail = TRUE;
+        }
+        else if( StartingByte->QuadPart == 0)
+        {
 
-        while( pCurrentExtent != NULL)
+            bInsertHead = TRUE;
+        }
+        else
         {
 
-            if( pCurrentExtent->FileOffset.QuadPart + pCurrentExtent->Size >= StartingByte->QuadPart ||
-                pCurrentExtent->DirtyList.fLink == NULL)
-            {
+            pCurrentExtent = pNPFcb->Specific.File.DirtyListHead;
 
-                break;
-            }
+            while( pCurrentExtent != NULL)
+            {
 
-            pCurrentExtent = (AFSExtent *)pCurrentExtent->DirtyList.fLink;
-        }
-    }
+                if( pCurrentExtent->FileOffset.QuadPart + pCurrentExtent->Size >= StartingByte->QuadPart ||
+                    pCurrentExtent->DirtyList.fLink == NULL)
+                {
 
-    while( ulCount < ExtentsCount)
-    {
+                    break;
+                }
 
-        pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
+                pCurrentExtent = (AFSExtent *)pCurrentExtent->DirtyList.fLink;
+            }
+        }
 
-        if( !BooleanFlagOn( pExtent->Flags, AFS_EXTENT_DIRTY))
+        while( ulCount < ExtentsCount)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSMarkDirty Marking extent offset %I64X Length %08lX DIRTY\n",
-                          pExtent->FileOffset.QuadPart,
-                          pExtent->Size);
-
-            pExtent->DirtyList.fLink = NULL;
-            pExtent->DirtyList.bLink = NULL;
+            pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
 
-            if( bInsertHead)
+            if( !BooleanFlagOn( pExtent->Flags, AFS_EXTENT_DIRTY))
             {
 
-                pExtent->DirtyList.fLink = (void *)pNPFcb->Specific.File.DirtyListHead;
+                AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSMarkDirty Marking extent offset %I64X Length %08lX DIRTY\n",
+                              pExtent->FileOffset.QuadPart,
+                              pExtent->Size);
 
+                pExtent->DirtyList.fLink = NULL;
                 pExtent->DirtyList.bLink = NULL;
 
-                pNPFcb->Specific.File.DirtyListHead->DirtyList.bLink = (void *)pExtent;
-
-                pNPFcb->Specific.File.DirtyListHead = pExtent;
+                if( bInsertHead)
+                {
 
-                pCurrentExtent = pExtent;
+                    pExtent->DirtyList.fLink = (void *)pNPFcb->Specific.File.DirtyListHead;
 
-                bInsertHead = FALSE;
-            }
-            else if( bInsertTail)
-            {
+                    pExtent->DirtyList.bLink = NULL;
 
-                if( pNPFcb->Specific.File.DirtyListHead == NULL)
-                {
+                    pNPFcb->Specific.File.DirtyListHead->DirtyList.bLink = (void *)pExtent;
 
                     pNPFcb->Specific.File.DirtyListHead = pExtent;
-                }
-                else
-                {
 
-                    pNPFcb->Specific.File.DirtyListTail->DirtyList.fLink = (void *)pExtent;
+                    pCurrentExtent = pExtent;
 
-                    pExtent->DirtyList.bLink = (void *)pNPFcb->Specific.File.DirtyListTail;
+                    bInsertHead = FALSE;
                 }
+                else if( bInsertTail)
+                {
 
-                pNPFcb->Specific.File.DirtyListTail = pExtent;
-            }
-            else
-            {
+                    if( pNPFcb->Specific.File.DirtyListHead == NULL)
+                    {
 
-                pExtent->DirtyList.fLink = pCurrentExtent->DirtyList.fLink;
-                pExtent->DirtyList.bLink = (void *)pCurrentExtent;
+                        pNPFcb->Specific.File.DirtyListHead = pExtent;
+                    }
+                    else
+                    {
 
-                if( pExtent->DirtyList.fLink == NULL)
-                {
+                        pNPFcb->Specific.File.DirtyListTail->DirtyList.fLink = (void *)pExtent;
+
+                        pExtent->DirtyList.bLink = (void *)pNPFcb->Specific.File.DirtyListTail;
+                    }
 
                     pNPFcb->Specific.File.DirtyListTail = pExtent;
                 }
                 else
                 {
 
-                    ((AFSExtent *)pExtent->DirtyList.fLink)->DirtyList.bLink = (void *)pExtent;
+                    pExtent->DirtyList.fLink = pCurrentExtent->DirtyList.fLink;
+
+                    pExtent->DirtyList.bLink = (void *)pCurrentExtent;
+
+                    if( pExtent->DirtyList.fLink == NULL)
+                    {
+
+                        pNPFcb->Specific.File.DirtyListTail = pExtent;
+                    }
+                    else
+                    {
+
+                        ((AFSExtent *)pExtent->DirtyList.fLink)->DirtyList.bLink = (void *)pExtent;
+                    }
+
+                    pCurrentExtent->DirtyList.fLink = (void *)pExtent;
+
+                    pCurrentExtent = pExtent;
                 }
 
-                pCurrentExtent->DirtyList.fLink = (void *)pExtent;
+                pExtent->Flags |= AFS_EXTENT_DIRTY;
+
+                //
+                // Up the dirty count
+                //
+
+                lCount = InterlockedIncrement( &Fcb->Specific.File.ExtentsDirtyCount);
+            }
+            else
+            {
 
                 pCurrentExtent = pExtent;
             }
 
-            pExtent->Flags |= AFS_EXTENT_DIRTY;
+            AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_ACTIVE_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSMarkDirty Decrement count on extent %08lX Cnt %d\n",
+                          pExtent,
+                          pExtent->ActiveCount);
 
-            //
-            // Up the dirty count
-            //
+            if( DerefExtents)
+            {
+                ASSERT( pExtent->ActiveCount > 0);
+                lCount = InterlockedDecrement( &pExtent->ActiveCount);
+            }
 
-            InterlockedIncrement( &Fcb->Specific.File.ExtentsDirtyCount);
-        }
-        else
-        {
+            pExtent = pNextExtent;
 
-            pCurrentExtent = pExtent;
+            ulCount++;
         }
+    }
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+    {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_ACTIVE_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSMarkDirty Decrement count on extent %08lX Cnt %d\n",
-                      pExtent,
-                      pExtent->ActiveCount);
-
-        ASSERT( pExtent->ActiveCount > 0);
-
-        InterlockedDecrement( &pExtent->ActiveCount);
-
-        pExtent = pNextExtent;
+        AFSDbgLogMsg( 0,
+                      0,
+                      "EXCEPTION - AFSMarkDirty\n");
 
-        ulCount++;
+        AFSDumpTraceFilesFnc();
     }
 
     AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
@@ -3534,7 +3620,10 @@ AFSMarkDirty( IN AFSFcb *Fcb,
                   &Fcb->NPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
-    AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
+    if( bLocked)
+    {
+        AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
+    }
 
     return;
 }
@@ -3543,7 +3632,8 @@ AFSMarkDirty( IN AFSFcb *Fcb,
 // Helper functions
 //
 
-static AFSExtent *ExtentFor(PLIST_ENTRY le, ULONG SkipList)
+AFSExtent *
+ExtentFor(PLIST_ENTRY le, ULONG SkipList)
 {
     return CONTAINING_RECORD( le, AFSExtent, Lists[SkipList] );
 }
@@ -3627,6 +3717,7 @@ AFSTrimExtents( IN AFSFcb *Fcb,
     LARGE_INTEGER        liAlignedOffset = {0,0};
     AFSDeviceExt        *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    LONG                 lCount;
 
     __Enter
     {
@@ -3766,9 +3857,11 @@ AFSTrimExtents( IN AFSFcb *Fcb,
                 //
                 AFSExFreePool( pExtent);
 
-                InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
 
-                if( InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount) == 0)
+                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+                if( lCount == 0)
                 {
 
                     KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
@@ -3815,6 +3908,7 @@ AFSTrimSpecifiedExtents( IN AFSFcb *Fcb,
     NTSTATUS             ntStatus = STATUS_SUCCESS;
     AFSDeviceExt        *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
     AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    LONG                 lCount;
 
     __Enter
     {
@@ -3890,9 +3984,11 @@ AFSTrimSpecifiedExtents( IN AFSFcb *Fcb,
                 //
                 AFSExFreePool( pExtent);
 
-                InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
 
-                if( InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount) == 0)
+                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+                if( lCount == 0)
                 {
 
                     KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
@@ -3928,19 +4024,20 @@ AFSReferenceActiveExtents( IN AFSExtent *StartExtent,
     AFSExtent     *pExtent = StartExtent;
     AFSExtent     *pNextExtent;
     ULONG          ulCount = 0;
+    LONG           lCount;
 
     while( ulCount < ExtentsCount)
     {
 
         pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
 
-        InterlockedIncrement( &pExtent->ActiveCount);
+        lCount = InterlockedIncrement( &pExtent->ActiveCount);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_ACTIVE_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSReferenceActiveExtents Increment count on extent %08lX Cnt %d\n",
                       pExtent,
-                      pExtent->ActiveCount);
+                      lCount);
 
         pExtent = pNextExtent;
 
@@ -3958,21 +4055,22 @@ AFSDereferenceActiveExtents( IN AFSExtent *StartExtent,
     AFSExtent     *pExtent = StartExtent;
     AFSExtent     *pNextExtent;
     ULONG          ulCount = 0;
+    LONG            lCount;
 
     while( ulCount < ExtentsCount)
     {
 
         pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
 
+        ASSERT( pExtent->ActiveCount > 0);
+
+        lCount = InterlockedDecrement( &pExtent->ActiveCount);
+
         AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_ACTIVE_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSDereferenceActiveExtents Decrement count on extent %08lX Cnt %d\n",
                       pExtent,
-                      pExtent->ActiveCount);
-
-        ASSERT( pExtent->ActiveCount > 0);
-
-        InterlockedDecrement( &pExtent->ActiveCount);
+                      lCount);
 
         pExtent = pNextExtent;
 
@@ -4025,6 +4123,106 @@ AFSRemoveEntryDirtyList( IN AFSFcb *Fcb,
     return;
 }
 
+ULONG
+AFSConstructCleanByteRangeList( AFSFcb * pFcb,
+                                AFSByteRange ** pByteRangeList)
+{
+
+    ULONG ulByteRangeMax;
+    ULONG ulByteRangeCount = 0;
+    AFSByteRange *ByteRangeList;
+    AFSExtent    *pExtent, *pNextExtent;
+
+    AFSAcquireShared( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock, TRUE);
+
+    ulByteRangeMax = pFcb->Specific.File.ExtentsDirtyCount + 1;
+
+    ByteRangeList = (AFSByteRange *) AFSExAllocatePoolWithTag( PagedPool,
+                                                               ulByteRangeMax * sizeof( AFSByteRange),
+                                                               AFS_BYTERANGE_TAG);
+
+    if ( ByteRangeList == NULL)
+    {
+
+        (*pByteRangeList) = NULL;
+
+        try_return( ulByteRangeCount = DWORD_MAX);
+    }
+
+    RtlZeroMemory( ByteRangeList,
+                   ulByteRangeMax * sizeof( AFSByteRange));
+
+    //
+    // The for loop populates the ByteRangeList entries with values that are
+    // the gaps in the DirtyList.  In other words, if a range is not present
+    // in the DirtyList it will be represented in the ByteRangeList array.
+    //
+
+    for ( ulByteRangeCount = 0,
+          pExtent = (AFSExtent *)pFcb->NPFcb->Specific.File.DirtyListHead;
+          ulByteRangeCount < ulByteRangeMax && pExtent != NULL;
+          pExtent = pNextExtent)
+    {
+
+        pNextExtent = (AFSExtent *)pExtent->DirtyList.fLink;
+
+        //
+        // The first time the for() is entered the ulByteRangeCount will be zero and
+        // ByteRangeList[0] FileOffset and Length will both be zero.  If the first
+        // extent is not for offset zero, the ByteRangeList[0] Length is set to the
+        // FileOffset of the Extent.
+        //
+        // Future passes through the loop behave in a similar fashion but
+        // ByteRangeList[ulByteRangeCount] FileOffset will have been set below.
+        //
+
+        if ( pExtent->FileOffset.QuadPart != ByteRangeList[ulByteRangeCount].FileOffset.QuadPart + ByteRangeList[ulByteRangeCount].Length.QuadPart)
+        {
+
+            ByteRangeList[ulByteRangeCount].Length.QuadPart =
+                pExtent->FileOffset.QuadPart - ByteRangeList[ulByteRangeCount].FileOffset.QuadPart;
+
+            ulByteRangeCount++;
+        }
+
+        //
+        // Having processed the current dirty extent, the following while loop
+        // searches for the next clean gap between dirty extents.
+        //
+
+        while ( pNextExtent && pNextExtent->FileOffset.QuadPart == pExtent->FileOffset.QuadPart + pExtent->Size)
+        {
+
+            pExtent = pNextExtent;
+
+            pNextExtent = (AFSExtent *)pExtent->DirtyList.fLink;
+        }
+
+        //
+        // Having found the next gap, the ByteRangeList[] FileOffset is set to the start of the gap.
+        // The Length is left at zero and will be assigned either when the for loop continues or
+        // when the for loop exits.
+        //
+
+        ByteRangeList[ulByteRangeCount].FileOffset.QuadPart = pExtent->FileOffset.QuadPart + pExtent->Size;
+    }
+
+    //
+    // Assign the Length of the final clean range to match the file length.
+    //
+
+    ByteRangeList[ulByteRangeCount].Length.QuadPart =
+        pFcb->ObjectInformation->EndOfFile.QuadPart - ByteRangeList[ulByteRangeCount].FileOffset.QuadPart;
+
+    (*pByteRangeList) = ByteRangeList;
+
+  try_exit:
+
+    AFSReleaseResource( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
+
+    return ulByteRangeCount;
+}
+
 #if GEN_MD5
 void
 AFSSetupMD5Hash( IN AFSFcb *Fcb,
@@ -4058,128 +4256,142 @@ AFSSetupMD5Hash( IN AFSFcb *Fcb,
 
         AFSAcquireShared( &Fcb->NPFcb->Specific.File.ExtentsResource, TRUE);
 
-        liByteOffset.QuadPart = ByteOffset->QuadPart;
-
-        while( ulCount < ExtentsCount)
+        __try
         {
+            liByteOffset.QuadPart = ByteOffset->QuadPart;
 
-            RtlZeroMemory( pExtent->MD5,
-                           sizeof( pExtent->MD5));
+            while( ulCount < ExtentsCount)
+            {
 
-            pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
+                RtlZeroMemory( pExtent->MD5,
+                               sizeof( pExtent->MD5));
 
-            if( liByteOffset.QuadPart == pExtent->FileOffset.QuadPart &&
-                ByteCount < pExtent->Size)
-            {
+                pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
 
-                if( pExtentBuffer == NULL)
+                if( liByteOffset.QuadPart == pExtent->FileOffset.QuadPart &&
+                    ByteCount < pExtent->Size)
                 {
 
-                    pExtentBuffer = AFSExAllocatePoolWithTag( PagedPool,
-                                                              pExtent->Size,
-                                                              AFS_GENERIC_MEMORY_9_TAG);
-
                     if( pExtentBuffer == NULL)
                     {
 
-                        break;
-                    }
-                }
+                        pExtentBuffer = AFSExAllocatePoolWithTag( PagedPool,
+                                                                  pExtent->Size,
+                                                                  AFS_GENERIC_MEMORY_9_TAG);
 
-                RtlZeroMemory( pExtentBuffer,
-                               pExtent->Size);
+                        if( pExtentBuffer == NULL)
+                        {
 
-                RtlCopyMemory( pExtentBuffer,
-                               pCurrentBuffer,
-                               ByteCount);
+                            break;
+                        }
+                    }
 
-                pMD5Buffer = (char *)pExtentBuffer;
+                    RtlZeroMemory( pExtentBuffer,
+                                   pExtent->Size);
 
-                ulCurrentLen = ByteCount;
-            }
-            else if( liByteOffset.QuadPart != pExtent->FileOffset.QuadPart)
-            {
+                    RtlCopyMemory( pExtentBuffer,
+                                   pCurrentBuffer,
+                                   ByteCount);
 
-                pExtentBuffer = AFSExAllocatePoolWithTag( PagedPool,
-                                                          pExtent->Size,
-                                                          AFS_GENERIC_MEMORY_10_TAG);
+                    pMD5Buffer = (char *)pExtentBuffer;
 
-                if( pExtentBuffer == NULL)
+                    ulCurrentLen = ByteCount;
+                }
+                else if( liByteOffset.QuadPart != pExtent->FileOffset.QuadPart)
                 {
 
-                    break;
-                }
+                    pExtentBuffer = AFSExAllocatePoolWithTag( PagedPool,
+                                                              pExtent->Size,
+                                                              AFS_GENERIC_MEMORY_10_TAG);
 
-                RtlZeroMemory( pExtentBuffer,
-                               pExtent->Size);
+                    if( pExtentBuffer == NULL)
+                    {
 
-                if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
-                {
+                        break;
+                    }
 
-#ifdef AMD64
-                    RtlCopyMemory( pExtentBuffer,
-                                   ((char *)AFSLibCacheBaseAddress + pExtent->CacheOffset.QuadPart),
+                    RtlZeroMemory( pExtentBuffer,
                                    pExtent->Size);
+
+                    if( BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE))
+                    {
+
+#ifdef AMD64
+                        RtlCopyMemory( pExtentBuffer,
+                                       ((char *)AFSLibCacheBaseAddress + pExtent->CacheOffset.QuadPart),
+                                       pExtent->Size);
 #else
-                    ASSERT( pExtent->CacheOffset.HighPart == 0);
-                    RtlCopyMemory( pExtentBuffer,
-                                   ((char *)AFSLibCacheBaseAddress + pExtent->CacheOffset.LowPart),
-                                   pExtent->Size);
+                        ASSERT( pExtent->CacheOffset.HighPart == 0);
+                        RtlCopyMemory( pExtentBuffer,
+                                       ((char *)AFSLibCacheBaseAddress + pExtent->CacheOffset.LowPart),
+                                       pExtent->Size);
 #endif
 
-                    ulBytesRead = pExtent->Size;
+                        ulBytesRead = pExtent->Size;
+                    }
+                    else
+                    {
+
+                        ntStatus = AFSReadCacheFile( pExtentBuffer,
+                                                     &pExtent->CacheOffset,
+                                                     pExtent->Size,
+                                                     &ulBytesRead);
+
+                        if( !NT_SUCCESS( ntStatus))
+                        {
+
+                            break;
+                        }
+                    }
+
+                    pMD5Buffer = (char *)pExtentBuffer;
+
+                    ulCurrentLen = min( ByteCount, pExtent->Size - (ULONG)(liByteOffset.QuadPart - pExtent->FileOffset.QuadPart));
+
+                    RtlCopyMemory( (void *)((char *)pExtentBuffer + (ULONG)(liByteOffset.QuadPart - pExtent->FileOffset.QuadPart)),
+                                   pCurrentBuffer,
+                                   ulCurrentLen);
                 }
                 else
                 {
 
-                    ntStatus = AFSReadCacheFile( pExtentBuffer,
-                                                 &pExtent->CacheOffset,
-                                                 pExtent->Size,
-                                                 &ulBytesRead);
+                    ulCurrentLen = pExtent->Size;
 
-                    if( !NT_SUCCESS( ntStatus))
-                    {
-                        break;
-                    }
+                    pMD5Buffer = pCurrentBuffer;
                 }
 
-                pMD5Buffer = (char *)pExtentBuffer;
+                AFSGenerateMD5( pMD5Buffer,
+                                pExtent->Size,
+                                pExtent->MD5);
 
-                ulCurrentLen = min( ByteCount, pExtent->Size - (ULONG)(liByteOffset.QuadPart - pExtent->FileOffset.QuadPart));
-
-                RtlCopyMemory( (void *)((char *)pExtentBuffer + (ULONG)(liByteOffset.QuadPart - pExtent->FileOffset.QuadPart)),
-                               pCurrentBuffer,
-                               ulCurrentLen);
-            }
-            else
-            {
+                pExtent = pNextExtent;
 
-                ulCurrentLen = pExtent->Size;
+                ulCount++;
 
-                pMD5Buffer = pCurrentBuffer;
-            }
+                ByteCount -= ulCurrentLen;
 
-            AFSGenerateMD5( pMD5Buffer,
-                            pExtent->Size,
-                            pExtent->MD5);
+                pCurrentBuffer += ulCurrentLen;
 
-            pExtent = pNextExtent;
+                liByteOffset.QuadPart += ulCurrentLen;
+            }
 
-            ulCount++;
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSSetupMD5Hash Releasing Fcb extents lock %08lX SHARED %08lX\n",
+                          &Fcb->NPFcb->Specific.File.ExtentsResource,
+                          PsGetCurrentThread());
 
-            ByteCount -= ulCurrentLen;
+        }
+        __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+        {
 
-            pCurrentBuffer += ulCurrentLen;
+            AFSDbgLogMsg( 0,
+                          0,
+                          "EXCEPTION - AFSSetupMD5Hash\n");
 
-            liByteOffset.QuadPart += ulCurrentLen;
+            AFSDumpTraceFilesFnc();
         }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSSetupMD5Hash Releasing Fcb extents lock %08lX SHARED %08lX\n",
-                      &Fcb->NPFcb->Specific.File.ExtentsResource,
-                      PsGetCurrentThread());
-
         AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
 
         if( pExtentBuffer != NULL)