AFSClose( IN PDEVICE_OBJECT LibDeviceObject,
IN PIRP Irp)
{
-
+ UNREFERENCED_PARAMETER(LibDeviceObject);
NTSTATUS ntStatus = STATUS_SUCCESS;
- ULONG ulRequestType = 0;
IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
AFSFcb *pFcb = NULL;
AFSDeviceExt *pDeviceExt = NULL;
AFSCcb *pCcb = NULL;
AFSObjectInfoCB *pObjectInfo = NULL;
AFSDirectoryCB *pDirCB = NULL;
+ LONG lCount;
__try
{
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Acquiring GlobalRoot lock %08lX EXCL %08lX\n",
+ "AFSClose Acquiring GlobalRoot lock %p EXCL %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_CLOSE,
AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
+ &pCcb->AuthGroup,
NULL,
&stParentFileId,
(void *)&stPIOCtlClose,
NULL,
NULL);
- pDirCB = pCcb->DirectoryCB;
-
//
// Remove the Ccb and de-allocate it
//
- ntStatus = AFSRemoveCcb( pCcb);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus);
-
- //
- // We can't actually fail a close operation so reset the status
- //
-
- ntStatus = STATUS_SUCCESS;
- }
-
- ASSERT( pDirCB->OpenReferenceCount > 0);
-
- InterlockedDecrement( &pDirCB->OpenReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (IOCtl) Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
- &pDirCB->NameInformation.FileName,
- pDirCB,
- pCcb,
- pDirCB->OpenReferenceCount);
+ AFSRemoveCcb( pFcb,
+ pCcb);
//
// If this is not the root then decrement the open child reference count
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (IOCtl) Decrement child open ref count on Parent object %08lX Cnt %d\n",
+ "AFSClose (IOCtl) Decrement child open ref count on Parent object %p Cnt %d\n",
pObjectInfo->ParentObjectInformation,
pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
}
AFSReleaseResource( &pFcb->NPFcb->Resource);
- ASSERT( pFcb->OpenReferenceCount != 0);
-
- InterlockedDecrement( &pFcb->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pFcb->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (IOCtl) Decrement count on Fcb %08lX Cnt %d\n",
+ "AFSClose (IOCtl) Decrement count on Fcb %p Cnt %d\n",
pFcb,
- pFcb->OpenReferenceCount);
+ lCount);
+
+ ASSERT( lCount >= 0);
break;
}
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Acquiring Special Root ALL lock %08lX EXCL %08lX\n",
+ "AFSClose Acquiring Special Root ALL lock %p EXCL %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
- pDirCB = pCcb->DirectoryCB;
-
//
// Remove the Ccb and de-allocate it
//
- ntStatus = AFSRemoveCcb( pCcb);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus);
-
- //
- // We can't actually fail a close operation so reset the status
- //
-
- ntStatus = STATUS_SUCCESS;
- }
-
- ASSERT( pDirCB->OpenReferenceCount > 0);
-
- InterlockedDecrement( &pDirCB->OpenReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Decrement (Root ALL) count on %wZ DE %p Ccb %p Cnt %d\n",
- &pDirCB->NameInformation.FileName,
- pDirCB,
- pCcb,
- pDirCB->OpenReferenceCount);
+ AFSRemoveCcb( pFcb,
+ pCcb);
AFSReleaseResource( &pFcb->NPFcb->Resource);
- ASSERT( pFcb->OpenReferenceCount > 0);
-
- InterlockedDecrement( &pFcb->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pFcb->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (RootAll) Decrement count on Fcb %08lX Cnt %d\n",
+ "AFSClose (RootAll) Decrement count on Fcb %p Cnt %d\n",
pFcb,
- pFcb->OpenReferenceCount);
+ lCount);
+
+ ASSERT( lCount >= 0);
break;
}
case AFS_SYMBOLIC_LINK_FCB:
case AFS_MOUNT_POINT_FCB:
case AFS_DFS_LINK_FCB:
+ case AFS_INVALID_FCB:
{
pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Acquiring Dcb lock %08lX EXCL %08lX\n",
+ "AFSClose Acquiring Dcb lock %p EXCL %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
KeQueryTickCount( &pFcb->ObjectInformation->LastAccessCount);
- pDirCB = pCcb->DirectoryCB;
+ if( pFcb->OpenReferenceCount == 1 &&
+ pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
+ {
- //
- // Remove the Ccb and de-allocate it
- //
+ SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
+
+ //
+ // Attempt to tear down our extent list for the file
+ // If there are remaining dirty extents then attempt to
+ // flush them as well
+ //
- ntStatus = AFSRemoveCcb( pCcb);
+ if( pFcb->Specific.File.ExtentsDirtyCount)
+ {
- if( !NT_SUCCESS( ntStatus))
- {
+ AFSFlushExtents( pFcb,
+ &pCcb->AuthGroup);
+ }
+
+ //
+ // Wait for any outstanding queued flushes to complete
+ //
+
+ AFSWaitOnQueuedFlushes( pFcb);
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSClose Failed to remove Ccb from Fcb Status %08lX\n",
- ntStatus);
+ ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 &&
+ pFcb->Specific.File.QueuedFlushCount == 0);
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
//
- // We can't actually fail a close operation so reset the status
+ // Tear 'em down, we'll not be needing them again
//
- ntStatus = STATUS_SUCCESS;
+ AFSTearDownFcbExtents( pFcb,
+ &pCcb->AuthGroup);
}
+ else
+ {
+
+ if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB &&
+ pFcb->Specific.File.ExtentsDirtyCount &&
+ (pCcb->GrantedAccess & FILE_WRITE_DATA))
+ {
+
+ AFSFlushExtents( pFcb,
+ &pCcb->AuthGroup);
+ }
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+ }
+
+ pDirCB = pCcb->DirectoryCB;
+
+ //
+ // Steal the DirOpenReferenceCount from the Ccb
+ //
+
+ pCcb->DirectoryCB = NULL;
+
+ //
+ // Remove the Ccb and de-allocate it
+ //
+
+ AFSRemoveCcb( pFcb,
+ pCcb);
//
// If this entry is deleted then remove the object from the volume tree
if( BooleanFlagOn( pDirCB->Flags, AFS_DIR_ENTRY_DELETED))
{
- if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
+ if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB &&
+ pObjectInfo->Links == 0)
{
//
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Acquiring Fcb extents lock %08lX EXCL %08lX\n",
+ "AFSClose Acquiring Fcb extents lock %p EXCL %08lX\n",
&pFcb->NPFcb->Specific.File.ExtentsResource,
PsGetCurrentThread());
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Releasing Fcb extents lock %08lX EXCL %08lX\n",
+ "AFSClose Releasing Fcb extents lock %p EXCL %08lX\n",
&pFcb->NPFcb->Specific.File.ExtentsResource,
PsGetCurrentThread());
AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
TRUE);
- if ( pDirCB->OpenReferenceCount == 0)
- {
- AFSDbgLogMsg( 0,
- 0,
- "AFSClose (Other) OpenReferenceCount is Zero on DE %08lX Ccb %08lX FileName %wZ\n",
- pDirCB,
- pCcb,
- &pDirCB->NameInformation.FileName);
- }
-
- ASSERT( pDirCB->OpenReferenceCount > 0);
-
- InterlockedDecrement( &pDirCB->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pDirCB->DirOpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
&pDirCB->NameInformation.FileName,
pDirCB,
pCcb,
- pDirCB->OpenReferenceCount);
+ lCount);
+
+ ASSERT( lCount >= 0);
- if( pDirCB->OpenReferenceCount == 0)
+ if( lCount == 0)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Deleting dir entry %08lX (%08lX) for %wZ\n",
+ "AFSClose Deleting dir entry %p (%p) for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
pDirCB,
pObjectInfo,
- &pDirCB->NameInformation.FileName);
+ &pDirCB->NameInformation.FileName,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique);
//
// Remove and delete the directory entry from the parent list
AFSDeleteDirEntry( pObjectInfo->ParentObjectInformation,
pDirCB);
- if( pObjectInfo->ObjectReferenceCount == 0)
+ AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
+ TRUE);
+
+ if( pObjectInfo->ObjectReferenceCount <= 0)
{
if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Removing object %08lX from volume tree\n",
+ "AFSClose Removing object %p from volume tree\n",
pObjectInfo);
AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
ClearFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
}
-
- SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
}
+
+ AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
}
AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
else
{
- ASSERT( pDirCB->OpenReferenceCount > 0);
-
- InterlockedDecrement( &pDirCB->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pDirCB->DirOpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
&pDirCB->NameInformation.FileName,
pDirCB,
pCcb,
- pDirCB->OpenReferenceCount);
+ lCount);
+
+ ASSERT( lCount >= 0);
}
//
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Decrement child open ref count on Parent object %08lX Cnt %d\n",
+ "AFSClose Decrement child open ref count on Parent object %p Cnt %d\n",
pObjectInfo->ParentObjectInformation,
pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
}
- if( pFcb->OpenReferenceCount == 1 &&
- pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
- {
-
- SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
-
- //
- // Attempt to tear down our extent list for the file
- // If there are remaining dirty extents then attempt to
- // flush them as well
- //
-
- if( pFcb->Specific.File.ExtentsDirtyCount)
- {
-
- AFSFlushExtents( pFcb);
- }
-
- //
- // Wait for any outstanding queued flushes to complete
- //
-
- AFSWaitOnQueuedFlushes( pFcb);
-
- ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 &&
- pFcb->Specific.File.QueuedFlushCount == 0);
-
- AFSReleaseResource( &pFcb->NPFcb->Resource);
-
- //
- // Tear 'em down, we'll not be needing them again
- //
-
- if( AFSTearDownFcbExtents( pFcb))
- {
-
- //
- // Indicate to the service that the file required complete flushing to the
- // server.
- //
-
- AFSProcessRequest( AFS_REQUEST_TYPE_FLUSH_FILE,
- AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
- NULL,
- &pFcb->ObjectInformation->FileId,
- NULL,
- 0,
- NULL,
- NULL);
- }
- }
- else
- {
-
- if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
- {
-
- if( pFcb->Specific.File.ExtentsDirtyCount)
- {
-
- AFSFlushExtents( pFcb);
- }
- }
-
- AFSReleaseResource( &pFcb->NPFcb->Resource);
- }
-
//
// Decrement the reference count on the Fcb. this is protecting it from teardown.
//
- ASSERT( pFcb->OpenReferenceCount != 0);
-
- InterlockedDecrement( &pFcb->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pFcb->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Decrement count on Fcb %08lX Cnt %d\n",
+ "AFSClose Decrement count on Fcb %p Cnt %d\n",
pFcb,
- pFcb->OpenReferenceCount);
+ lCount);
+
+ ASSERT( lCount >= 0);
break;
}
AFSPipeOpenCloseRequestCB stPipeClose;
+ pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
+
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose Acquiring Special Share lock %08lX EXCL %08lX\n",
+ "AFSClose Acquiring Special Share lock %p EXCL %08lX\n",
&pFcb->NPFcb->Resource,
PsGetCurrentThread());
AFSAcquireExcl( &pFcb->NPFcb->Resource,
TRUE);
- pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
-
- pDirCB = pCcb->DirectoryCB;
-
RtlZeroMemory( &stPipeClose,
sizeof( AFSPipeOpenCloseRequestCB));
// Remove the Ccb and de-allocate it
//
- ntStatus = AFSRemoveCcb( pCcb);
-
- if( !NT_SUCCESS( ntStatus))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_WARNING,
- "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus);
-
- //
- // We can't actually fail a close operation so reset the status
- //
-
- ntStatus = STATUS_SUCCESS;
- }
-
- ASSERT( pDirCB->OpenReferenceCount > 0);
-
- InterlockedDecrement( &pDirCB->OpenReferenceCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (Share) Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
- &pDirCB->NameInformation.FileName,
- pDirCB,
- pCcb,
- pDirCB->OpenReferenceCount);
+ AFSRemoveCcb( pFcb,
+ pCcb);
//
// If this is not the root then decrement the open child reference count
pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
{
- InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
+ lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (Share) Decrement child open ref count on Parent object %08lX Cnt %d\n",
+ "AFSClose (Share) Decrement child open ref count on Parent object %p Cnt %d\n",
pObjectInfo->ParentObjectInformation,
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
+ lCount);
}
AFSReleaseResource( &pFcb->NPFcb->Resource);
- ASSERT( pFcb->OpenReferenceCount != 0);
-
- InterlockedDecrement( &pFcb->OpenReferenceCount);
+ lCount = InterlockedDecrement( &pFcb->OpenReferenceCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
- "AFSClose (Share) Decrement count on Fcb %08lX Cnt %d\n",
+ "AFSClose (Share) Decrement count on Fcb %p Cnt %d\n",
pFcb,
- pFcb->OpenReferenceCount);
+ lCount);
+
+ ASSERT( lCount >= 0);
break;
}
AFSCompleteRequest( Irp,
ntStatus);
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSClose\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;