NTSTATUS ntStatus = STATUS_SUCCESS;
void *pAddress = NULL;
- MDL *pMdl = NULL;
+ MDL *pMdl = NULL;
- __Enter
- {
+ __Enter
+ {
pMdl = IoAllocateMdl( UserBuffer,
BufferLength,
FALSE,
NULL);
- if( pMdl == NULL)
- {
+ if( pMdl == NULL)
+ {
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
//
// Lock the new Mdl in memory.
{
MmProbeAndLockPages( pMdl,
- KernelMode,
+ KernelMode,
IoWriteAccess);
pAddress = MmGetSystemAddressForMdlSafe( pMdl,
- NormalPagePriority);
+ NormalPagePriority);
}
__except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
{
pAddress = NULL;
}
- if( pMdl != NULL)
- {
+ if( pMdl != NULL)
+ {
- *Mdl = pMdl;
- }
+ *Mdl = pMdl;
+ }
try_exit:
try_return( ntStatus);
}
+ AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
if ( AFSIsVolumeFID( &InvalidateCB->FileID))
{
else
{
- AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
-
lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
ullIndex,
(AFSBTreeEntry **)&pObjectInfo);
-
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
-
}
if( pObjectInfo != NULL)
lCount);
}
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+
if( !NT_SUCCESS( ntStatus) ||
pObjectInfo == NULL)
{
AFSInvalidateObject( &pCurrentObject,
Reason);
- lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+ if ( pCurrentObject)
+ {
- AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
- pCurrentObject,
- lCount);
+ lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
+ pCurrentObject,
+ lCount);
+ }
}
//
{
AFSNameArrayHdr *pNameArray = NULL;
+ AFSNameArrayCB *pCurrentElement = NULL;
AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
LONG lCount;
if( pNameArray == NULL)
{
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
"AFSInitNameArray Failed to allocate name array\n");
if( DirectoryCB != NULL)
{
- pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
+ pCurrentElement = &pNameArray->ElementArray[ 0];
+
+ pNameArray->CurrentEntry = pCurrentElement;
- lCount = InterlockedIncrement( &pNameArray->Count);
+ pNameArray->Count = 1;
+
+ pNameArray->LinkCount = 0;
lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
DirectoryCB,
lCount);
- pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
+ pCurrentElement->DirectoryCB = DirectoryCB;
+
+ pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+ pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+ if( pCurrentElement->FileId.Vnode == 1)
+ {
- pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
+ SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+ }
- pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ pNameArray,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
}
try_exit:
__Enter
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ &Path,
+ DirectoryCB,
+ DirectoryCB->ObjectInformation->FileId.Cell,
+ DirectoryCB->ObjectInformation->FileId.Volume,
+ DirectoryCB->ObjectInformation->FileId.Vnode,
+ DirectoryCB->ObjectInformation->FileId.Unique,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB->ObjectInformation->FileType);
+
//
// Init some info in the header
//
pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
+ pCurrentElement->Flags = 0;
+
+ if( pCurrentElement->FileId.Vnode == 1)
+ {
+
+ SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+ }
+
NameArray->Count = 1;
NameArray->LinkCount = 0;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
+
//
// If the root is the parent then we are done ...
//
__Enter
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ RelatedNameArray,
+ DirectoryCB,
+ DirectoryCB->ObjectInformation->FileId.Cell,
+ DirectoryCB->ObjectInformation->FileId.Volume,
+ DirectoryCB->ObjectInformation->FileId.Vnode,
+ DirectoryCB->ObjectInformation->FileId.Unique,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB->ObjectInformation->FileType);
+
//
// Init some info in the header
//
pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
+ pCurrentElement->Flags = 0;
+
+ if( pCurrentElement->FileId.Vnode == 1)
+ {
+
+ SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+ }
+
lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
lCount = InterlockedIncrement( &NameArray->Count);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ lCount - 1,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
+
if( pCurrentElement->DirectoryCB == DirectoryCB ||
NameArray->Count == RelatedNameArray->Count)
{
pCurrentRelatedElement++;
}
- if( NameArray->Count > 0)
- {
- NameArray->CurrentEntry = pCurrentElement;
- }
+ NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
}
return ntStatus;
NTSTATUS ntStatus = STATUS_SUCCESS;
AFSNameArrayCB *pCurrentElement = NULL;
- LONG lCount;
+ LONG lCount, lElement;
__Enter
{
- pCurrentElement = &NameArray->ElementArray[ 0];
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSFreeNameArray [NA:%p]\n",
+ NameArray);
- while( TRUE)
+ for ( lElement = 0; lElement < NameArray->Count; lElement++)
{
- if( pCurrentElement->DirectoryCB == NULL)
- {
-
- break;
- }
+ pCurrentElement = &NameArray->ElementArray[ lElement];
lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
&pCurrentElement->DirectoryCB->NameInformation.FileName,
pCurrentElement->DirectoryCB,
lCount);
-
- pCurrentElement++;
}
AFSExFreePool( NameArray);
NTSTATUS
AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
- IN AFSDirectoryCB *DirEntry)
+ IN AFSDirectoryCB *DirectoryCB)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
+ AFSNameArrayCB *pCurrentElement = NULL;
LONG lCount;
__Enter
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ DirectoryCB,
+ DirectoryCB->ObjectInformation->FileId.Cell,
+ DirectoryCB->ObjectInformation->FileId.Volume,
+ DirectoryCB->ObjectInformation->FileId.Vnode,
+ DirectoryCB->ObjectInformation->FileId.Unique,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB->ObjectInformation->FileType);
+
if( NameArray->Count == NameArray->MaxElementCount)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
+ NameArray);
+
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
if( NameArray->CurrentEntry != NULL &&
- NameArray->CurrentEntry->DirectoryCB == DirEntry)
+ NameArray->CurrentEntry->DirectoryCB == DirectoryCB)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSInsertNextElement [NA:%p] DE %p already current element\n",
+ NameArray,
+ DirectoryCB);
+
try_return( ntStatus);
}
NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
}
+ pCurrentElement = NameArray->CurrentEntry;
+
lCount = InterlockedIncrement( &NameArray->Count);
- lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
+ lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
- &DirEntry->NameInformation.FileName,
- DirEntry,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB,
lCount);
- NameArray->CurrentEntry->DirectoryCB = DirEntry;
+ pCurrentElement->DirectoryCB = DirectoryCB;
+
+ pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+ pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+ pCurrentElement->Flags = 0;
- NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
+ if( pCurrentElement->FileId.Vnode == 1)
+ {
+
+ SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+ }
- NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ NameArray->Count - 1,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
try_exit:
AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
IN AFSDirectoryCB *DirectoryCB)
{
+ AFSNameArrayCB *pCurrentElement = NULL;
LONG lCount;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSReplaceCurrentElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ DirectoryCB,
+ DirectoryCB->ObjectInformation->FileId.Cell,
+ DirectoryCB->ObjectInformation->FileId.Volume,
+ DirectoryCB->ObjectInformation->FileId.Vnode,
+ DirectoryCB->ObjectInformation->FileId.Unique,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB->ObjectInformation->FileType);
+
ASSERT( NameArray->CurrentEntry != NULL);
+ pCurrentElement = NameArray->CurrentEntry;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSReplaceCurrentElement [NA:%p] Replacing Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ NameArray->Count - 1,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
+
lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
- &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
- NameArray->CurrentEntry->DirectoryCB,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB,
lCount);
lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
DirectoryCB,
lCount);
- NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
+ pCurrentElement->DirectoryCB = DirectoryCB;
- NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
+ pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
- NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
+ pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
- if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
+ pCurrentElement->Flags = 0;
+
+ if( pCurrentElement->FileId.Vnode == 1)
{
- SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+ SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
}
return;
AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
{
- AFSDirectoryCB *pCurrentDirEntry = NULL;
+ AFSDirectoryCB *pDirectoryCB = NULL;
+ AFSNameArrayCB *pCurrentElement = NULL;
LONG lCount;
__Enter
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSBackupEntry [NA:%p]\n",
+ NameArray);
+
if( NameArray->Count == 0)
{
- try_return( pCurrentDirEntry);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSBackupEntry [NA:%p] No more entries\n",
+ NameArray);
+
+ try_return( pCurrentElement);
}
lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
if( lCount == 0)
{
NameArray->CurrentEntry = NULL;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSBackupEntry [NA:%p] No more entries\n",
+ NameArray);
}
else
{
NameArray->CurrentEntry--;
- pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
+
+ pCurrentElement = NameArray->CurrentEntry;
+
+ pDirectoryCB = pCurrentElement->DirectoryCB;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ NameArray->Count - 1,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
}
try_exit:
NOTHING;
}
- return pCurrentDirEntry;
+ return pDirectoryCB;
}
AFSDirectoryCB *
__Enter
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSGetParentEntry [NA:%p]\n",
+ NameArray);
+
if( NameArray->Count == 0 ||
NameArray->Count == 1)
{
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSGetParentEntry [NA:%p] No more entries\n",
+ NameArray);
+
try_return( pDirEntry = NULL);
}
pDirEntry = pElement->DirectoryCB;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ NameArray->Count - 2,
+ pElement->DirectoryCB,
+ pElement->FileId.Cell,
+ pElement->FileId.Volume,
+ pElement->FileId.Vnode,
+ pElement->FileId.Unique,
+ &pElement->DirectoryCB->NameInformation.FileName,
+ pElement->DirectoryCB->ObjectInformation->FileType);
+
try_exit:
NOTHING;
void
AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
- IN AFSDirectoryCB *DirEntry)
+ IN AFSDirectoryCB *DirectoryCB)
{
AFSNameArrayCB *pCurrentElement = NULL;
AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
- LONG lCount;
+ LONG lCount, lElement;
__Enter
{
- pCurrentElement = &NameArray->ElementArray[ 0];
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ DirectoryCB,
+ DirectoryCB->ObjectInformation->FileId.Cell,
+ DirectoryCB->ObjectInformation->FileId.Volume,
+ DirectoryCB->ObjectInformation->FileId.Vnode,
+ DirectoryCB->ObjectInformation->FileId.Unique,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB->ObjectInformation->FileType);
+ //
+ // Dereference previous name array contents
+ //
- while( TRUE)
+ for ( lElement = 0; lElement < NameArray->Count; lElement++)
{
- if( pCurrentElement->DirectoryCB == NULL)
- {
-
- break;
- }
+ pCurrentElement = &NameArray->ElementArray[ lElement];
lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
&pCurrentElement->DirectoryCB->NameInformation.FileName,
pCurrentElement->DirectoryCB,
lCount);
-
- pCurrentElement++;
}
RtlZeroMemory( NameArray,
NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
- if( DirEntry != NULL)
+ if( DirectoryCB != NULL)
{
- NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
+ pCurrentElement = &NameArray->ElementArray[ 0];
- lCount = InterlockedIncrement( &NameArray->Count);
+ NameArray->CurrentEntry = pCurrentElement;
+
+ NameArray->Count = 1;
+
+ NameArray->LinkCount = 0;
- lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
+ lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
- &DirEntry->NameInformation.FileName,
- DirEntry,
+ &DirectoryCB->NameInformation.FileName,
+ DirectoryCB,
lCount);
- NameArray->CurrentEntry->DirectoryCB = DirEntry;
+ pCurrentElement->DirectoryCB = DirectoryCB;
+
+ pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
+
+ pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
+
+ pCurrentElement->Flags = 0;
- NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
+ if( pCurrentElement->FileId.Vnode == 1)
+ {
+
+ SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
+ }
- NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
+ AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
+ NameArray,
+ pCurrentElement->DirectoryCB,
+ pCurrentElement->FileId.Cell,
+ pCurrentElement->FileId.Volume,
+ pCurrentElement->FileId.Vnode,
+ pCurrentElement->FileId.Unique,
+ &pCurrentElement->DirectoryCB->NameInformation.FileName,
+ pCurrentElement->DirectoryCB->ObjectInformation->FileType);
}
}
LARGE_INTEGER liCurrentOffset = {0,0};
LARGE_INTEGER liFlushLength = {0,0};
ULONG ulFlushLength = 0;
+ BOOLEAN bLocked = FALSE;
+ BOOLEAN bExtentsLocked = FALSE;
+ BOOLEAN bCleanExtents = FALSE;
if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
ObjectInfo->Fcb != NULL)
AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
TRUE);
+ bLocked = TRUE;
+
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
TRUE);
- __try
+ bExtentsLocked = TRUE;
+
+ //
+ // There are several possibilities here:
+ //
+ // 0. If there are no extents or all of the extents are dirty, do nothing.
+ //
+ // 1. There could be nothing dirty and an open reference count of zero
+ // in which case we can just tear down all of the extents without
+ // holding any resources.
+ //
+ // 2. There could be nothing dirty and a non-zero open reference count
+ // in which case we can issue a CcPurge against the entire file
+ // while holding just the Fcb Resource.
+ //
+ // 3. There can be dirty extents in which case we need to identify
+ // the non-dirty ranges and then perform a CcPurge on just the
+ // non-dirty ranges while holding just the Fcb Resource.
+ //
+
+ if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
{
- le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+ if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
+ {
+
+ if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
+ {
- ulProcessCount = 0;
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
- ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+ bExtentsLocked = FALSE;
- if( ulCount > 0)
- {
- pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
- while( ulProcessCount < ulCount)
+ bLocked = FALSE;
+
+ (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
+ NULL);
+ }
+ else
{
- pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
- if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+ __try
{
+
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+ bExtentsLocked = FALSE;
+
if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- &pEntry->FileOffset,
- pEntry->Size,
+ NULL,
+ 0,
FALSE))
{
SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
}
+ else
+ {
+
+ bCleanExtents = TRUE;
+ }
}
+ __except( EXCEPTION_EXECUTE_HANDLER)
+ {
+
+ ntStatus = GetExceptionCode();
- if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+ AFSDbgLogMsg( 0,
+ 0,
+ "EXCEPTION - AFSPerformObjectInvalidate Status %08lX\n",
+ ntStatus);
+ }
+ }
+ }
+ else
+ {
+
+ //
+ // Must build a list of non-dirty ranges from the beginning of the file
+ // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
+ // ranges. In all but the most extreme random data write scenario there will
+ // be significantly fewer.
+ //
+ // For each range we need offset and size.
+ //
+
+ AFSByteRange * ByteRangeList = NULL;
+ ULONG ulByteRangeCount = 0;
+ ULONG ulIndex;
+ BOOLEAN bPurgeOnClose = FALSE;
+
+ __try
+ {
+
+ ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
+ &ByteRangeList);
+
+ if ( ByteRangeList != NULL ||
+ ulByteRangeCount == 0)
{
- liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+
+ bExtentsLocked = FALSE;
- while( liFlushLength.QuadPart > 0)
+ for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
{
- if( liFlushLength.QuadPart > 512 * 1024000)
- {
- ulFlushLength = 512 * 1024000;
- }
- else
+ ULONG ulSize;
+
+ do {
+
+ ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
+
+ if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ &ByteRangeList[ulIndex].FileOffset,
+ ulSize,
+ FALSE))
+ {
+
+ bPurgeOnClose = TRUE;
+ }
+ else
+ {
+
+ bCleanExtents = TRUE;
+ }
+
+ ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
+
+ ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
+
+ } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
+ }
+ }
+ else
+ {
+
+ //
+ // We couldn't allocate the memory to build the purge list
+ // so just walk the extent list while holding the ExtentsList Resource.
+ // This could deadlock but we do not have much choice.
+ //
+
+ le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+
+ ulProcessCount = 0;
+
+ ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+
+ if( ulCount > 0)
+ {
+ pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+ while( ulProcessCount < ulCount)
{
- ulFlushLength = liFlushLength.LowPart;
+ pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+ if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+ {
+ if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ &pEntry->FileOffset,
+ pEntry->Size,
+ FALSE))
+ {
+
+ bPurgeOnClose = TRUE;
+ }
+ else
+ {
+
+ bCleanExtents = TRUE;
+ }
+ }
+
+ if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+ {
+
+ liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+
+ while( liFlushLength.QuadPart > 0)
+ {
+
+ if( liFlushLength.QuadPart > 512 * 1024000)
+ {
+ ulFlushLength = 512 * 1024000;
+ }
+ else
+ {
+ ulFlushLength = liFlushLength.LowPart;
+ }
+
+ if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ &liCurrentOffset,
+ ulFlushLength,
+ FALSE))
+ {
+
+ bPurgeOnClose = TRUE;
+ }
+ else
+ {
+
+ bCleanExtents = TRUE;
+ }
+
+ liFlushLength.QuadPart -= ulFlushLength;
+ }
+ }
+
+ liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+
+ ulProcessCount++;
+ le = le->Flink;
}
-
+ }
+ else
+ {
if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- &liCurrentOffset,
- ulFlushLength,
+ NULL,
+ 0,
FALSE))
{
- SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+ bPurgeOnClose = TRUE;
}
+ else
+ {
- liFlushLength.QuadPart -= ulFlushLength;
+ bCleanExtents = TRUE;
+ }
}
- }
- liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+ if ( bPurgeOnClose)
+ {
- ulProcessCount++;
- le = le->Flink;
+ SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+ }
+ }
}
- }
- else
- {
- if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- NULL,
- 0,
- FALSE))
+ __except( EXCEPTION_EXECUTE_HANDLER)
{
- SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+ ntStatus = GetExceptionCode();
+
+ AFSDbgLogMsg( 0,
+ 0,
+ "EXCEPTION - AFSPerformObjectInvalidate Status %08lX\n",
+ ntStatus);
}
}
}
- __except( EXCEPTION_EXECUTE_HANDLER)
+
+ if ( bExtentsLocked)
{
- ntStatus = GetExceptionCode();
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
}
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
-
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+ if ( bLocked)
+ {
- AFSReleaseCleanExtents( ObjectInfo->Fcb,
- NULL);
- }
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+ }
- break;
- }
+ if ( bCleanExtents)
+ {
- default:
- {
+ AFSReleaseCleanExtents( ObjectInfo->Fcb,
+ NULL);
+ }
+ }
break;
}