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,
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()) )
+ {
+
+ AFSDbgLogMsg( 0,
+ 0,
+ "EXCEPTION - AFSDoExtentsMapRegion\n");
- entry = newEntry;
+ AFSDumpTraceFilesFnc();
}
try_exit:
if (NULL == pExtent)
{
- ASSERT( FALSE);
-
try_return (ntStatus = STATUS_INSUFFICIENT_RESOURCES );
}
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)
+ {
+
+ 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);
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,
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)