Windows: shuffle trace messages for clarity
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSExtentsSupport.cpp
index f2b41c5..a5c8a73 100644 (file)
@@ -39,7 +39,6 @@
 
 #define AFS_MAX_FCBS_TO_DROP 10
 
-static AFSExtent *NextExtent( AFSExtent *Extent, ULONG SkipList );
 static ULONG ExtentsMasks[AFS_NUM_EXTENT_LISTS] = AFS_EXTENTS_MASKS;
 static VOID VerifyExtentsLists(AFSFcb *Fcb);
 static AFSExtent *DirtyExtentFor(PLIST_ENTRY le);
@@ -56,16 +55,14 @@ AFSEntryForOffset( IN AFSFcb *Fcb,
 VOID
 AFSLockForExtentsTrim( IN AFSFcb *Fcb)
 {
-    NTSTATUS          ntStatus;
-    AFSNonPagedFcb *pNPFcb = Fcb->NPFcb;
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSLockForExtentsTrim Acquiring Fcb extents lock %08lX EXCL %08lX\n",
-                  &pNPFcb->Specific.File.ExtentsResource,
+                  &Fcb->NPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
-    AFSAcquireExcl( &pNPFcb->Specific.File.ExtentsResource, TRUE );
+    AFSAcquireExcl( &Fcb->NPFcb->Specific.File.ExtentsResource, TRUE );
 
     return;
 }
@@ -76,15 +73,14 @@ AFSLockForExtentsTrim( IN AFSFcb *Fcb)
 BOOLEAN
 AFSLockForExtentsTrimNoWait( IN AFSFcb *Fcb)
 {
-    AFSNonPagedFcb *pNPFcb = Fcb->NPFcb;
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
                   "AFSLockForExtentsTrimNoWait Attempting to acquire Fcb extent lock %08lX EXCL %08lX\n",
-                  &pNPFcb->Specific.File.ExtentsResource,
+                  &Fcb->NPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
-    if (!AFSAcquireExcl( &pNPFcb->Specific.File.ExtentsResource, FALSE ))
+    if (!AFSAcquireExcl( &Fcb->NPFcb->Specific.File.ExtentsResource, FALSE ))
     {
         //
         // Couldn't lock immediately
@@ -93,7 +89,7 @@ AFSLockForExtentsTrimNoWait( IN AFSFcb *Fcb)
         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSLockForExtentsTrimNoWait Refused to wait for Fcb extent lock %08lX EXCL %08lX\n",
-                      &pNPFcb->Specific.File.ExtentsResource,
+                      &Fcb->NPFcb->Specific.File.ExtentsResource,
                       PsGetCurrentThread());
 
         return FALSE;
@@ -101,18 +97,62 @@ AFSLockForExtentsTrimNoWait( IN AFSFcb *Fcb)
 
     return TRUE;
 }
+
+static VOID
+AFSFreeExtent( IN AFSFcb *Fcb,
+               IN AFSExtent *pExtent)
+{
+    AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    LONG                 lCount;
+
+    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)));
+
+    lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+
+    lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+
+    if( lCount == 0)
+    {
+
+        KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
+                    0,
+                    FALSE);
+    }
+
+    AFSExFreePoolWithTag( pExtent, AFS_EXTENT_TAG);
+}
+
 //
-// Pull all the extents away from the FCB.
+// AFSTearDownFcbExtents was originally written to
+// remove all of the extents from an FCB.  For that to happen
+// it must be an invariant that the extent list cannot change
+// from the moment the caller decides to execute AFSTearDownFcbExtents
+// until it returns.  This invariant does not hold because the
+// the decision to call AFSTearDownFcbExtents is made without
+// holding the ExtentsResource and it is possible that extents
+// are in active use. Therefore, AFSTearDownFcbExtents now releases
+// as many non-active extents as it can.
 //
-BOOLEAN
+VOID
 AFSTearDownFcbExtents( IN AFSFcb *Fcb,
                        IN GUID *AuthGroup)
 {
-    BOOLEAN             bFoundExtents = FALSE;
     AFSNonPagedFcb      *pNPFcb = Fcb->NPFcb;
-    LIST_ENTRY          *le;
+    LIST_ENTRY          *le, *leNext;
     AFSExtent           *pEntry;
-    ULONG                ulCount = 0, ulReleaseCount = 0, ulProcessCount = 0;
+    LONG                 lExtentCount = 0, lProcessCount = 0;
+    LONG                 lFcbExtentCount;
+    ULONG                ulReleaseCount = 0;
     size_t               sz;
     AFSReleaseExtentsCB *pRelease = NULL;
     BOOLEAN              locked = FALSE;
@@ -161,10 +201,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,
@@ -176,63 +212,44 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb,
             try_return ( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
         }
 
-        le = Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
-
-        ulCount = Fcb->Specific.File.ExtentCount;
+        AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
+                        TRUE);
 
-        while( ulReleaseCount < ulCount)
+        for( le = Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink,
+             lExtentCount = 0,
+             lFcbExtentCount = Fcb->Specific.File.ExtentCount;
+             lExtentCount < lFcbExtentCount;
+             lExtentCount += lProcessCount)
         {
 
-            bFoundExtents = TRUE;
-
             RtlZeroMemory( pRelease,
                            sizeof( AFSReleaseExtentsCB ) +
                            (AFS_MAXIMUM_EXTENT_RELEASE_COUNT * sizeof ( AFSFileExtentCB )));
 
-            if( ulCount - ulReleaseCount <= AFS_MAXIMUM_EXTENT_RELEASE_COUNT)
-            {
-                ulProcessCount = ulCount - ulReleaseCount;
-            }
-            else
+            for( lProcessCount = 0, ulReleaseCount = 0;
+                 !IsListEmpty( le) &&
+                 ulReleaseCount < AFS_MAXIMUM_EXTENT_RELEASE_COUNT &&
+                 lExtentCount + lProcessCount < lFcbExtentCount;
+                 lProcessCount++, le = leNext)
             {
-                ulProcessCount = AFS_MAXIMUM_EXTENT_RELEASE_COUNT;
-            }
-
-            pRelease->Flags = AFS_EXTENT_FLAG_RELEASE;
-            pRelease->ExtentCount = ulProcessCount;
 
-            //
-            // Update the metadata for this call
-            //
+                leNext = le->Flink;
 
-            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;
-
-            ulProcessCount = 0;
-
-            while (ulProcessCount < pRelease->ExtentCount)
-            {
                 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
 
-                pRelease->FileExtents[ulProcessCount].Flags = AFS_EXTENT_FLAG_RELEASE;
+                if( pEntry->ActiveCount == 0)
+                {
+
+                    pRelease->FileExtents[ulReleaseCount].Flags = AFS_EXTENT_FLAG_RELEASE;
 
 #if GEN_MD5
-                RtlCopyMemory( pRelease->FileExtents[ulProcessCount].MD5,
-                               pEntry->MD5,
-                               sizeof(pEntry->MD5));
+                    RtlCopyMemory( pRelease->FileExtents[ulReleaseCount].MD5,
+                                   pEntry->MD5,
+                                   sizeof(pEntry->MD5));
 
-                pRelease->FileExtents[ulProcessCount].Flags |= AFS_EXTENT_FLAG_MD5_SET;
+                    pRelease->FileExtents[ulReleaseCount].Flags |= AFS_EXTENT_FLAG_MD5_SET;
 #endif
 
-                if( BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
-                {
-
-                    AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
-                                    TRUE);
-
                     if( BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
                     {
 
@@ -241,122 +258,261 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb,
                         AFSRemoveEntryDirtyList( Fcb,
                                                  pEntry);
 
-                        pRelease->FileExtents[ulProcessCount].Flags |= AFS_EXTENT_FLAG_DIRTY;
+                        pRelease->FileExtents[ulReleaseCount].Flags |= AFS_EXTENT_FLAG_DIRTY;
 
                         dirtyCount = InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
 
                         ASSERT( dirtyCount >= 0);
                     }
 
-                    AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+                    AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
+                                  AFS_TRACE_LEVEL_VERBOSE,
+                                  "AFSTearDownFcbExtents Releasing extent %p fid %08lX-%08lX-%08lX-%08lX Offset %08lX-%08lX Len %08lX\n",
+                                  pEntry,
+                                  Fcb->ObjectInformation->FileId.Cell,
+                                  Fcb->ObjectInformation->FileId.Volume,
+                                  Fcb->ObjectInformation->FileId.Vnode,
+                                  Fcb->ObjectInformation->FileId.Unique,
+                                  pEntry->FileOffset.HighPart,
+                                  pEntry->FileOffset.LowPart,
+                                  pEntry->Size);
+
+                    pRelease->FileExtents[ulReleaseCount].Length = pEntry->Size;
+                    pRelease->FileExtents[ulReleaseCount].DirtyLength = pEntry->Size;
+                    pRelease->FileExtents[ulReleaseCount].DirtyOffset = 0;
+                    pRelease->FileExtents[ulReleaseCount].CacheOffset = pEntry->CacheOffset;
+                    pRelease->FileExtents[ulReleaseCount].FileOffset = pEntry->FileOffset;
+
+                    ulReleaseCount++;
+
+                    AFSFreeExtent( Fcb,
+                                   pEntry);
                 }
+            }
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSTearDownFcbExtents Releasing extent %p fid %08lX-%08lX-%08lX-%08lX Offset %08lX-%08lX Len %08lX\n",
-                              pEntry,
-                              Fcb->ObjectInformation->FileId.Cell,
-                              Fcb->ObjectInformation->FileId.Volume,
-                              Fcb->ObjectInformation->FileId.Vnode,
-                              Fcb->ObjectInformation->FileId.Unique,
-                              pEntry->FileOffset.HighPart,
-                              pEntry->FileOffset.LowPart,
-                              pEntry->Size);
+            if ( ulReleaseCount > 0)
+            {
 
-                pRelease->FileExtents[ulProcessCount].Length = pEntry->Size;
-                pRelease->FileExtents[ulProcessCount].DirtyLength = pEntry->Size;
-                pRelease->FileExtents[ulProcessCount].DirtyOffset = 0;
-                pRelease->FileExtents[ulProcessCount].CacheOffset = pEntry->CacheOffset;
-                pRelease->FileExtents[ulProcessCount].FileOffset = pEntry->FileOffset;
+                pRelease->ExtentCount = ulReleaseCount;
 
-                InterlockedExchangeAdd( &pControlDevExt->Specific.Control.ExtentsHeldLength, -((LONG)(pEntry->Size/1024)));
+                pRelease->Flags = AFS_EXTENT_FLAG_RELEASE;
 
-                InterlockedExchangeAdd( &Fcb->Specific.File.ExtentLength, -((LONG)(pEntry->Size/1024)));
+                //
+                // Update the metadata for this call
+                //
 
-                ASSERT( pEntry->ActiveCount == 0);
+                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;
 
-                ulProcessCount ++;
-                le = le->Flink;
-                AFSExFreePool( pEntry);
+                //
+                // Send the request down.  We cannot send this down
+                // asynchronously - if we did that we could request them
+                // back before the service got this request and then this
+                // request would be a corruption.
+                //
 
-                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
+                sz = sizeof( AFSReleaseExtentsCB ) + (lProcessCount * sizeof ( AFSFileExtentCB ));
 
-                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
+                ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS,
+                                              AFS_REQUEST_FLAG_SYNCHRONOUS,
+                                              pAuthGroup,
+                                              NULL,
+                                              &Fcb->ObjectInformation->FileId,
+                                              pRelease,
+                                              sz,
+                                              NULL,
+                                              NULL);
 
-                if( lCount == 0)
+                if( !NT_SUCCESS(ntStatus))
                 {
 
-                    KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
-                                0,
-                                FALSE);
+                    //
+                    // 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,
+                                  "AFSTearDownFcbExtents 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);
+
                 }
             }
+        }
+
+        AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+
+        //
+        // if all extents have been released, reinitialize the skip lists
+        //
+
+        if( Fcb->Specific.File.ExtentCount == 0)
+        {
+
+            for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
+            {
+                InitializeListHead(&Fcb->Specific.File.ExtentsLists[i]);
+            }
 
             //
-            // Send the request down.  We cannot send this down
-            // asynchronously - if we did that we could request them
-            // back before the service got this request and then this
-            // request would be a corruption.
+            // Reinitialize the dirty list as well
             //
 
-            sz = sizeof( AFSReleaseExtentsCB ) + (ulProcessCount * sizeof ( AFSFileExtentCB ));
+            AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
+                            TRUE);
 
-            ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS,
-                                          AFS_REQUEST_FLAG_SYNCHRONOUS,
-                                          pAuthGroup,
-                                          NULL,
-                                          &Fcb->ObjectInformation->FileId,
-                                          pRelease,
-                                          sz,
-                                          NULL,
-                                          NULL);
+            ASSERT( Fcb->Specific.File.ExtentsDirtyCount == 0);
 
-            if( !NT_SUCCESS(ntStatus))
+            Fcb->NPFcb->Specific.File.DirtyListHead = NULL;
+            Fcb->NPFcb->Specific.File.DirtyListTail = NULL;
+
+            AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+        }
+
+        Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
+
+try_exit:
+
+        if (locked)
+        {
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSTearDownFcbExtents Releasing Fcb extent lock %08lX thread %08lX\n",
+                          &Fcb->NPFcb->Specific.File.ExtentsResource,
+                          PsGetCurrentThread());
+
+            AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
+        }
+
+        if (pRelease)
+        {
+
+            AFSExFreePoolWithTag( pRelease, AFS_EXTENT_RELEASE_TAG);
+        }
+    }
+}
+
+VOID
+AFSDeleteFcbExtents( IN AFSFcb *Fcb)
+{
+    AFSNonPagedFcb      *pNPFcb = Fcb->NPFcb;
+    LIST_ENTRY          *le, *leNext;
+    AFSExtent           *pEntry;
+    LONG                 lExtentCount = 0, lProcessCount = 0;
+    LONG                 lFcbExtentCount;
+    size_t               sz;
+    BOOLEAN              locked = FALSE;
+    NTSTATUS             ntStatus;
+    AFSDeviceExt        *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
+    LONG                 lCount;
+
+    __Enter
+    {
+
+        //
+        // Ensure that no one is working with the extents and grab the
+        // lock
+        //
+
+        AFSLockForExtentsTrim( Fcb );
+
+        locked = TRUE;
+
+        if (0 == Fcb->Specific.File.ExtentCount)
+        {
+            try_return ( ntStatus = STATUS_SUCCESS);
+        }
+
+        sz = sizeof( AFSReleaseExtentsCB ) + (AFS_MAXIMUM_EXTENT_RELEASE_COUNT * sizeof ( AFSFileExtentCB ));
+
+        AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
+                        TRUE);
+
+        for( le = Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink,
+             lExtentCount = 0,
+             lFcbExtentCount = Fcb->Specific.File.ExtentCount;
+             lExtentCount < lFcbExtentCount;
+             lExtentCount += lProcessCount)
+        {
+
+            for( lProcessCount = 0;
+                 !IsListEmpty( le) &&
+                 lExtentCount + lProcessCount < lFcbExtentCount;
+                 lProcessCount++, le = leNext)
             {
 
-                //
-                // 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.
-                //
+                leNext = le->Flink;
+
+                pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+                if( BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+                {
+
+                    LONG dirtyCount;
+
+                    AFSRemoveEntryDirtyList( Fcb,
+                                             pEntry);
+
+                    dirtyCount = InterlockedDecrement( &Fcb->Specific.File.ExtentsDirtyCount);
+
+                    ASSERT( dirtyCount >= 0);
+                }
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
-                              AFS_TRACE_LEVEL_ERROR,
-                              "AFSTearDownFcbExtents AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS failed fid %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSDeleteFcbExtents Deleting extent %p fid %08lX-%08lX-%08lX-%08lX Offset %08lX-%08lX Len %08lX\n",
+                              pEntry,
                               Fcb->ObjectInformation->FileId.Cell,
                               Fcb->ObjectInformation->FileId.Volume,
                               Fcb->ObjectInformation->FileId.Vnode,
                               Fcb->ObjectInformation->FileId.Unique,
-                              ntStatus);
+                              pEntry->FileOffset.HighPart,
+                              pEntry->FileOffset.LowPart,
+                              pEntry->Size);
 
+                AFSFreeExtent( Fcb,
+                               pEntry);
             }
-
-            ulReleaseCount += ulProcessCount;
         }
 
+        AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+
         //
-        // Reinitialize the skip lists
+        // if all extents have been released, reinitialize the skip lists
         //
 
         ASSERT( Fcb->Specific.File.ExtentCount == 0);
 
-        for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
+        if( Fcb->Specific.File.ExtentCount == 0)
         {
-            InitializeListHead(&Fcb->Specific.File.ExtentsLists[i]);
-        }
 
-        //
-        // Reinitialize the dirty list as well
-        //
+            for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
+            {
+                InitializeListHead(&Fcb->Specific.File.ExtentsLists[i]);
+            }
 
-        AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
-                        TRUE);
+            //
+            // Reinitialize the dirty list as well
+            //
 
-        ASSERT( Fcb->Specific.File.ExtentsDirtyCount == 0);
+            AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
+                            TRUE);
 
-        Fcb->NPFcb->Specific.File.DirtyListHead = NULL;
-        Fcb->NPFcb->Specific.File.DirtyListTail = NULL;
+            ASSERT( Fcb->Specific.File.ExtentsDirtyCount == 0);
 
-        AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+            Fcb->NPFcb->Specific.File.DirtyListHead = NULL;
+            Fcb->NPFcb->Specific.File.DirtyListTail = NULL;
+
+            AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
+        }
 
         Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
 
@@ -367,23 +523,16 @@ try_exit:
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSTearDownFcbExtents Releasing Fcb extent lock %08lX thread %08lX\n",
+                          "AFSDeleteFcbExtents Releasing Fcb extent lock %08lX thread %08lX\n",
                           &Fcb->NPFcb->Specific.File.ExtentsResource,
                           PsGetCurrentThread());
 
             AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
         }
-
-        if (pRelease)
-        {
-
-            AFSExFreePool( pRelease);
-        }
     }
-
-    return bFoundExtents;
 }
 
+
 static PAFSExtent
 ExtentForOffsetInList( IN AFSFcb *Fcb,
                        IN LIST_ENTRY *List,
@@ -615,66 +764,64 @@ BOOLEAN AFSDoExtentsMapRegion(IN AFSFcb *Fcb,
     __Enter
     {
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSDoExtentsMapRegion Acquiring Fcb extent lock %08lX SHARED %08lX\n",
-                      &Fcb->NPFcb->Specific.File.ExtentsResource,
-                      PsGetCurrentThread());
-
-        AFSAcquireShared( &Fcb->NPFcb->Specific.File.ExtentsResource, TRUE );
+        ASSERT( ExIsResourceAcquiredLite( &Fcb->NPFcb->Specific.File.ExtentsResource ));
 
-        entry = AFSExtentForOffsetHint(Fcb, Offset, TRUE, *FirstExtent);
-        *FirstExtent = entry;
-
-        if (NULL == entry || !AFSExtentContains(entry, Offset))
+        __try
         {
-            try_return (retVal = FALSE);
-        }
+            entry = AFSExtentForOffsetHint(Fcb, Offset, TRUE, *FirstExtent);
+            *FirstExtent = entry;
 
-        ASSERT(Offset->QuadPart >= entry->FileOffset.QuadPart);
-
-        while (TRUE)
-        {
-            if ((entry->FileOffset.QuadPart + entry->Size) >=
-                                                (Offset->QuadPart + Size))
+            if (NULL == entry || !AFSExtentContains(entry, Offset))
             {
-                //
-                // 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 );
+            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;
+                entry = newEntry;
+            }
         }
+        __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+        {
 
-try_exit:
+            AFSDbgLogMsg( 0,
+                          0,
+                          "EXCEPTION - AFSDoExtentsMapRegion\n");
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSDoExtentsMapRegion Releasing Fcb extent lock %08lX SHARED %08lX\n",
-                      &Fcb->NPFcb->Specific.File.ExtentsResource,
-                      PsGetCurrentThread());
+            AFSDumpTraceFilesFnc();
+        }
 
-        AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
+try_exit:
 
         *LastExtent = entry;
     }
@@ -738,11 +885,33 @@ AFSRequestExtentsAsync( IN AFSFcb *Fcb,
         // Check if we are already mapped
         //
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRequestExtentsAsync Acquiring Fcb extents lock %08lX SHARED %08lX\n",
+                      &pNPFcb->Specific.File.ExtentsResource,
+                      PsGetCurrentThread());
+
+        AFSAcquireShared( &pNPFcb->Specific.File.ExtentsResource, TRUE );
+
         bRegionMapped = AFSDoExtentsMapRegion( Fcb, Offset, Size, &pFirstExtent, &pExtent);
 
         if( bRegionMapped)
         {
 
+            KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
+        }
+
+        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSRequestExtentsAsync Releasing Fcb extents lock %08lX SHARED %08lX\n",
+                      &pNPFcb->Specific.File.ExtentsResource,
+                      PsGetCurrentThread());
+
+        AFSReleaseResource( &pNPFcb->Specific.File.ExtentsResource );
+
+        if ( bRegionMapped)
+        {
+
             try_return( ntStatus = STATUS_SUCCESS);
         }
 
@@ -779,6 +948,8 @@ AFSRequestExtentsAsync( IN AFSFcb *Fcb,
                                        request.Length))
         {
 
+            KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
+
             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",
@@ -828,17 +999,14 @@ AFSRequestExtentsAsync( IN AFSFcb *Fcb,
                 }
             }
 
-            if( NT_SUCCESS( ntStatus))
+            if( !NT_SUCCESS( ntStatus))
             {
 
-                KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
+                KeSetEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
+                            0,
+                            FALSE);
             }
         }
-        else
-        {
-
-            KeClearEvent( &pNPFcb->Specific.File.ExtentsRequestComplete );
-        }
 
 try_exit:
 
@@ -1014,8 +1182,6 @@ AFSProcessExtentsResult( IN AFSFcb *Fcb,
                 if (NULL  == pExtent)
                 {
 
-                    ASSERT( FALSE);
-
                     try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
                 }
 
@@ -1166,29 +1332,6 @@ AFSProcessExtentsResult( IN AFSFcb *Fcb,
                 //
                 le = &pExtent->Lists[AFS_EXTENTS_LIST];
 
-                /*
-                //
-                // Then the check the skip lists cursors
-                //
-                for (ULONG i = AFS_NUM_EXTENT_LISTS-1; i > AFS_EXTENTS_LIST; i--)
-                {
-                    if (0 == (pFileExtents->FileOffset.LowPart & ExtentsMasks[i]))
-                    {
-                        //
-                        // Three options:
-                        //    - empty list (pSkipEntries[i]->Flink == pSkipEntries[i]->Flink == fcb->lists[i]
-                        //    - We are the last on the list (pSkipEntries[i]->Flink == fcb->lists[i])
-                        //    - We are not the last on the list.  In that case we have to be strictly less than
-                        //      that extent.
-                        if (pSkipEntries[i]->Flink != &Fcb->Specific.File.ExtentsLists[i]) {
-
-                            AFSExtent *otherExtent = ExtentFor(pSkipEntries[i]->Flink, i);
-                            ASSERT(pFileExtents->FileOffset.QuadPart < otherExtent->FileOffset.QuadPart);
-                        }
-                    }
-                }
-                */
-
                 //
                 // setup pExtent if there is one
                 //
@@ -1286,13 +1429,13 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
         if( pVolumeCB != NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSProcessSetFileExtents Acquiring VolumeRoot FileIDTree.TreeLock lock %08lX SHARED %08lX\n",
-                          pVolumeCB->ObjectInfoTree.TreeLock,
-                          PsGetCurrentThread());
-
             lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSProcessSetFileExtents Increment count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
         }
 
         AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -1316,8 +1459,6 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
         //
         // Now locate the Object in this volume
         //
@@ -1335,7 +1476,7 @@ AFSProcessSetFileExtents( IN AFSSetFileExtentsCB *SetExtents )
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1416,7 +1557,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -1424,6 +1565,18 @@ try_exit:
                           pObjectInfo,
                           lCount);
         }
+
+        if ( pVolumeCB)
+        {
+
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSProcessSetFileExtents Decrement count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
+        }
     }
 
     return ntStatus;
@@ -1640,37 +1793,8 @@ AFSReleaseSpecifiedExtents( IN  AFSReleaseFileExtentsCB *Extents,
             ulExtentCount ++;
             *ExtentCount = (*ExtentCount) + 1;
 
-            //
-            // And unpick
-            //
-            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)));
-
-            //
-            // and free
-            //
-            AFSExFreePool( pExtent);
-
-            lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
-
-            lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
-
-            if( lCount == 0)
-            {
-
-                KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
-                            0,
-                            FALSE);
-            }
+            AFSFreeExtent( Fcb,
+                           pExtent);
         }
 
 try_exit:
@@ -1717,23 +1841,35 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
         // The Volume list may move under our feet.  Lock it.
         //
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSFindFcbToClean Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
-                      pVolumeCB->ObjectInfoTree.TreeLock,
-                      PsGetCurrentThread());
-
         lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSFindFcbToClean Increment count on volume %08lX Cnt %d\n",
+                      pVolumeCB,
+                      lCount);
+
         AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
 
         bReleaseVolumeListLock = FALSE;
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSFindFcbToClean Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
+                      pVolumeCB->ObjectInfoTree.TreeLock,
+                      PsGetCurrentThread());
+
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
         lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSFindFcbToClean Decrement count on volume %08lX Cnt %d\n",
+                      pVolumeCB,
+                      lCount);
+
         if( NULL == LastFcb)
         {
 
@@ -1850,7 +1986,7 @@ AFSFindFcbToClean(ULONG IgnoreTime, AFSFcb *LastFcb, BOOLEAN Block)
                 // A hit a very palpable hit.  Pin it
                 //
 
-                lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pCurrentObject);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -1942,13 +2078,13 @@ AFSProcessExtentFailure( PIRP Irp)
         if( pVolumeCB != NULL)
         {
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSProcessExtentFailure Acquiring VolumeRoot FileIDTree.TreeLock lock %08lX SHARED %08lX\n",
-                          pVolumeCB->ObjectInfoTree.TreeLock,
-                          PsGetCurrentThread());
-
             lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSProcessExtentFailure Increment count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
         }
 
         AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -1965,11 +2101,15 @@ AFSProcessExtentFailure( PIRP Irp)
             try_return( ntStatus = STATUS_UNSUCCESSFUL);
         }
 
+        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                      AFS_TRACE_LEVEL_VERBOSE,
+                      "AFSProcessExtentFailure Acquiring VolumeRoot FileIDTree.TreeLock lock %08lX SHARED %08lX\n",
+                      pVolumeCB->ObjectInfoTree.TreeLock,
+                      PsGetCurrentThread());
+
         AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                           TRUE);
 
-        lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
         //
         // Now locate the Object in this volume
         //
@@ -1988,7 +2128,7 @@ AFSProcessExtentFailure( PIRP Irp)
             // Reference the node so it won't be torn down
             //
 
-            lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoIncrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2049,7 +2189,7 @@ AFSProcessExtentFailure( PIRP Irp)
 
         AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
 
-        lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+        lCount = AFSObjectInfoDecrement( pObjectInfo);
 
         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                       AFS_TRACE_LEVEL_VERBOSE,
@@ -2059,7 +2199,17 @@ AFSProcessExtentFailure( PIRP Irp)
 
 try_exit:
 
-        NOTHING;
+        if ( pVolumeCB)
+        {
+
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSProcessExtentFailure Decrement count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
+        }
     }
 
     return ntStatus;
@@ -2181,13 +2331,13 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
             if( pVolumeCB != NULL)
             {
 
-                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
-                              AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSProcessReleaseFileExtents Acquiring VolumeRoot FileIDTree.TreeLock lock %08lX SHARED %08lX\n",
-                              pVolumeCB->ObjectInfoTree.TreeLock,
-                              PsGetCurrentThread());
-
                 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
+
+                AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                              AFS_TRACE_LEVEL_VERBOSE,
+                              "AFSProcessReleaseFileExtents Increment count on volume %08lX Cnt %d\n",
+                              pVolumeCB,
+                              lCount);
             }
 
             AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
@@ -2204,11 +2354,15 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
                 try_return( ntStatus = STATUS_UNSUCCESSFUL);
             }
 
+            AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSProcessReleaseFileExtents Acquiring VolumeRoot FileIDTree.TreeLock lock %08lX SHARED %08lX\n",
+                          pVolumeCB->ObjectInfoTree.TreeLock,
+                          PsGetCurrentThread());
+
             AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
                               TRUE);
 
-            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
-
             //
             // Now locate the Object in this volume
             //
@@ -2226,7 +2380,7 @@ AFSProcessReleaseFileExtents( IN PIRP Irp)
                 // Reference the node so it won't be torn down
                 //
 
-                lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
+                lCount = AFSObjectInfoIncrement( pObjectInfo);
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                               AFS_TRACE_LEVEL_VERBOSE,
@@ -2434,7 +2588,7 @@ try_exit:
             Irp->AssociatedIrp.SystemBuffer != pResult)
         {
 
-            AFSExFreePool(pResult);
+            AFSExFreePoolWithTag(pResult, AFS_EXTENTS_RESULT_TAG);
         }
 
         if (NT_SUCCESS(ntStatus))
@@ -2451,7 +2605,7 @@ try_exit:
         if( pObjectInfo != NULL)
         {
 
-            lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
+            lCount = AFSObjectInfoDecrement( pObjectInfo);
 
             AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                           AFS_TRACE_LEVEL_VERBOSE,
@@ -2459,6 +2613,19 @@ try_exit:
                           pObjectInfo,
                           lCount);
         }
+
+        if ( pVolumeCB)
+        {
+
+            lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
+
+            AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSProcessReleaseFileExtents Decrement count on volume %08lX Cnt %d\n",
+                          pVolumeCB,
+                          lCount);
+
+        }
     }
 
     return ntStatus;
@@ -2583,6 +2750,8 @@ AFSFlushExtents( IN AFSFcb *Fcb,
     __Enter
     {
 
+        lCount = InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
+
         if( pAuthGroup == NULL ||
             RtlCompareMemory( pAuthGroup,
                               &Fcb->NPFcb->Specific.File.ExtentsRequestAuthGroup,
@@ -2614,8 +2783,6 @@ AFSFlushExtents( IN AFSFcb *Fcb,
 
         bExtentsLocked = TRUE;
 
-        lCount = InterlockedIncrement( &Fcb->Specific.File.QueuedFlushCount);
-
         //
         // Clear our queued flush event
         //
@@ -2731,35 +2898,8 @@ AFSFlushExtents( IN AFSFcb *Fcb,
 
                 pRelease->FileExtents[count].Flags |= AFS_EXTENT_FLAG_RELEASE;
 
-                //
-                // 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);
-                }
+                AFSFreeExtent( Fcb,
+                               pExtent);
 
                 count ++;
 
@@ -2831,6 +2971,7 @@ AFSFlushExtents( IN AFSFcb *Fcb,
                               ntStatus);
 
             }
+
             AFSLockForExtentsTrim( Fcb);
 
             bExtentsLocked = TRUE;
@@ -2840,6 +2981,8 @@ try_exit:
 
         lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
 
+       ASSERT( lCount >= 0);
+
         if( lCount == 0)
         {
 
@@ -2866,7 +3009,7 @@ try_exit:
 
         if (pRelease)
         {
-            AFSExFreePool( pRelease);
+            AFSExFreePoolWithTag( pRelease, AFS_EXTENT_RELEASE_TAG);
         }
     }
 
@@ -2875,7 +3018,8 @@ try_exit:
 
 NTSTATUS
 AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
-                            IN GUID *AuthGroup)
+                            IN GUID *AuthGroup,
+                            IN BOOLEAN bReleaseAll)
 {
     AFSNonPagedFcb      *pNPFcb = Fcb->NPFcb;
     AFSExtent           *pExtent;
@@ -2946,18 +3090,15 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
             try_return ( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
         }
 
-        if( Fcb->OpenHandleCount > 0)
+        if( Fcb->OpenHandleCount > 0 &&
+            !bReleaseAll)
         {
 
             //
             // Don't release everything ...
             //
 
-            //
-            // For now release everything
-            //
-
-            //ulRemainingExtentLength = 1500;
+            ulRemainingExtentLength = 1024;
         }
 
         while( Fcb->Specific.File.ExtentLength > (LONG)ulRemainingExtentLength)
@@ -3044,35 +3185,8 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb,
                     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);
-                }
+                AFSFreeExtent( Fcb,
+                               pExtent);
 
                 count ++;
             }
@@ -3161,7 +3275,7 @@ try_exit:
 
         if (pRelease)
         {
-            AFSExFreePool( pRelease);
+            AFSExFreePoolWithTag( pRelease, AFS_EXTENT_RELEASE_TAG);
         }
     }
 
@@ -3304,33 +3418,8 @@ AFSReleaseCleanExtents( IN AFSFcb *Fcb,
                 pRelease->FileExtents[count].Flags |= AFS_EXTENT_FLAG_MD5_SET;
 #endif
 
-                //
-                // 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);
-
-                InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
-
-                if( InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount) == 0)
-                {
-
-                    KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
-                                0,
-                                FALSE);
-                }
+                AFSFreeExtent( Fcb,
+                               pExtent);
 
                 count ++;
             }
@@ -3419,7 +3508,7 @@ try_exit:
 
         if (pRelease)
         {
-            AFSExFreePool( pRelease);
+            AFSExFreePoolWithTag( pRelease, AFS_EXTENT_RELEASE_TAG);
         }
     }
 
@@ -3440,7 +3529,6 @@ AFSMarkDirty( IN AFSFcb *Fcb,
     ULONG ulCount = 0;
     BOOLEAN bInsertTail = FALSE, bInsertHead = FALSE;
     LONG lCount;
-    BOOLEAN bLocked = FALSE;
 
     AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                   AFS_TRACE_LEVEL_VERBOSE,
@@ -3448,149 +3536,158 @@ AFSMarkDirty( IN AFSFcb *Fcb,
                   &Fcb->NPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
-    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)
-    {
+    ASSERT( ExIsResourceAcquiredLite( &pNPFcb->Specific.File.ExtentsResource));
 
-        bInsertTail = TRUE;
-    }
-    else if( StartingByte->QuadPart == 0)
-    {
+    AFSAcquireExcl( &pNPFcb->Specific.File.DirtyExtentsListLock,
+                    TRUE);
 
-        bInsertHead = TRUE;
-    }
-    else
+    __try
     {
+        //
+        // Find the insertion point
+        //
 
-        pCurrentExtent = pNPFcb->Specific.File.DirtyListHead;
+        if( pNPFcb->Specific.File.DirtyListHead == NULL)
+        {
 
-        while( pCurrentExtent != NULL)
+            bInsertTail = TRUE;
+        }
+        else if( StartingByte->QuadPart == 0)
         {
 
-            if( pCurrentExtent->FileOffset.QuadPart + pCurrentExtent->Size >= StartingByte->QuadPart ||
-                pCurrentExtent->DirtyList.fLink == NULL)
-            {
+            bInsertHead = TRUE;
+        }
+        else
+        {
 
-                break;
-            }
+            pCurrentExtent = pNPFcb->Specific.File.DirtyListHead;
 
-            pCurrentExtent = (AFSExtent *)pCurrentExtent->DirtyList.fLink;
-        }
-    }
+            while( pCurrentExtent != NULL)
+            {
 
-    while( ulCount < ExtentsCount)
-    {
+                if( pCurrentExtent->FileOffset.QuadPart + pCurrentExtent->Size >= StartingByte->QuadPart ||
+                    pCurrentExtent->DirtyList.fLink == NULL)
+                {
 
-        pNextExtent = NextExtent( pExtent, AFS_EXTENTS_LIST);
+                    break;
+                }
 
-        if( !BooleanFlagOn( pExtent->Flags, AFS_EXTENT_DIRTY))
-        {
+                pCurrentExtent = (AFSExtent *)pCurrentExtent->DirtyList.fLink;
+            }
+        }
 
-            AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
-                          AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSMarkDirty Marking extent offset %I64X Length %08lX DIRTY\n",
-                          pExtent->FileOffset.QuadPart,
-                          pExtent->Size);
+        while( ulCount < ExtentsCount)
+        {
 
-            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)
+                    {
+
+                        pNPFcb->Specific.File.DirtyListHead = pExtent;
+                    }
+                    else
+                    {
 
-                pExtent->DirtyList.fLink = pCurrentExtent->DirtyList.fLink;
-                pExtent->DirtyList.bLink = (void *)pCurrentExtent;
+                        pNPFcb->Specific.File.DirtyListTail->DirtyList.fLink = (void *)pExtent;
 
-                if( pExtent->DirtyList.fLink == NULL)
-                {
+                        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;
 
-                pCurrentExtent = pExtent;
-            }
+                //
+                // Up the dirty count
+                //
 
-            pExtent->Flags |= AFS_EXTENT_DIRTY;
+                lCount = InterlockedIncrement( &Fcb->Specific.File.ExtentsDirtyCount);
+            }
+            else
+            {
 
-            //
-            // Up the dirty count
-            //
+                pCurrentExtent = pExtent;
+            }
 
-            lCount = InterlockedIncrement( &Fcb->Specific.File.ExtentsDirtyCount);
-        }
-        else
-        {
+            AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_ACTIVE_COUNTING,
+                          AFS_TRACE_LEVEL_VERBOSE,
+                          "AFSMarkDirty Decrement count on extent %08lX Cnt %d\n",
+                          pExtent,
+                          pExtent->ActiveCount);
 
-            pCurrentExtent = pExtent;
-        }
+            if( DerefExtents)
+            {
+                ASSERT( pExtent->ActiveCount > 0);
+                lCount = InterlockedDecrement( &pExtent->ActiveCount);
+            }
 
-        AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_ACTIVE_COUNTING,
-                      AFS_TRACE_LEVEL_VERBOSE,
-                      "AFSMarkDirty Decrement count on extent %08lX Cnt %d\n",
-                      pExtent,
-                      pExtent->ActiveCount);
+            pExtent = pNextExtent;
 
-        if( DerefExtents)
-        {
-            ASSERT( pExtent->ActiveCount > 0);
-            lCount = InterlockedDecrement( &pExtent->ActiveCount);
+            ulCount++;
         }
+    }
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+    {
 
-        pExtent = pNextExtent;
+        AFSDbgLogMsg( 0,
+                      0,
+                      "EXCEPTION - AFSMarkDirty\n");
 
-        ulCount++;
+        AFSDumpTraceFilesFnc();
     }
 
     AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
@@ -3601,11 +3698,6 @@ AFSMarkDirty( IN AFSFcb *Fcb,
                   &Fcb->NPFcb->Specific.File.ExtentsResource,
                   PsGetCurrentThread());
 
-    if( bLocked)
-    {
-        AFSReleaseResource( &Fcb->NPFcb->Specific.File.ExtentsResource );
-    }
-
     return;
 }
 
@@ -3616,16 +3708,20 @@ AFSMarkDirty( IN AFSFcb *Fcb,
 AFSExtent *
 ExtentFor(PLIST_ENTRY le, ULONG SkipList)
 {
+
     return CONTAINING_RECORD( le, AFSExtent, Lists[SkipList] );
 }
 
-static AFSExtent *NextExtent(AFSExtent *Extent, ULONG SkipList)
+AFSExtent *
+NextExtent(AFSExtent *Extent, ULONG SkipList)
 {
+
     return ExtentFor(Extent->Lists[SkipList].Flink, SkipList);
 }
 
 static AFSExtent *DirtyExtentFor(PLIST_ENTRY le)
 {
+
     return CONTAINING_RECORD( le, AFSExtent, DirtyList );
 }
 
@@ -3808,14 +3904,6 @@ AFSTrimExtents( IN AFSFcb *Fcb,
                     AFSReleaseResource( &pNPFcb->Specific.File.DirtyExtentsListLock);
                 }
 
-                for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i ++)
-                {
-                    if (NULL != pExtent->Lists[i].Flink && !IsListEmpty(&pExtent->Lists[i]))
-                    {
-                        RemoveEntryList( &pExtent->Lists[i] );
-                    }
-                }
-
                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSTrimExtents Releasing extent %p fid %08lX-%08lX-%08lX-%08lX Offset %I64X Len %08lX\n",
@@ -3827,28 +3915,10 @@ AFSTrimExtents( IN AFSFcb *Fcb,
                               pExtent->FileOffset.QuadPart,
                               pExtent->Size);
 
-                InterlockedExchangeAdd( &pControlDevExt->Specific.Control.ExtentsHeldLength, -((LONG)(pExtent->Size/1024)));
-
-                InterlockedExchangeAdd( &Fcb->Specific.File.ExtentLength, -((LONG)(pExtent->Size/1024)));
-
                 ASSERT( pExtent->ActiveCount == 0);
 
-                //
-                // and free
-                //
-                AFSExFreePool( pExtent);
-
-                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
-
-                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
-
-                if( lCount == 0)
-                {
-
-                    KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
-                                0,
-                                FALSE);
-                }
+                AFSFreeExtent( Fcb,
+                               pExtent);
             }
         }
 
@@ -3935,14 +4005,6 @@ AFSTrimSpecifiedExtents( IN AFSFcb *Fcb,
 
                 }
 
-                for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i ++)
-                {
-                    if (NULL != pExtent->Lists[i].Flink && !IsListEmpty(&pExtent->Lists[i]))
-                    {
-                        RemoveEntryList( &pExtent->Lists[i] );
-                    }
-                }
-
                 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSTrimSpecifiedExtents Releasing extent %p fid %08lX-%08lX-%08lX-%08lX Offset %I64X Len %08lX\n",
@@ -3954,28 +4016,10 @@ AFSTrimSpecifiedExtents( IN AFSFcb *Fcb,
                               pExtent->FileOffset.QuadPart,
                               pExtent->Size);
 
-                InterlockedExchangeAdd( &pControlDevExt->Specific.Control.ExtentsHeldLength, -((LONG)(pExtent->Size/1024)));
-
-                InterlockedExchangeAdd( &Fcb->Specific.File.ExtentLength, -((LONG)(pExtent->Size/1024)));
-
                 ASSERT( pExtent->ActiveCount == 0);
 
-                //
-                // and free
-                //
-                AFSExFreePool( pExtent);
-
-                lCount = InterlockedDecrement( &Fcb->Specific.File.ExtentCount);
-
-                lCount = InterlockedDecrement( &pControlDevExt->Specific.Control.ExtentCount);
-
-                if( lCount == 0)
-                {
-
-                    KeSetEvent( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
-                                0,
-                                FALSE);
-                }
+                AFSFreeExtent( Fcb,
+                               pExtent);
 
                 //
                 // Next extent we are looking for
@@ -4104,6 +4148,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,
@@ -4137,134 +4281,148 @@ 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)
         {
 
-            AFSExFreePool( pExtentBuffer);
+            AFSExFreePoolWithTag( pExtentBuffer, AFS_GENERIC_MEMORY_9_TAG);
         }
     }