{
AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb,
- &pWorkItem->AuthGroup);
+ &pWorkItem->AuthGroup,
+ FALSE);
}
ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0);
break;
}
- case AFS_WORK_ASYNCH_READ:
- {
-
- ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
-
- (VOID) AFSCommonRead( pWorkItem->Specific.AsynchIo.Device,
- pWorkItem->Specific.AsynchIo.Irp,
- pWorkItem->Specific.AsynchIo.CallingProcess);
-
- break;
- }
-
- case AFS_WORK_ASYNCH_WRITE:
- {
-
- ASSERT( pWorkItem->Specific.AsynchIo.CallingProcess != NULL);
-
- (VOID) AFSCommonWrite( pWorkItem->Specific.AsynchIo.Device,
- pWorkItem->Specific.AsynchIo.Irp,
- pWorkItem->Specific.AsynchIo.CallingProcess);
- break;
- }
-
case AFS_WORK_ENUMERATE_GLOBAL_ROOT:
{
LONG lFileType;
LARGE_INTEGER liCurrentTime;
BOOLEAN bVolumeObject = FALSE;
+ BOOLEAN bFcbBusy = FALSE;
LONG lCount;
pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
while( BooleanFlagOn( pPoolContext->State, AFS_WORKER_PROCESS_REQUESTS))
{
- KeWaitForSingleObject( &Timer,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ if ( bFcbBusy == FALSE)
+ {
+
+ KeWaitForSingleObject( &Timer,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+ else
+ {
+
+ bFcbBusy = FALSE;
+ }
//
// This is the primary volume worker so it will traverse the volume list
pNextVolume = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
+ AFSAcquireShared( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
if( pVolumeCB->ObjectInfoListHead == NULL &&
pVolumeCB->DirectoryCB->OpenReferenceCount == 0 &&
pVolumeCB->VolumeReferenceCount == 1 &&
AFSRemoveRootFcb( pVolumeCB->RootFcb);
}
+ AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
AFSRemoveVolume( pVolumeCB);
}
else
{
+ AFSReleaseResource( &pVolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
+
AFSReleaseResource( pVolumeCB->VolumeLock);
}
FALSE))
{
- if ( pCurrentObject->ObjectReferenceCount <= 0)
- {
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- if( pCurrentObject->Fcb != NULL)
- {
+ if ( pCurrentObject->ObjectReferenceCount <= 0 &&
+ ( pCurrentObject->Fcb == NULL ||
+ pCurrentObject->Fcb->OpenReferenceCount == 0 &&
+ pCurrentObject->Fcb->Specific.File.ExtentCount == 0))
+ {
- AFSRemoveFcb( &pCurrentObject->Fcb);
- }
+ AFSRemoveFcb( &pCurrentObject->Fcb);
if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
{
- if( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
- {
+ AFSAcquireExcl( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- }
+ AFSRemoveFcb( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
+
+ AFSReleaseResource( &pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
AFSDeleteObjectInfo( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
+ AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
- AFSExFreePool( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB);
+ AFSExFreePoolWithTag( pCurrentObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
}
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSPrimaryVolumeWorkerThread Deleting deleted object %08lX\n",
AFSDeleteObjectInfo( pCurrentObject);
}
+ else
+ {
+
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
AFSDeleteDirEntry( pCurrentObject,
pCurrentDirEntry);
- if( pCurrentChildObject->ObjectReferenceCount <= 0)
+
+ //
+ // Acquire ObjectInfoLock shared here so as not to deadlock
+ // with an invalidation call from the service during AFSCleanupFcb
+ //
+
+ AFSAcquireShared( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
+ pCurrentChildObject->Fcb != NULL &&
+ pCurrentChildObject->FileType == AFS_FILE_TYPE_FILE)
{
- if( pCurrentChildObject->Fcb != NULL)
- {
+ //
+ // We must not hold pVolumeCB->ObjectInfoTree.TreeLock exclusive
+ // across an AFSCleanupFcb call since it can deadlock with an
+ // invalidation call from the service.
+ //
- pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)&pCurrentChildObject->Fcb, NULL, (PVOID)pCurrentChildObject->Fcb);
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
- lFileType = pCurrentChildObject->FileType;
+ //
+ // Dropping the TreeLock permits the
+ // pCurrentObject->ObjectReferenceCount to change
+ //
+
+ ntStatus = AFSCleanupFcb( pCurrentChildObject->Fcb,
+ TRUE);
+
+ if ( ntStatus == STATUS_RETRY)
+ {
+
+ bFcbBusy = TRUE;
}
+ AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ TRUE);
+ }
+
+ AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+
+ AFSAcquireExcl( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ if( pCurrentChildObject->ObjectReferenceCount <= 0 &&
+ ( pCurrentChildObject->Fcb == NULL ||
+ pCurrentChildObject->Fcb->OpenReferenceCount == 0 &&
+ pCurrentChildObject->Fcb->Specific.File.ExtentCount == 0))
+ {
+
+ AFSRemoveFcb( &pCurrentChildObject->Fcb);
+
if( pCurrentChildObject->FileType == AFS_FILE_TYPE_DIRECTORY &&
pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB != NULL)
{
- if( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
- {
+ AFSAcquireExcl( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- AFSRemoveFcb( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
- }
+ AFSReleaseResource( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
AFSDeleteObjectInfo( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
ExDeleteResourceLite( &pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged);
+ AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
- AFSExFreePool( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB);
+ AFSExFreePoolWithTag( pCurrentChildObject->Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
}
+ AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSPrimaryVolumeWorkerThread Deleting object %08lX\n",
AFSDeleteObjectInfo( pCurrentChildObject);
}
-
- pCurrentDirEntry = pNextDirEntry;
-
- if ( pFcb != NULL)
+ else
{
- if( lFileType == AFS_FILE_TYPE_FILE)
- {
- //
- // We must not hold pVolumeCB->ObjectInfoTree.TreeLock exclusive
- // across an AFSCleanupFcb call since it can deadlock with an
- // invalidation call from the service.
- //
-
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
-
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
-
- AFSCleanupFcb( pFcb,
- TRUE);
+ AFSReleaseResource( &pCurrentChildObject->NonPagedInfo->ObjectInfoLock);
+ }
- AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
- }
+ pCurrentDirEntry = pNextDirEntry;
- AFSRemoveFcb( &pFcb);
- }
}
pCurrentObject->Specific.Directory.DirectoryNodeListHead = NULL;
else if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
{
- if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
- pCurrentObject->ObjectReferenceCount <= 0 &&
- ( pCurrentObject->Fcb == NULL ||
- pCurrentObject->Fcb->OpenReferenceCount == 0))
- {
-
- pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)&pCurrentObject->Fcb, NULL, (PVOID)pCurrentObject->Fcb);
-
- if( pFcb != NULL)
- {
+ AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ if( pCurrentObject->Fcb != NULL)
+ {
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
+ //
+ // Dropping the TreeLock permits the
+ // pCurrentObject->ObjectReferenceCount to change
+ //
- AFSCleanupFcb( pFcb,
- TRUE);
+ ntStatus = AFSCleanupFcb( pCurrentObject->Fcb,
+ FALSE);
- AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
+ if ( ntStatus == STATUS_RETRY)
+ {
- AFSRemoveFcb( &pFcb);
+ bFcbBusy = TRUE;
}
+ }
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ if( !AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
+ FALSE))
+ {
- if( AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
- FALSE))
- {
+ bReleaseVolumeLock = FALSE;
- AFSDeleteObjectInfo( pCurrentObject);
+ break;
+ }
- AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
+ AFSAcquireExcl( &pCurrentObject->NonPagedInfo->ObjectInfoLock,
+ TRUE);
- pCurrentObject = pNextObject;
+ if( BooleanFlagOn( pCurrentObject->Flags, AFS_OBJECT_FLAGS_DELETED) &&
+ pCurrentObject->ObjectReferenceCount <= 0 &&
+ ( pCurrentObject->Fcb == NULL ||
+ pCurrentObject->Fcb->OpenReferenceCount == 0 &&
+ pCurrentObject->Fcb->Specific.File.ExtentCount == 0))
+ {
- continue;
- }
- else
- {
+ AFSRemoveFcb( &pCurrentObject->Fcb);
- bReleaseVolumeLock = FALSE;
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
- break;
- }
+ AFSDeleteObjectInfo( pCurrentObject);
}
- else if( pCurrentObject->Fcb != NULL)
+ else
{
- AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
+ AFSReleaseResource( &pCurrentObject->NonPagedInfo->ObjectInfoLock);
+ }
- //
- // Dropping the TreeLock permits the
- // pCurrentObject->ObjectReferenceCount to change
- //
+ AFSConvertToShared( pVolumeCB->ObjectInfoTree.TreeLock);
- AFSCleanupFcb( pCurrentObject->Fcb,
- FALSE);
+ pCurrentObject = pNextObject;
- AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
- TRUE);
- }
+ continue;
}
pCurrentObject = pNextObject;
pWorkItem->RequestType = AFS_WORK_FLUSH_FCB;
- RtlCopyMemory( &pWorkItem->AuthGroup,
- AuthGroup,
- sizeof( GUID));
+ if ( AuthGroup == NULL)
+ {
+
+ RtlZeroMemory( &pWorkItem->AuthGroup,
+ sizeof( GUID));
+
+ ntStatus = AFSRetrieveValidAuthGroup( Fcb,
+ NULL,
+ TRUE,
+ &pWorkItem->AuthGroup);
+ }
+ else
+ {
+ RtlCopyMemory( &pWorkItem->AuthGroup,
+ AuthGroup,
+ sizeof( GUID));
+ }
pWorkItem->Specific.Fcb.Fcb = Fcb;
lCount = InterlockedDecrement( &Fcb->Specific.File.QueuedFlushCount);
+ ASSERT( lCount >= 0);
+
if( lCount == 0)
{
"AFSQueueFlushExtents Failed to queue request Status %08lX\n", ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSQueueFlushExtents\n");
- }
-
- return ntStatus;
-}
-NTSTATUS
-AFSQueueAsyncRead( IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN HANDLE CallerProcess)
-{
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkItem *pWorkItem = NULL;
-
- __try
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Queuing request for Irp %08lX\n",
- Irp);
-
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
- if (NULL == pWorkItem)
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncRead Failed to allocate work item\n");
-
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
- }
-
- RtlZeroMemory( pWorkItem,
- sizeof(AFSWorkItem));
-
- pWorkItem->Size = sizeof( AFSWorkItem);
-
- pWorkItem->RequestType = AFS_WORK_ASYNCH_READ;
-
- pWorkItem->Specific.AsynchIo.Device = DeviceObject;
-
- pWorkItem->Specific.AsynchIo.Irp = Irp;
-
- pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Workitem %08lX for Irp %08lX\n",
- pWorkItem,
- Irp);
-
- ntStatus = AFSQueueWorkerRequest( pWorkItem);
-
-try_exit:
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncRead Request for Irp %08lX complete Status %08lX\n",
- Irp,
- ntStatus);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- if( pWorkItem != NULL)
- {
-
- ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
- }
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncRead Failed to queue request Status %08lX\n", ntStatus);
- }
- }
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
- {
-
- AFSDbgLogMsg( 0,
- 0,
- "EXCEPTION - AFSQueueAsyncRead\n");
- }
-
- return ntStatus;
-}
-
-NTSTATUS
-AFSQueueAsyncWrite( IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN HANDLE CallerProcess)
-{
-
- NTSTATUS ntStatus = STATUS_SUCCESS;
- AFSWorkItem *pWorkItem = NULL;
-
- __try
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Queuing request for Irp %08lX\n",
- Irp);
-
- pWorkItem = (AFSWorkItem *) AFSLibExAllocatePoolWithTag( NonPagedPool,
- sizeof(AFSWorkItem),
- AFS_WORK_ITEM_TAG);
- if (NULL == pWorkItem)
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncWrite Failed to allocate work item\n");
-
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
- }
-
- RtlZeroMemory( pWorkItem,
- sizeof(AFSWorkItem));
-
- pWorkItem->Size = sizeof( AFSWorkItem);
-
- pWorkItem->RequestType = AFS_WORK_ASYNCH_WRITE;
-
- pWorkItem->Specific.AsynchIo.Device = DeviceObject;
-
- pWorkItem->Specific.AsynchIo.Irp = Irp;
-
- pWorkItem->Specific.AsynchIo.CallingProcess = CallerProcess;
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Workitem %08lX for Irp %08lX\n",
- pWorkItem,
- Irp);
-
- ntStatus = AFSQueueWorkerRequest( pWorkItem);
-
-try_exit:
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_WORKER_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSQueueAsyncWrite Request for Irp %08lX complete Status %08lX\n",
- Irp,
- ntStatus);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- if( pWorkItem != NULL)
- {
-
- ExFreePoolWithTag( pWorkItem, AFS_WORK_ITEM_TAG);
- }
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSQueueAsyncWrite Failed to queue request Status %08lX\n", ntStatus);
- }
- }
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
- {
-
- AFSDbgLogMsg( 0,
- 0,
- "EXCEPTION - AFSQueueAsyncWrite\n");
+ AFSDumpTraceFilesFnc();
}
return ntStatus;
ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSQueueGlobalRootEnumeration\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;
}
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSQueueStartIos\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;
ntStatus);
}
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSQueueInvalidateObject\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;