NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG ulEntryLength = 0;
AFSObjectInfoCB *pObjectInfoCB = NULL;
- BOOLEAN bAllocatedObjectCB = FALSE;
ULONGLONG ullIndex = 0;
AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
LONG lCount;
ullIndex,
(AFSBTreeEntry **)&pObjectInfoCB);
- if( !NT_SUCCESS( ntStatus) ||
- pObjectInfoCB == NULL)
+ if( !NT_SUCCESS( ntStatus))
{
//
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
- bAllocatedObjectCB = TRUE;
-
AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
pObjectInfoCB,
ParentObjectInfo,
FileName));
+
+ //
+ // If we allocated the object information cb then set the information
+ //
+
+ pObjectInfoCB->FileId = DirEnumEntry->FileId;
+
+ pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
+
+ pObjectInfoCB->FileType = DirEnumEntry->FileType;
+
+ pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
+
+ if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
+ pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
+ {
+
+ pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ }
+
+ if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
+ {
+
+ if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+ {
+
+ pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+ else
+ {
+
+ pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+ }
+
+ //
+ // Check for the case where we have a filetype of SymLink but both the TargetFid and the
+ // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
+ // the code
+ //
+
+ if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
+ pObjectInfoCB->TargetFileId.Vnode == 0 &&
+ pObjectInfoCB->TargetFileId.Unique == 0 &&
+ (TargetName == NULL || TargetName->Length == 0))
+ {
+
+ //
+ // This will ensure we perform a validation on the node
+ //
+
+ pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
+ }
+
+ if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
+ {
+
+ SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
+ }
+
+ SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
+ }
+
+ if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
+ {
+
+ pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
+
+ pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
+
+ pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
+
+ pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
+
+ pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
+
+ pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
+
+ pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
+
+ pObjectInfoCB->Links = DirEnumEntry->Links;
+
+ pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
+
+ pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
+
+ ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
}
//
pObjectInfoCB,
lCount));
+ KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
+
AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
ntStatus = STATUS_SUCCESS;
pDirNode->NameInformation.TargetName.Length);
}
- //
- // If we allocated the object information cb then update the information
- //
-
- if( bAllocatedObjectCB)
- {
-
- //
- // Populate the rest of the data
- //
-
- pObjectInfoCB->FileId = DirEnumEntry->FileId;
-
- pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
-
- pObjectInfoCB->FileType = DirEnumEntry->FileType;
-
- pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
-
- pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
-
- pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
-
- pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
-
- pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
-
- pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
-
- pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
-
- if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
- pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
- {
-
- pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
- }
-
- if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
- {
-
- if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
- {
-
- pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
- }
- else
- {
-
- pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
- }
- }
-
- pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
-
- //
- // Check for the case where we have a filetype of SymLink but both the TargetFid and the
- // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
- // the code
- //
-
- if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
- pObjectInfoCB->TargetFileId.Vnode == 0 &&
- pObjectInfoCB->TargetFileId.Unique == 0 &&
- pDirNode->NameInformation.TargetName.Length == 0)
- {
-
- //
- // This will ensure we perform a validation on the node
- //
-
- pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
- }
-
- if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
- {
-
- SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
- }
- }
-
- //
- // Object specific information
- //
-
- pObjectInfoCB->Links = DirEnumEntry->Links;
-
- pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
-
- pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
try_exit:
if( pObjectInfoCB != NULL)
{
+ AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoDecrement( pObjectInfoCB,
AFS_OBJECT_REFERENCE_DIRENTRY);
pObjectInfoCB,
lCount));
- if( bAllocatedObjectCB &&
- lCount == 0)
- {
-
- AFSDeleteObjectInfo( &pObjectInfoCB);
- }
+ AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
}
}
}
{
pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
- &(*ppObjectInfo)->ParentFileId);
+ &(*ppObjectInfo)->ParentFileId,
+ FALSE);
}
if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
try_return( ntStatus);
}
- AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
+ AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
TRUE);
if ( AFSIsVolumeFID( &InvalidateCB->FileID))
}
pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
- &pCurrentFcb->ObjectInformation->ParentFileId);
+ &pCurrentFcb->ObjectInformation->ParentFileId,
+ FALSE);
if ( pParentObjectInfo != NULL)
{
}
}
+ AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
//
// Invalidate the volume root directory
//
pCurrentObject,
lCount));
+ AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
+
AFSInvalidateObject( &pCurrentObject,
Reason);
+ AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
if ( pCurrentObject)
{
// Apply invalidation to all other volume objects
//
- AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
-
pCurrentObject = VolumeCB->ObjectInfoListHead;
if ( pCurrentObject)
AFSInvalidateObject( &pCurrentObject,
Reason);
+ AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
if ( pCurrentObject )
{
lCount));
}
- AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
-
pCurrentObject = pNextObject;
}
&pCurrentDirEntry->NameInformation.FileName));
AFSDeleteDirEntry( ObjectInfo,
- pCurrentDirEntry);
+ &pCurrentDirEntry);
}
else
{
ObjectInfo->FileId.Unique));
AFSDeleteDirEntry( ObjectInfo,
- pCurrentDirEntry);
+ &pCurrentDirEntry);
}
else
{
&pCurrentDirEntry->NameInformation.FileName));
AFSDeleteDirEntry( ObjectInfoCB,
- pCurrentDirEntry);
+ &pCurrentDirEntry);
}
else
{
__Enter
{
+ AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
0);
if( pObjectInfoCB == NULL)
{
+ AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
+
try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
}
pObjectInfoCB,
lCount));
+ AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
+
pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
+ AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoIncrement( ParentObjectInfo,
AFS_OBJECT_REFERENCE_CHILD);
"AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
ParentObjectInfo,
lCount));
+
+ AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
}
//
AFSObjectInfoCB *
AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
- IN AFSFileID *FileId)
+ IN AFSFileID *FileId,
+ IN BOOLEAN bUpdateLastUse)
{
DWORD ntStatus = STATUS_SUCCESS;
ULONGLONG ullIndex;
"AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
pObjectInfo,
lCount));
+
+ if ( bUpdateLastUse)
+ {
+
+ KeQueryTickCount( &pObjectInfo->LastAccessCount);
+ }
}
AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
{
pParentObjectInfo = AFSFindObjectInfo( pVolume,
- &pObjectInfo->ParentFileId);
+ &pObjectInfo->ParentFileId,
+ FALSE);
+
if( pParentObjectInfo != NULL)
{
ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
+ AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoDecrement( pParentObjectInfo,
AFS_OBJECT_REFERENCE_CHILD);
pParentObjectInfo,
lCount));
+ AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
+
AFSReleaseObjectInfo( &pParentObjectInfo);
}
}
__Enter
{
+ ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
+
AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
UNREFERENCED_PARAMETER(Fcb);
if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
{
- Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
+ Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
}
if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
{
- Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
+ Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
}
if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
{
- Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
+ Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
}
if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
{
- Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
+ Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
}
if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
{
- Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
+ Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
}
return;
pObjectInfo = &pVolumeCB->ObjectInformation;
+ AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoIncrement( pObjectInfo,
AFS_OBJECT_REFERENCE_STATUS);
"AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
pObjectInfo,
lCount));
+
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
}
else
{
- AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
+ AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
"AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
pObjectInfo,
lCount));
+
+ KeQueryTickCount( &pObjectInfo->LastAccessCount);
}
AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
pObjectInfo = pDirectoryEntry->ObjectInformation;
+ AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoIncrement( pObjectInfo,
AFS_OBJECT_REFERENCE_STATUS);
"AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
pObjectInfo,
lCount));
+
+ AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
}
//
ASSERT( lCount >= 0);
}
- if( pObjectInfo != NULL)
+ if( pVolumeCB != NULL)
{
- lCount = AFSObjectInfoDecrement( pObjectInfo,
- AFS_OBJECT_REFERENCE_STATUS);
+ if( pObjectInfo != NULL)
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
- pObjectInfo,
- lCount));
- }
+ AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
- if( pVolumeCB != NULL)
- {
+ lCount = AFSObjectInfoDecrement( pObjectInfo,
+ AFS_OBJECT_REFERENCE_STATUS);
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
+ pObjectInfo,
+ lCount));
+
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ }
lCount = AFSVolumeDecrement( pVolumeCB,
VolumeReferenceReason);
try_return( ntStatus = STATUS_INVALID_PARAMETER);
}
- pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
- PAGE_SIZE,
- AFS_GENERIC_MEMORY_27_TAG);
+ pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
+ PAGE_SIZE,
+ AFS_GENERIC_MEMORY_27_TAG);
if( pRelativeSecurityDescr == NULL)
{
IN ULONG InvalidateReason)
{
+ AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
LIST_ENTRY *le;
AFSExtent *pEntry;
bLocked = TRUE;
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
- &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
- PsGetCurrentThread()));
+ if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
+ {
- AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
- TRUE);
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ PsGetCurrentThread()));
- bExtentsLocked = TRUE;
+ AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ 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.
- //
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
- if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
- {
+ bLocked = FALSE;
- if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
+ __try
{
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
-
- bExtentsLocked = FALSE;
-
- if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
+ if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+ !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ NULL,
+ 0,
+ FALSE))
{
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
-
- bLocked = FALSE;
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique));
- AFSTearDownFcbExtents( ObjectInfo->Fcb,
- NULL);
+ SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
}
else
{
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
- &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
- PsGetCurrentThread()));
+ bCleanExtents = TRUE;
+ }
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER)
+ {
- AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
- TRUE);
+ ntStatus = GetExceptionCode();
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+ AFSDbgTrace(( 0,
+ 0,
+ "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique,
+ ntStatus));
- bLocked = FALSE;
+ SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+ }
- __try
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ PsGetCurrentThread()));
- if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
- !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- NULL,
- 0,
- FALSE))
- {
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
+ }
+ else
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
- ObjectInfo->FileId.Cell,
- ObjectInfo->FileId.Volume,
- ObjectInfo->FileId.Vnode,
- ObjectInfo->FileId.Unique));
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+ PsGetCurrentThread()));
- SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
- }
- else
- {
+ AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+ TRUE);
- bCleanExtents = TRUE;
- }
- }
- __except( EXCEPTION_EXECUTE_HANDLER)
- {
+ 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)
+ {
- ntStatus = GetExceptionCode();
+ if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
+ {
- AFSDbgTrace(( 0,
- 0,
- "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
- ObjectInfo->FileId.Cell,
- ObjectInfo->FileId.Volume,
- ObjectInfo->FileId.Vnode,
- ObjectInfo->FileId.Unique,
- ntStatus));
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
- SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
- }
+ bExtentsLocked = FALSE;
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
- &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
- PsGetCurrentThread()));
+ if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
+ {
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
- }
- }
- else
- {
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+ bLocked = FALSE;
- bExtentsLocked = FALSE;
+ AFSTearDownFcbExtents( ObjectInfo->Fcb,
+ NULL);
+ }
+ else
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
- &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
- PsGetCurrentThread()));
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ PsGetCurrentThread()));
- AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
- TRUE);
+ AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ TRUE);
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
- bLocked = FALSE;
+ bLocked = FALSE;
- //
- // 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
+ {
- __try
- {
+ if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+ !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ NULL,
+ 0,
+ FALSE))
+ {
- ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
- &ByteRangeList);
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique));
- if ( ByteRangeList != NULL ||
- ulByteRangeCount == 0)
- {
+ SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+ }
+ else
+ {
- for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
+ bCleanExtents = TRUE;
+ }
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER)
{
- ULONG ulSize;
+ ntStatus = GetExceptionCode();
- do {
+ AFSDbgTrace(( 0,
+ 0,
+ "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique,
+ ntStatus));
- ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
+ SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+ }
- if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
- !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- &ByteRangeList[ulIndex].FileOffset,
- ulSize,
- FALSE))
- {
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ PsGetCurrentThread()));
- AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
- ObjectInfo->FileId.Cell,
- ObjectInfo->FileId.Volume,
- ObjectInfo->FileId.Vnode,
- ObjectInfo->FileId.Unique));
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
+ }
+ }
+ else
+ {
- bPurgeOnClose = TRUE;
- }
- else
- {
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
- bCleanExtents = TRUE;
- }
+ bExtentsLocked = FALSE;
- ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ PsGetCurrentThread()));
- ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
+ AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ TRUE);
- } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
- }
- }
- else
- {
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
- //
- // 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.
- //
+ bLocked = FALSE;
- AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
- TRUE);
- bExtentsLocked = TRUE;
+ //
+ // 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.
+ //
- le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
+ AFSByteRange * ByteRangeList = NULL;
+ ULONG ulByteRangeCount = 0;
+ ULONG ulIndex;
+ BOOLEAN bPurgeOnClose = FALSE;
- ulProcessCount = 0;
+ __try
+ {
- ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
+ ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
+ &ByteRangeList);
- if( ulCount > 0)
+ if ( ByteRangeList != NULL ||
+ ulByteRangeCount == 0)
{
- pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
- while( ulProcessCount < ulCount)
+ for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
{
- pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
- if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
- {
- if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- &pEntry->FileOffset,
- pEntry->Size,
+ ULONG ulSize;
+
+ do {
+
+ ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
+
+ if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+ !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ &ByteRangeList[ulIndex].FileOffset,
+ ulSize,
FALSE))
{
AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_WARNING,
- "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
ObjectInfo->FileId.Cell,
ObjectInfo->FileId.Volume,
ObjectInfo->FileId.Vnode,
bCleanExtents = TRUE;
}
- }
- if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
- {
+ ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
- liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
+ ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
- while( liFlushLength.QuadPart > 0)
- {
+ } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
+ }
+ }
+ else
+ {
- if( liFlushLength.QuadPart > 512 * 1024000)
- {
- ulFlushLength = 512 * 1024000;
- }
- else
- {
- ulFlushLength = liFlushLength.LowPart;
- }
+ //
+ // 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.
+ //
+
+ AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+ TRUE);
+ bExtentsLocked = TRUE;
+
+ 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)
+ {
+ pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
+
+ if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
+ {
if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- &liCurrentOffset,
- ulFlushLength,
+ &pEntry->FileOffset,
+ pEntry->Size,
FALSE))
{
AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
AFS_TRACE_LEVEL_WARNING,
- "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+ "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
ObjectInfo->FileId.Cell,
ObjectInfo->FileId.Volume,
ObjectInfo->FileId.Vnode,
bCleanExtents = TRUE;
}
+ }
+
+ if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
+ {
- liFlushLength.QuadPart -= ulFlushLength;
+ 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))
+ {
+
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique));
+
+ bPurgeOnClose = TRUE;
+ }
+ else
+ {
+
+ bCleanExtents = TRUE;
+ }
+
+ liFlushLength.QuadPart -= ulFlushLength;
+ }
}
- }
- liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
+ liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
- ulProcessCount++;
- le = le->Flink;
+ ulProcessCount++;
+ le = le->Flink;
+ }
}
- }
- else
- {
- if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
- NULL,
- 0,
- FALSE))
+ else
{
+ if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+ NULL,
+ 0,
+ FALSE))
+ {
- AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
- ObjectInfo->FileId.Cell,
- ObjectInfo->FileId.Volume,
- ObjectInfo->FileId.Vnode,
- ObjectInfo->FileId.Unique));
+ AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_WARNING,
+ "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique));
- bPurgeOnClose = TRUE;
+ bPurgeOnClose = TRUE;
+ }
+ else
+ {
+
+ bCleanExtents = TRUE;
+ }
}
- else
+
+ if ( bPurgeOnClose)
{
- bCleanExtents = TRUE;
+ SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
}
}
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER)
+ {
- if ( bPurgeOnClose)
- {
+ ntStatus = GetExceptionCode();
- SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
- }
+ AFSDbgTrace(( 0,
+ 0,
+ "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+ ObjectInfo->FileId.Cell,
+ ObjectInfo->FileId.Volume,
+ ObjectInfo->FileId.Vnode,
+ ObjectInfo->FileId.Unique,
+ ntStatus));
}
- }
- __except( EXCEPTION_EXECUTE_HANDLER)
- {
- ntStatus = GetExceptionCode();
+ AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
+ &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
+ PsGetCurrentThread()));
- AFSDbgTrace(( 0,
- 0,
- "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
- ObjectInfo->FileId.Cell,
- ObjectInfo->FileId.Volume,
- ObjectInfo->FileId.Vnode,
- ObjectInfo->FileId.Unique,
- ntStatus));
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
}
-
- AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
- &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
- PsGetCurrentThread()));
-
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
}
- }
- if ( bExtentsLocked)
- {
+ if ( bExtentsLocked)
+ {
- AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+ AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
+ }
}
if ( bLocked)
// or AFSQueueInvalidateObject
//
+ AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+
lCount = AFSObjectInfoDecrement( ObjectInfo,
AFS_OBJECT_REFERENCE_INVALIDATION);
"AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
ObjectInfo,
lCount));
+
+ AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
}
return ntStatus;
}
+
+BOOLEAN
+AFSIgnoreReparsePointToFile( void)
+{
+ AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+ BOOLEAN bIgnoreReparsePoint;
+
+ {
+
+ bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
+ AFS_REPARSE_POINT_TO_FILE_AS_FILE);
+ }
+
+ return bIgnoreReparsePoint;
+}