AFSDeviceExt *pControlDeviceExt = NULL;
IO_STATUS_BLOCK stIoSB;
AFSObjectInfoCB *pObjectInfo = NULL;
+ AFSObjectInfoCB *pParentObjectInfo = NULL;
AFSFileCleanupCB stFileCleanup;
+ AFSFileCleanupResultCB *pResultCB = NULL;
+ ULONG ulResultLen = 0;
ULONG ulNotificationFlags = 0;
+ LONG lCount;
__try
{
}
pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
+
pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
//
stFileCleanup.Identifier = (ULONGLONG)pFileObject;
//
+ // Allocate our return buffer
+ //
+
+ pResultCB = (AFSFileCleanupResultCB *)AFSExAllocatePoolWithTag( PagedPool,
+ PAGE_SIZE,
+ AFS_GENERIC_MEMORY_32_TAG);
+
+ if( pResultCB == NULL)
+ {
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlZeroMemory( pResultCB,
+ PAGE_SIZE);
+
+ ulResultLen = PAGE_SIZE;
+
+
+ //
// Perform the cleanup functionality depending on the type of node it is
//
ASSERT( pFcb->OpenHandleCount != 0);
- InterlockedDecrement( &pFcb->OpenHandleCount);
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+ lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup (RootAll) Decrement handle count on Fcb %08lX Cnt %d\n",
pFcb,
- pFcb->OpenHandleCount);
-
- AFSReleaseResource( &pFcb->NPFcb->Resource);
+ lCount);
FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync,
&pControlDeviceExt->Specific.Control.DirNotifyList,
ASSERT( pFcb->OpenHandleCount != 0);
- InterlockedDecrement( &pFcb->OpenHandleCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCleanup (IOCtl) Decrement handle count on Fcb %08lX Cnt %d\n",
- pFcb,
- pFcb->OpenHandleCount);
-
//
// Decrement the open child handle count
//
pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
{
- InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ lCount = InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup (IOCtl) Decrement child open handle count on Parent object %08lX Cnt %d\n",
pObjectInfo->ParentObjectInformation,
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ lCount);
}
- //
- // And finally, release the Fcb if we acquired it.
- //
-
AFSReleaseResource( &pFcb->NPFcb->Resource);
+ lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCleanup (IOCtl) Decrement handle count on Fcb %08lX Cnt %d\n",
+ pFcb,
+ lCount);
+
break;
}
TRUE);
//
+ // If the handle has write permission ...
+ //
+
+ if( (pCcb->GrantedAccess & FILE_WRITE_DATA) &&
+ CcIsFileCached( pIrpSp->FileObject))
+ {
+
+ __try
+ {
+
+ CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
+ NULL,
+ 0,
+ &stIoSB);
+
+ if( !NT_SUCCESS( stIoSB.Status))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSCleanup CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
+ &pCcb->FullFileName,
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique,
+ stIoSB.Status,
+ stIoSB.Information);
+
+ ntStatus = stIoSB.Status;
+ }
+ }
+ __except( EXCEPTION_EXECUTE_HANDLER)
+ {
+
+ ntStatus = GetExceptionCode();
+ }
+ }
+
+ //
// Uninitialize the cache map. This call is unconditional.
//
ASSERT( pFcb->OpenHandleCount != 0);
- InterlockedDecrement( &pFcb->OpenHandleCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCleanup (File) Decrement handle count on Fcb %08lX Cnt %d\n",
- pFcb,
- pFcb->OpenHandleCount);
-
if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
{
}
//
- // If the count has dropped to zero and there is a pending delete
- // then delete the node
+ // If the count has dropped to one and there is a pending delete
+ // then delete the node. The final count will be decremented just
+ // before the Fcb->NPFcb->Resource is released.
//
- if( pFcb->OpenHandleCount == 0 &&
+ if( pFcb->OpenHandleCount == 1 &&
BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
{
&pFcb->NPFcb->Specific.File.ExtentsResource,
PsGetCurrentThread());
- AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
+ AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
TRUE);
- pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
+ pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
- KeSetEvent( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
+ KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
0,
FALSE);
+ //
+ // Before telling the server about the deleted file, tear down all extents for
+ // the file
+ //
+
+ AFSTearDownFcbExtents( pFcb,
+ &pCcb->AuthGroup);
+
AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup Releasing Fcb extents lock %08lX EXCL %08lX\n",
&pFcb->NPFcb->Specific.File.ExtentsResource,
PsGetCurrentThread());
- AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
-
- //
- // Before telling the server about the deleted file, tear down all extents for
- // the file
- //
-
- AFSTearDownFcbExtents( pFcb);
+ AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
ntStatus = STATUS_SUCCESS;
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
+ &pCcb->AuthGroup,
&pCcb->DirectoryCB->NameInformation.FileName,
&pObjectInfo->FileId,
&stFileCleanup,
sizeof( AFSFileCleanupCB),
- NULL,
- NULL);
+ pResultCB,
+ &ulResultLen);
if( !NT_SUCCESS( ntStatus) &&
ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);
- ASSERT( pObjectInfo->ParentObjectInformation != NULL);
+ ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
- AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
- pCcb,
- (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
- (ULONG)FILE_ACTION_REMOVED);
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ ASSERT( pParentObjectInfo != NULL);
+
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( pParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
+ {
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ else
+ {
+
+ pParentObjectInfo->DataVersion.QuadPart = pResultCB->ParentDataVersion.QuadPart;
+ }
//
// Now that the service has the entry has deleted we need to remove it from the parent
if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
{
- AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
-
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup DE %p for %wZ removing entry\n",
pCcb->DirectoryCB,
&pCcb->DirectoryCB->NameInformation.FileName);
- AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
+ AFSRemoveNameEntry( pParentObjectInfo,
pCcb->DirectoryCB);
-
- AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
else
{
pCcb->DirectoryCB,
&pCcb->DirectoryCB->NameInformation.FileName);
}
+
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+ pCcb,
+ (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+ (ULONG)FILE_ACTION_REMOVED);
+
}
}
else
}
//
- // Flush out any dirty pages on every handle close to reduce strain on the afs cache
- //
-
- if( CcIsFileCached( pIrpSp->FileObject))
- {
-
- __try
- {
-
- CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
- NULL,
- 0,
- &stIoSB);
-
- if( !NT_SUCCESS( stIoSB.Status))
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSCleanup CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
- &pCcb->FullFileName,
- pObjectInfo->FileId.Cell,
- pObjectInfo->FileId.Volume,
- pObjectInfo->FileId.Vnode,
- pObjectInfo->FileId.Unique,
- stIoSB.Status,
- stIoSB.Information);
-
- ntStatus = stIoSB.Status;
- }
- }
- __except( EXCEPTION_EXECUTE_HANDLER)
- {
-
- ntStatus = GetExceptionCode();
- }
- }
-
- //
// Attempt to flush any dirty extents to the server. This may be a little
// aggressive, to flush whenever the handle is closed, but it ensures
// coherency.
//
- if( pFcb->Specific.File.ExtentsDirtyCount)
+ if( (pCcb->GrantedAccess & FILE_WRITE_DATA) &&
+ pFcb->Specific.File.ExtentsDirtyCount != 0)
{
- AFSFlushExtents( pFcb);
+ AFSFlushExtents( pFcb,
+ &pCcb->AuthGroup);
+
+ ulNotificationFlags |= AFS_REQUEST_FLAG_FLUSH_FILE;
}
- if( pFcb->OpenHandleCount == 0)
+ if( pFcb->OpenHandleCount == 1)
{
//
AFSWaitOnQueuedFlushes( pFcb);
- ulNotificationFlags |= AFS_REQUEST_FLAG_FLUSH_FILE;
+ AFSTearDownFcbExtents( pFcb,
+ &pCcb->AuthGroup);
}
//
stFileCleanup.FileAccess = pCcb->FileAccess;
//
+ // Remove the share access at this time since we may not get the close for sometime on this FO.
+ //
+
+ IoRemoveShareAccess( pFileObject,
+ &pFcb->ShareAccess);
+
+
+ //
+ // We don't need the name array after the user closes the handle on the file
+ //
+
+ if( pCcb->NameArray != NULL)
+ {
+
+ AFSFreeNameArray( pCcb->NameArray);
+
+ pCcb->NameArray = NULL;
+ }
+
+ //
+ // Release the Fcb Resource across the call to the service
+ // which may block for quite a while if flushing of the
+ // data is required.
+ //
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+ //
// Push the request to the service
//
- AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
- ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
- &pCcb->DirectoryCB->NameInformation.FileName,
- &pObjectInfo->FileId,
- &stFileCleanup,
- sizeof( AFSFileCleanupCB),
- NULL,
- NULL);
- }
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
+ ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
+ &pCcb->AuthGroup,
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ &pObjectInfo->FileId,
+ &stFileCleanup,
+ sizeof( AFSFileCleanupCB),
+ pResultCB,
+ &ulResultLen);
- //
- // Remove the share access at this time since we may not get the close for sometime on this FO.
- //
+ //
+ // Regain exclusive access to the Fcb
+ //
- IoRemoveShareAccess( pFileObject,
- &pFcb->ShareAccess);
+ AFSAcquireExcl( &pFcb->NPFcb->Resource,
+ TRUE);
- //
- // We don't need the name array after the user closes the handle on the file
- //
+ if ( NT_SUCCESS( ntStatus))
+ {
- if( pCcb->NameArray != NULL)
- {
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
- AFSFreeNameArray( pCcb->NameArray);
+ if ( pParentObjectInfo != NULL)
+ {
- pCcb->NameArray = NULL;
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( pParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart)
+ {
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+ }
+
+ ntStatus = STATUS_SUCCESS;
}
//
// Decrement the open child handle count
//
- if( pObjectInfo->ParentObjectInformation != NULL)
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if( pParentObjectInfo != NULL)
{
- ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);
+ ASSERT( pParentObjectInfo->Specific.Directory.ChildOpenHandleCount > 0);
- InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ lCount = InterlockedDecrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup (File) Decrement child open handle count on Parent object %08lX Cnt %d\n",
- pObjectInfo->ParentObjectInformation,
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ pParentObjectInfo,
+ lCount);
}
- //
- // And finally, release the Fcb if we acquired it.
- //
- AFSReleaseResource( &pFcb->NPFcb->Resource);
+ lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCleanup (File) Decrement handle count on Fcb %08lX Cnt %d\n",
+ pFcb,
+ lCount);
+
+ if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE))
+ {
+ //
+ // The ObjectReferenceCount will be freed by AFSPerformObjectInvalidate
+ //
+
+ AFSObjectInfoIncrement( pObjectInfo);
+
+ ClearFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+
+ AFSPerformObjectInvalidate( pObjectInfo,
+ AFS_INVALIDATE_DATA_VERSION);
+ }
+ else
+ {
+
+ AFSReleaseResource( &pFcb->NPFcb->Resource);
+ }
break;
}
ASSERT( pFcb->OpenHandleCount != 0);
- InterlockedDecrement( &pFcb->OpenHandleCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCleanup (Dir) Decrement handle count on Fcb %08lX Cnt %d\n",
- pFcb,
- pFcb->OpenHandleCount);
-
if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
{
}
//
- // If the count has dropped to zero and there is a pending delete
- // then delete the node
+ // If the count has dropped to one and there is a pending delete
+ // then delete the node. The final count will be decremented just
+ // before the Fcb->NPFcb->Resource is released.
//
- if( pFcb->OpenHandleCount == 0 &&
+ if( pFcb->OpenHandleCount == 1 &&
BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
{
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
+ &pCcb->AuthGroup,
&pCcb->DirectoryCB->NameInformation.FileName,
&pObjectInfo->FileId,
&stFileCleanup,
sizeof( AFSFileCleanupCB),
- NULL,
- NULL);
+ pResultCB,
+ &ulResultLen);
if( !NT_SUCCESS( ntStatus) &&
ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);
- ASSERT( pObjectInfo->ParentObjectInformation != NULL);
+ ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
- AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
- pCcb,
- (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
- (ULONG)FILE_ACTION_REMOVED);
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ ASSERT( pParentObjectInfo != NULL);
+
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( pParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
+ {
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ else
+ {
+
+ pParentObjectInfo->DataVersion.QuadPart = pResultCB->ParentDataVersion.QuadPart;
+ }
//
// Now that the service has the entry has deleted we need to remove it from the parent
if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
{
- AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
-
- AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
+ AFSRemoveNameEntry( pParentObjectInfo,
pCcb->DirectoryCB);
-
- AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
else
{
pCcb->DirectoryCB,
&pCcb->DirectoryCB->NameInformation.FileName);
}
+
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+ pCcb,
+ (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+ (ULONG)FILE_ACTION_REMOVED);
+
}
}
ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
- if( pObjectInfo->ParentObjectInformation != NULL)
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if( pParentObjectInfo != NULL)
{
ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES);
- AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
+ AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
pCcb,
(ULONG)ulNotifyFilter,
(ULONG)FILE_ACTION_MODIFIED);
stFileCleanup.FileAccess = pCcb->FileAccess;
- AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
- ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
- &pCcb->DirectoryCB->NameInformation.FileName,
- &pObjectInfo->FileId,
- &stFileCleanup,
- sizeof( AFSFileCleanupCB),
- NULL,
- NULL);
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
+ ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
+ &pCcb->AuthGroup,
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ &pObjectInfo->FileId,
+ &stFileCleanup,
+ sizeof( AFSFileCleanupCB),
+ pResultCB,
+ &ulResultLen);
+
+ if ( NT_SUCCESS( ntStatus))
+ {
+
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if ( pParentObjectInfo != NULL)
+ {
+
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( pParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart)
+ {
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+ }
+
+ ntStatus = STATUS_SUCCESS;
}
//
// Decrement the open child handle count
//
- if( pObjectInfo->ParentObjectInformation != NULL)
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if( pParentObjectInfo != NULL)
{
- ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);
+ ASSERT( pParentObjectInfo->Specific.Directory.ChildOpenHandleCount > 0);
- InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ lCount = InterlockedDecrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup (Dir) Decrement child open handle count on Parent object %08lX Cnt %d\n",
- pObjectInfo->ParentObjectInformation,
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ pParentObjectInfo,
+ lCount);
}
- //
- // And finally, release the Fcb if we acquired it.
- //
-
AFSReleaseResource( &pFcb->NPFcb->Resource);
+ lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCleanup (Dir) Decrement handle count on Fcb %08lX Cnt %d\n",
+ pFcb,
+ lCount);
+
break;
}
case AFS_SYMBOLIC_LINK_FCB:
case AFS_MOUNT_POINT_FCB:
case AFS_DFS_LINK_FCB:
+ case AFS_INVALID_FCB:
{
//
ASSERT( pFcb->OpenHandleCount != 0);
- InterlockedDecrement( &pFcb->OpenHandleCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCleanup (MP/SL) Decrement handle count on Fcb %08lX Cnt %d\n",
- pFcb,
- pFcb->OpenHandleCount);
-
if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
{
}
//
- // If the count has dropped to zero and there is a pending delete
- // then delete the node
+ // If the count has dropped to one and there is a pending delete
+ // then delete the node. The final count will be decremented just
+ // before the Fcb->NPFcb->Resource is released.
//
- if( pFcb->OpenHandleCount == 0 &&
+ if( pFcb->OpenHandleCount == 1 &&
BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
{
ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
+ &pCcb->AuthGroup,
&pCcb->DirectoryCB->NameInformation.FileName,
&pObjectInfo->FileId,
&stFileCleanup,
sizeof( AFSFileCleanupCB),
- NULL,
- NULL);
+ pResultCB,
+ &ulResultLen);
if( !NT_SUCCESS( ntStatus) &&
ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);
- ASSERT( pObjectInfo->ParentObjectInformation != NULL);
+ ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
- AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
- pCcb,
- (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
- (ULONG)FILE_ACTION_REMOVED);
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ ASSERT( pParentObjectInfo != NULL);
+
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( pParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart - 1)
+ {
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+ else
+ {
+ pParentObjectInfo->DataVersion.QuadPart = pResultCB->ParentDataVersion.QuadPart;
+ }
//
// Now that the service has the entry has deleted we need to remove it from the parent
if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
{
- AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
- TRUE);
-
- AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
+ AFSRemoveNameEntry( pParentObjectInfo,
pCcb->DirectoryCB);
-
- AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
}
else
{
pCcb->DirectoryCB,
&pCcb->DirectoryCB->NameInformation.FileName);
}
+
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
+ pCcb,
+ (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
+ (ULONG)FILE_ACTION_REMOVED);
+
}
}
ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
- if( pObjectInfo->ParentObjectInformation != NULL)
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if( pParentObjectInfo != NULL)
{
ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES);
- AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
+ AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
pCcb,
(ULONG)ulNotifyFilter,
(ULONG)FILE_ACTION_MODIFIED);
stFileCleanup.FileAccess = pCcb->FileAccess;
- AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
- ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
- &pFcb->AuthGroup,
- &pCcb->DirectoryCB->NameInformation.FileName,
- &pObjectInfo->FileId,
- &stFileCleanup,
- sizeof( AFSFileCleanupCB),
- NULL,
- NULL);
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
+ ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
+ &pCcb->AuthGroup,
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ &pObjectInfo->FileId,
+ &stFileCleanup,
+ sizeof( AFSFileCleanupCB),
+ pResultCB,
+ &ulResultLen);
+
+ if ( NT_SUCCESS( ntStatus))
+ {
+
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if ( pParentObjectInfo != NULL)
+ {
+
+ AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
+ TRUE);
+
+ if ( pParentObjectInfo->DataVersion.QuadPart != pResultCB->ParentDataVersion.QuadPart)
+ {
+
+ SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
+
+ pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
+
+ AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+ }
+ }
+
+ ntStatus = STATUS_SUCCESS;
}
//
// Decrement the open child handle count
//
- if( pObjectInfo->ParentObjectInformation != NULL)
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if( pParentObjectInfo != NULL)
{
- ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);
+ ASSERT( pParentObjectInfo->Specific.Directory.ChildOpenHandleCount > 0);
- InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ lCount = InterlockedDecrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup (MP/SL) Decrement child open handle count on Parent object %08lX Cnt %d\n",
- pObjectInfo->ParentObjectInformation,
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ pParentObjectInfo,
+ lCount);
}
- //
- // And finally, release the Fcb if we acquired it.
- //
-
AFSReleaseResource( &pFcb->NPFcb->Resource);
+ lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCleanup (MP/SL) Decrement handle count on Fcb %08lX Cnt %d\n",
+ pFcb,
+ lCount);
+
break;
}
ASSERT( pFcb->OpenHandleCount != 0);
- InterlockedDecrement( &pFcb->OpenHandleCount);
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSCleanup (Share) Decrement handle count on Fcb %08lX Cnt %d\n",
- pFcb,
- pFcb->OpenHandleCount);
-
//
// Decrement the open child handle count
//
- if( pObjectInfo->ParentObjectInformation != NULL &&
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
+ pParentObjectInfo = pObjectInfo->ParentObjectInformation;
+
+ if( pParentObjectInfo != NULL &&
+ pParentObjectInfo->Specific.Directory.ChildOpenHandleCount > 0)
{
- InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ lCount = InterlockedDecrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
AFS_TRACE_LEVEL_VERBOSE,
"AFSCleanup (Share) Decrement child open handle count on Parent object %08lX Cnt %d\n",
- pObjectInfo->ParentObjectInformation,
- pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
+ pParentObjectInfo,
+ lCount);
}
- //
- // And finally, release the Fcb if we acquired it.
- //
-
AFSReleaseResource( &pFcb->NPFcb->Resource);
+ lCount = InterlockedDecrement( &pFcb->OpenHandleCount);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSCleanup (Share) Decrement handle count on Fcb %08lX Cnt %d\n",
+ pFcb,
+ lCount);
+
break;
}
try_exit:
+ if( pResultCB != NULL)
+ {
+
+ AFSExFreePoolWithTag( pResultCB, AFS_GENERIC_MEMORY_32_TAG);
+ }
+
if( pFileObject != NULL)
{
AFSCompleteRequest( Irp, ntStatus);
}
- __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
{
AFSDbgLogMsg( 0,
0,
"EXCEPTION - AFSCleanup\n");
+
+ AFSDumpTraceFilesFnc();
}
return ntStatus;